rake-compile 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []