rake-compile 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc349b9380f07be9b6c46d55bdab2a92b5ab7277
4
+ data.tar.gz: 89dba20f86cb03d00c3da741b5efd82aa958ea46
5
+ SHA512:
6
+ metadata.gz: e2820c68fbcad6743329e7d30e843721d9640977606ff998af6ec365071e10c5f46b3ad463832e9af30fa6f96ed92fa19304217637f8f78232a92b5a8a8dd9e6
7
+ data.tar.gz: 62c41fa7650cd834b6b7ac36b3f96477bdd51214eaf6384cad13db8dbc2c695d994e711e35d6f6d7774f31e239f4b8813c6704431aec7ec30e657be12e8960a7
@@ -0,0 +1,7 @@
1
+ require 'colorize'
2
+
3
+ require_relative 'rake-compile/logging'
4
+ require_relative 'rake-compile/install'
5
+ require_relative 'rake-compile/compiler'
6
+ require_relative 'rake-compile/multi_file_task'
7
+ require_relative 'rake-compile/dsl_definition'
@@ -0,0 +1,31 @@
1
+ module RakeCompile
2
+ class Application
3
+ attr_accessor :build_directory
4
+ attr_accessor :base_cpp_flags
5
+ attr_accessor :cpp_flags
6
+ attr_accessor :base_cc_flags
7
+ attr_accessor :cc_flags
8
+ attr_reader :libraries
9
+ attr_accessor :pch
10
+
11
+ def self.app
12
+ @app ||= RakeCompile::Application.new
13
+ end
14
+
15
+ def initialize()
16
+ @libraries = []
17
+ end
18
+
19
+ def full_cpp_flags
20
+ "#{self.base_cpp_flags} #{self.cpp_flags}"
21
+ end
22
+
23
+ def full_cc_flags
24
+ "#{self.base_cc_flags} #{self.cc_flags}"
25
+ end
26
+
27
+ def flags
28
+ {:cc_flags => self.full_cc_flags, :cpp_flags => self.full_cpp_flags}
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ module RakeCompile
2
+ def self.compiler_for_source(source, flags=nil)
3
+ cpp_flags = cc_flags = flags
4
+
5
+ if flags.is_a? Hash
6
+ cpp_flags = flags[:cpp_flags]
7
+ cc_flags = flags[:cc_flags]
8
+ end
9
+
10
+ case File.extname(source)
11
+ when '.cpp', '.cc', '.hpp'
12
+ "c++ #{cpp_flags}"
13
+ when ".c", ".h"
14
+ "cc #{cc_flags}"
15
+ else
16
+ raise("Don't know how to compile #{source}")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,67 @@
1
+ require_relative 'target'
2
+ require_relative 'application'
3
+
4
+ require 'rake/clean'
5
+
6
+ module RakeCompile
7
+ module DSL
8
+ def build_directory(dir)
9
+ directory dir
10
+ RakeCompile::Application.app.build_directory = dir
11
+ end
12
+
13
+ def base_cc_flags(flags)
14
+ RakeCompile::Application.app.base_cc_flags = flags
15
+ end
16
+
17
+ def cc_flags(flags)
18
+ RakeCompile::Application.app.cc_flags = flags
19
+ end
20
+
21
+ def base_cpp_flags(flags)
22
+ RakeCompile::Application.app.base_cpp_flags = flags
23
+ end
24
+
25
+ def cpp_flags(flags)
26
+ RakeCompile::Application.app.cpp_flags = flags
27
+ end
28
+
29
+ def link_library(library)
30
+ RakeCompile::Application.app.libraries << library
31
+ end
32
+
33
+ def pch(name)
34
+ RakeCompile::Application.app.pch = name
35
+ end
36
+
37
+ def multifile(*args, &block)
38
+ RakeCompile::MultiFileTask.define_task(*args, &block)
39
+ end
40
+
41
+ def static_library(name)
42
+ Target.define_static_library_task(name) do |t|
43
+ yield t
44
+ end
45
+
46
+ clear_build_state
47
+ end
48
+
49
+ def executable(name)
50
+ Target.define_executable_task(name) do |t|
51
+ yield t
52
+ end
53
+
54
+ clear_build_state
55
+ end
56
+
57
+ private
58
+ def clear_build_state
59
+ cpp_flags('')
60
+ cc_flags('')
61
+ RakeCompile::Application.app.libraries.clear()
62
+ RakeCompile::Application.app.pch = nil
63
+ end
64
+ end
65
+ end
66
+
67
+ self.extend RakeCompile::DSL
@@ -0,0 +1,11 @@
1
+ module RakeCompile
2
+ def self.install(src, dst)
3
+ RakeCompile.log("INSTALL".yellow, dst)
4
+ FileUtils.rm_f(dst)
5
+ FileUtils.cp(src, dst)
6
+ end
7
+ def self.uninstall(path)
8
+ RakeCompile.log("UNINSTALL".yellow, path)
9
+ FileUtils.rm_rf(path)
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module RakeCompile
2
+ def self.log(key, msg)
3
+ puts "[#{key}] #{msg}"
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module RakeCompile
2
+ class MultiFileTask < Rake::FileTask
3
+ private
4
+ def invoke_prerequisites(task_args, invocation_chain)
5
+ invoke_prerequisites_concurrently(task_args, invocation_chain)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,196 @@
1
+ require_relative 'application'
2
+ require_relative 'dsl_definition'
3
+
4
+ module RakeCompile
5
+ class Target
6
+ include Rake::DSL
7
+
8
+ attr_reader :objects
9
+ attr_reader :name
10
+ attr_accessor :libraries
11
+ attr_accessor :pch
12
+
13
+ def self.define_executable_task(name)
14
+ target = Target.new(name)
15
+
16
+ yield target
17
+
18
+ target.define_task() do |t|
19
+ t.create_executable()
20
+ end
21
+ end
22
+
23
+ def self.define_static_library_task(name)
24
+ target = Target.new(name)
25
+
26
+ yield target
27
+
28
+ target.define_task() do |t|
29
+ t.create_static_library()
30
+ end
31
+ end
32
+
33
+ def initialize(a_name)
34
+ @name = a_name
35
+ @objects = []
36
+
37
+ self.setup_pch_task()
38
+ end
39
+
40
+ def setup_pch_task
41
+ return if RakeCompile::Application.app.pch.nil?
42
+
43
+ pch_source = RakeCompile::Application.app.pch
44
+ pch_output = pch_source.ext('.gch')
45
+ pch_output = File.join(RakeCompile::Application.app.build_directory, pch_output)
46
+ self.pch = File.absolute_path(pch_output)
47
+
48
+ define_object_dependencies(pch_source, self.pch)
49
+ end
50
+
51
+ def append_pch_to_flags(pch_file, flags)
52
+ flags = flags.dup
53
+
54
+ # Remove the extension. I'm not certain why this is necessary, but clang freaks out if you do not.
55
+ pch_file = pch_file.ext('')
56
+ pch_flag = " -include '#{pch_file}'"
57
+ flags[:cc_flags] += pch_flag
58
+ flags[:cpp_flags] += pch_flag
59
+ flags
60
+ end
61
+
62
+ def define_task()
63
+ CLOBBER.include(self.name)
64
+
65
+ dir = File.dirname(self.name)
66
+ directory dir
67
+
68
+ # Capture libraries, for use in the block below. We need to dup the array,
69
+ # because the app copy gets mutated, and we don't just want a reference.
70
+ self.libraries = RakeCompile::Application.app.libraries.dup
71
+
72
+ prereqs = [dir, self.objects, self.libraries].flatten
73
+
74
+ RakeCompile::MultiFileTask.define_task(self.name => prereqs) do
75
+ yield self
76
+ end
77
+ end
78
+
79
+ def create_executable()
80
+ FileUtils.rm_f(self.name)
81
+
82
+ RakeCompile.log("BIN".light_blue, self.name)
83
+ linker = 'c++ -std=c++11 -stdlib=libc++'
84
+
85
+ inputs = self.objects.join("' '")
86
+ libs = self.libraries.join("' '")
87
+
88
+ cmd = "#{linker}"
89
+ cmd += " -o '#{self.name}'"
90
+ cmd += " '#{inputs}'"
91
+ cmd += " '#{libs}'" if libs.length > 0
92
+
93
+ Rake::sh(cmd)
94
+ end
95
+
96
+ def create_static_library()
97
+ FileUtils.rm_f(self.name)
98
+
99
+ inputs = self.objects.join("' '")
100
+
101
+ RakeCompile.log("LIB".light_blue, self.name)
102
+ Rake::sh("/usr/bin/ar crs '#{self.name}' '#{inputs}'")
103
+ end
104
+
105
+ def add_objects_from_sources(filelist, flags=nil)
106
+ filelist.each { |source| self.add_object_from_source(source, flags) }
107
+ end
108
+
109
+ def add_object_from_source(source, flags=nil)
110
+ object = File.join(RakeCompile::Application.app.build_directory, source.ext('.o'))
111
+
112
+ add_object(source, object, flags)
113
+ end
114
+
115
+ def add_object(source, object, flags=nil)
116
+ object = File.absolute_path(object)
117
+ @objects << object
118
+
119
+ define_object_dependencies(source, object, flags)
120
+ end
121
+
122
+ def define_object_dependencies(source, object, flags=nil)
123
+ flags ||= RakeCompile::Application.app.flags
124
+
125
+ source = File.absolute_path(source)
126
+ dependency_file = "#{object}.deps"
127
+
128
+ deps = []
129
+ if File.exist?(dependency_file)
130
+ deps = dependencies_from_deps_file(dependency_file)
131
+ end
132
+
133
+ dir = File.dirname(dependency_file)
134
+ directory dir
135
+
136
+ # define a file task to create the deps file, which
137
+ # depends on the dependencies themselves. Also
138
+ # depends on the directory that contains it
139
+ if self.pch && (object != self.pch)
140
+ file(dependency_file => self.pch)
141
+ flags = append_pch_to_flags(self.pch, flags)
142
+ end
143
+
144
+ file dependency_file => dir
145
+ file dependency_file => deps do
146
+ RakeCompile.log("DEPS".red, object)
147
+ deps = dependencies_for_source(source, flags)
148
+
149
+ File.open(dependency_file, "w+") do |file|
150
+ file << deps.join("\n")
151
+ file << "\n"
152
+ end
153
+ end
154
+
155
+ # and, now define the actual object file itself
156
+ file object => [dir, dependency_file] do
157
+ s = RakeCompile.compiler_for_source(source, flags)
158
+ s += " -o '#{object}'"
159
+ s += " -c '#{source}'"
160
+
161
+ RakeCompile.log("OBJ".yellow, object)
162
+ Rake::sh(s)
163
+ end
164
+
165
+ # make sure these are cleaned
166
+ CLEAN.include(dependency_file)
167
+ CLEAN.include(object)
168
+ end
169
+
170
+ def dependencies_for_source(source, flags)
171
+ s = RakeCompile::compiler_for_source(source, flags)
172
+ s += " -MM "
173
+ s += "'#{source}'"
174
+
175
+ puts s if verbose() != false
176
+ output = `#{s}`.chomp()
177
+
178
+ output.gsub!(" \\\n ", " ")
179
+
180
+ dependencies = output.split(" ")
181
+ dependencies.delete_at(0) # remove the first element, which is the object file itself
182
+ dependencies.reject! { |x| x.empty? } # remove blanks
183
+
184
+ dependencies.collect { |x| File.absolute_path(x) }
185
+ end
186
+
187
+ def dependencies_from_deps_file(path)
188
+ deps = []
189
+ File.open(path, 'r') do |file|
190
+ deps = file.readlines()
191
+ end
192
+
193
+ deps.collect {|x| x.chomp() }
194
+ end
195
+ end
196
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rake-compile
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Massicotte
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Rake-compile is a set of rake tasks and utitlies to help build native
28
+ projects
29
+ email:
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - lib/rake-compile/application.rb
35
+ - lib/rake-compile/compiler.rb
36
+ - lib/rake-compile/dsl_definition.rb
37
+ - lib/rake-compile/install.rb
38
+ - lib/rake-compile/logging.rb
39
+ - lib/rake-compile/multi_file_task.rb
40
+ - lib/rake-compile/target.rb
41
+ - lib/rake-compile.rb
42
+ homepage: https://github.com/mattmassicotte/rake-compile
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.1.11
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: Rake-compile makes it easier to use rake to build native projects
66
+ test_files: []