bake 0.1.1 → 0.1.2
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.
- data/CHANGELOG +23 -1
- data/CONCEPTS +2 -2
- data/TUTORIAL +14 -8
- data/lib/bake.rb +18 -6
- data/lib/bake/configuration.rb +16 -44
- data/lib/bake/context.rb +41 -9
- data/lib/bake/extensions.rb +3 -0
- data/lib/bake/extensions/class.rb +11 -0
- data/lib/bake/extensions/object.rb +22 -0
- data/lib/bake/{string_utils.rb → extensions/string.rb} +0 -1
- data/lib/bake/file_target.rb +8 -3
- data/lib/bake/plugin.rb +13 -36
- data/lib/bake/plugins/cpp.rb +111 -45
- data/lib/bake/plugins/cpp/darwin.rb +3 -4
- data/lib/bake/plugins/cpp/gcc.rb +5 -0
- data/lib/bake/plugins/cpp/gcc_toolset_base.rb +11 -28
- data/lib/bake/plugins/cpp/msvc.rb +10 -16
- data/lib/bake/plugins/cpp/qt.rb +29 -26
- data/lib/bake/plugins/cpp/toolset_base.rb +28 -70
- data/lib/bake/plugins/runner.rb +40 -0
- data/lib/bake/plugins/system.rb +6 -22
- data/lib/bake/project.rb +60 -19
- data/lib/bake/project_loader.rb +13 -4
- data/lib/bake/system_utils.rb +42 -0
- data/lib/bake/target.rb +100 -23
- data/lib/bake/toolset.rb +8 -1
- data/lib/bake_version.rb +1 -1
- data/test/test_bake.rb +2 -0
- data/test/test_configuration.rb +58 -0
- metadata +11 -8
- data/test/bake_test.rb +0 -5
- data/test/configuration_test.rb +0 -102
- data/test/context_test.rb +0 -94
- data/test/scheme_test.rb +0 -121
- data/test/target_test.rb +0 -93
data/lib/bake/plugin.rb
CHANGED
@@ -1,44 +1,26 @@
|
|
1
|
-
require 'bake/string_utils'
|
2
|
-
|
3
|
-
class Object
|
4
|
-
def self.const_missing(name)
|
5
|
-
return Bake::Plugins.const_get(name)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
1
|
module Bake
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def self.search_dirs
|
15
|
-
return @@search_dirs
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.plugins
|
19
|
-
return @@plugins
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.load_plugin(full_name)
|
23
|
-
parent = Plugins
|
24
|
-
plugin = nil
|
2
|
+
module PluginManager
|
3
|
+
def load_plugin(full_name)
|
4
|
+
plugin = Object.main_object.class
|
25
5
|
full_name.to_s.split('::').each do |name|
|
26
|
-
plugin = load_child_plugin(
|
6
|
+
plugin = load_child_plugin(plugin, name)
|
27
7
|
end
|
28
8
|
return plugin
|
29
9
|
end
|
30
10
|
|
31
|
-
def
|
11
|
+
def load_child_plugin(parent, name)
|
32
12
|
name = name.to_s
|
33
|
-
full_name = parent.
|
13
|
+
full_name = parent.equal?(Object.main_object.class) ?
|
14
|
+
name : parent.name + '::' + name
|
34
15
|
plugin_file = full_name.underscore.gsub('::', '/')
|
35
16
|
|
36
17
|
plugin = nil
|
37
18
|
if parent.const_defined?(name)
|
38
19
|
plugin = parent.const_get(name)
|
20
|
+
return plugin if plugin.equal?(Bake)
|
39
21
|
end
|
40
22
|
|
41
|
-
|
23
|
+
search_dirs.each do |rootdir|
|
42
24
|
if File.exists?(File.join(rootdir, plugin_file + '.rb'))
|
43
25
|
require plugin_file
|
44
26
|
if !plugin && parent.const_defined?(name)
|
@@ -51,22 +33,17 @@ module Bake
|
|
51
33
|
plugin = Module.new
|
52
34
|
parent.const_set(name, plugin)
|
53
35
|
end
|
54
|
-
|
55
|
-
|
36
|
+
plugin_manager = self
|
37
|
+
plugin.metaclass.send(
|
38
|
+
:define_method, :const_missing) do |name|
|
39
|
+
return plugin_manager.load_child_plugin(self, name)
|
56
40
|
end
|
57
41
|
end
|
58
42
|
end
|
59
43
|
|
60
44
|
raise "could not find plugin '#{name}'" if !plugin
|
61
|
-
@@plugins[full_name] = plugin
|
62
45
|
return plugin
|
63
46
|
end
|
64
47
|
end
|
65
|
-
|
66
|
-
module Plugins
|
67
|
-
def self.const_missing(name)
|
68
|
-
return PluginManager.load_plugin(name)
|
69
|
-
end
|
70
|
-
end
|
71
48
|
end
|
72
49
|
|
data/lib/bake/plugins/cpp.rb
CHANGED
@@ -6,72 +6,129 @@ module Bake
|
|
6
6
|
class SystemLibrary < Target
|
7
7
|
attr_reader :file
|
8
8
|
|
9
|
-
def
|
10
|
-
super(parent, toolset)
|
9
|
+
def post_initialize(name, file)
|
11
10
|
@built = true
|
12
11
|
@name = name
|
13
12
|
@file = file
|
14
|
-
|
13
|
+
end
|
14
|
+
|
15
|
+
def products
|
16
|
+
return nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def mtimes
|
20
|
+
return [ Time.at(0) ]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# +MainTarget+ is a mix-in for the +Library+ and +Executable+
|
25
|
+
# classes containing code common to both types of targets.
|
26
|
+
module MainTarget
|
27
|
+
# A special override of +stale?+ that ignores changes to
|
28
|
+
# dlls when determining if this target is stale. The only
|
29
|
+
# case in which a lib or exe should have to update when a
|
30
|
+
# dll dependency is updated is when the interface changes.
|
31
|
+
# Since exes and libs depend on the headers implicitly,
|
32
|
+
# they will be updated if the interface changes
|
33
|
+
# automatically.
|
34
|
+
def stale?
|
35
|
+
return @stale if !@stale.nil?
|
36
|
+
tmin = mtimes.min
|
37
|
+
@stale = deps.any? do |dep|
|
38
|
+
is_dll = dep.is_a?(Library) &&
|
39
|
+
dep[:libtype] == 'dynamic'
|
40
|
+
(dep.stale? || dep.mtimes.max > tmin) && !is_dll
|
41
|
+
end
|
42
|
+
return @stale
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_dep(target)
|
46
|
+
if target.is_a?(FileTarget)
|
47
|
+
target = Source.new(self, toolset, target)
|
48
|
+
end
|
49
|
+
return super if !target.is_a?(Source)
|
50
|
+
deps << Cpp::Object.new(self, toolset, target)
|
51
|
+
end
|
52
|
+
|
53
|
+
def build
|
54
|
+
toolset.build(self)
|
15
55
|
end
|
16
56
|
end
|
17
57
|
|
18
58
|
class Library < Target
|
19
|
-
|
20
|
-
|
59
|
+
include MainTarget
|
60
|
+
|
61
|
+
def post_initialize(name)
|
21
62
|
@name = name
|
22
63
|
default(:libtype => 'static')
|
23
64
|
default(:debug_symbols? => false)
|
24
65
|
end
|
25
|
-
|
26
|
-
def add_dep(target)
|
27
|
-
return super if !target.is_a?(FileTarget)
|
28
|
-
deps << Cpp::Object.new(self, toolset, target)
|
29
|
-
end
|
30
66
|
end
|
31
67
|
|
32
68
|
class Executable < Target
|
33
|
-
|
34
|
-
|
69
|
+
include MainTarget
|
70
|
+
|
71
|
+
def post_initialize(name)
|
35
72
|
@name = name
|
36
73
|
default(:debug_symbols? => false)
|
37
74
|
end
|
38
75
|
|
39
|
-
|
40
|
-
|
41
|
-
|
76
|
+
# Enables +Executable+ to be run via a +Runner+ target.
|
77
|
+
def run_command
|
78
|
+
return toolset.exe_fn(self)
|
42
79
|
end
|
43
80
|
end
|
44
81
|
|
45
|
-
class
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
default(:rtti? => true)
|
51
|
-
default(:optimizations? => false)
|
52
|
-
default(:multithreaded? => true)
|
82
|
+
class Source < Target
|
83
|
+
def post_initialize(source)
|
84
|
+
@source = source
|
85
|
+
@includes = IncludeList.new(self, toolset, source)
|
86
|
+
dep(source, @includes)
|
53
87
|
end
|
54
88
|
|
55
|
-
def
|
56
|
-
return
|
89
|
+
def path
|
90
|
+
return @source.path
|
57
91
|
end
|
58
92
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
93
|
+
alias :id :path
|
94
|
+
|
95
|
+
def mtimes
|
96
|
+
return @includes.mtimes
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class IncludeList < Target
|
101
|
+
attr_reader :includes
|
102
|
+
|
103
|
+
def post_initialize(source)
|
104
|
+
@src = source.path
|
105
|
+
if File.exists?(products)
|
106
|
+
@includes = load_includes
|
107
|
+
@calculated = false
|
108
|
+
else
|
109
|
+
@includes = calc_includes(@src)
|
110
|
+
@calculated = true
|
67
111
|
end
|
68
|
-
|
112
|
+
dep(source, *@includes)
|
113
|
+
end
|
114
|
+
|
115
|
+
def id
|
116
|
+
return @src
|
117
|
+
end
|
118
|
+
|
119
|
+
def build
|
120
|
+
@includes = calc_includes(@src) if !@calculated
|
121
|
+
toolset.sys.fwrite(products, includes.to_a.join("\n"))
|
122
|
+
end
|
123
|
+
|
124
|
+
def products
|
125
|
+
return "#{get(:outdir)}/#{@src.basename}.includes"
|
69
126
|
end
|
70
127
|
|
71
128
|
private
|
72
|
-
def load_includes
|
129
|
+
def load_includes
|
73
130
|
includes = Set.new
|
74
|
-
file = File.open(
|
131
|
+
file = File.open(products)
|
75
132
|
while line = file.gets
|
76
133
|
line.chomp!
|
77
134
|
includes << line if !line.empty?
|
@@ -80,9 +137,9 @@ module Bake
|
|
80
137
|
return includes
|
81
138
|
end
|
82
139
|
|
83
|
-
def calc_includes(
|
140
|
+
def calc_includes(src, include_fns = Set.new)
|
84
141
|
new_include_fns = Set.new
|
85
|
-
File.open(
|
142
|
+
File.open(src) do |file|
|
86
143
|
incdirs = get(:incdirs)
|
87
144
|
while line = file.gets
|
88
145
|
if line =~ /\s*#\s*include\s+("|<)([^"]+)("|>)/
|
@@ -107,13 +164,22 @@ module Bake
|
|
107
164
|
end
|
108
165
|
end
|
109
166
|
|
110
|
-
class
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
167
|
+
class Object < Target
|
168
|
+
attr_reader :src
|
169
|
+
|
170
|
+
alias :id :src
|
171
|
+
|
172
|
+
def post_initialize(source)
|
173
|
+
@src = source.path
|
174
|
+
dep(source)
|
175
|
+
default(:exceptions? => true)
|
176
|
+
default(:rtti? => true)
|
177
|
+
default(:optimizations? => false)
|
178
|
+
default(:multithreaded? => true)
|
179
|
+
end
|
180
|
+
|
181
|
+
def build
|
182
|
+
toolset.build(self)
|
117
183
|
end
|
118
184
|
end
|
119
185
|
end
|
@@ -7,16 +7,15 @@ module Bake
|
|
7
7
|
|
8
8
|
output = lib_fn(lib)
|
9
9
|
if lib[:libtype] == 'dynamic'
|
10
|
-
sh("g++ #{flags} -dynamiclib -o #{output} #{obj_str} #{lib_str}")
|
10
|
+
sys.sh("g++ #{flags} -dynamiclib -o #{output} #{obj_str} #{lib_str}")
|
11
11
|
else
|
12
|
-
sh("ar rcs #{output} #{obj_str}")
|
12
|
+
sys.sh("ar rcs #{output} #{obj_str}")
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
private
|
17
16
|
def lib_fn(lib)
|
18
17
|
if lib[:libtype] == 'dynamic'
|
19
|
-
return File.join(lib[:outdir], "#{lib.name}.dylib")
|
18
|
+
return File.join(lib[:outdir], "lib#{lib.name}.dylib")
|
20
19
|
end
|
21
20
|
return File.join(lib[:outdir], "lib#{lib.name}.a")
|
22
21
|
end
|
data/lib/bake/plugins/cpp/gcc.rb
CHANGED
@@ -11,8 +11,6 @@ module Bake
|
|
11
11
|
return lib_fn(target)
|
12
12
|
elsif target.is_a?(Cpp::Executable)
|
13
13
|
return exe_fn(target)
|
14
|
-
elsif target.is_a?(Cpp::Runner)
|
15
|
-
return runner_fn(target)
|
16
14
|
end
|
17
15
|
return nil
|
18
16
|
end
|
@@ -26,7 +24,7 @@ module Bake
|
|
26
24
|
flags += ' -fno-rtti' if !obj[:rtti?]
|
27
25
|
flags += ' -O3' if obj[:optimizations?]
|
28
26
|
flags += ' -g' if obj[:debug_symbols?]
|
29
|
-
sh("g++ -c -o #{output} #{flags} #{src}")
|
27
|
+
sys.sh("g++ -c -o #{output} #{flags} #{src}")
|
30
28
|
end
|
31
29
|
|
32
30
|
def ar(lib)
|
@@ -34,13 +32,13 @@ module Bake
|
|
34
32
|
|
35
33
|
output = lib_fn(lib)
|
36
34
|
if lib[:libtype] == 'dynamic'
|
37
|
-
sh("g++ #{flags} -shared -Wl,-soname,#{output} -o #{output} #{obj_str} #{lib_str}")
|
35
|
+
sys.sh("g++ #{flags} -shared -Wl,-soname,#{output} -o #{output} #{obj_str} #{lib_str}")
|
38
36
|
if lib.has_prop?(:gcc_lib_path)
|
39
37
|
fn = File.join(lib[:gcc_lib_path], output.basename)
|
40
38
|
File.symlink(output, fn) if !File.exists?(fn)
|
41
39
|
end
|
42
40
|
else
|
43
|
-
sh("ar rcs #{output} #{obj_str}")
|
41
|
+
sys.sh("ar rcs #{output} #{obj_str}")
|
44
42
|
end
|
45
43
|
end
|
46
44
|
|
@@ -48,17 +46,7 @@ module Bake
|
|
48
46
|
obj_str, lib_str, flags = process_inputs(exe)
|
49
47
|
|
50
48
|
output = exe_fn(exe)
|
51
|
-
sh("g++ #{flags} -o #{output} #{obj_str} #{lib_str}")
|
52
|
-
end
|
53
|
-
|
54
|
-
def run(runner)
|
55
|
-
sh(exe_fn(runner.deps.first))
|
56
|
-
FileUtils.touch(runner_fn(runner))
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
def build_flags(flag, args)
|
61
|
-
return args.inject('') { |str, arg| str + "#{flag}#{arg} " }
|
49
|
+
sys.sh("g++ #{flags} -o #{output} #{obj_str} #{lib_str}")
|
62
50
|
end
|
63
51
|
|
64
52
|
def obj_fn(obj)
|
@@ -78,16 +66,16 @@ module Bake
|
|
78
66
|
return File.join(exe[:outdir], exe.name)
|
79
67
|
end
|
80
68
|
|
81
|
-
|
82
|
-
|
69
|
+
private
|
70
|
+
def build_flags(flag, args)
|
71
|
+
return args.inject('') { |str, arg| str + "#{flag}#{arg} " }
|
83
72
|
end
|
84
|
-
|
73
|
+
|
85
74
|
def process_inputs(target)
|
86
75
|
output = output(target)
|
87
76
|
obj_str = ''
|
88
77
|
lib_str = ''
|
89
78
|
libdirs = []
|
90
|
-
rtdirs = []
|
91
79
|
target.deps.each do |input|
|
92
80
|
if input.is_a?(Cpp::Object)
|
93
81
|
fn = obj_fn(input)
|
@@ -96,14 +84,9 @@ module Bake
|
|
96
84
|
lib_str += '-l' + input.file + ' '
|
97
85
|
elsif input.is_a?(Cpp::Library)
|
98
86
|
fn = lib_fn(input)
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
else
|
103
|
-
lib_str += '-l' + input.name + ' '
|
104
|
-
libdir = File.dirname(fn)
|
105
|
-
libdirs << libdir if !libdirs.include?(libdir)
|
106
|
-
end
|
87
|
+
lib_str += '-l' + input.name + ' '
|
88
|
+
libdir = File.dirname(fn)
|
89
|
+
libdirs << libdir if !libdirs.include?(libdir)
|
107
90
|
end
|
108
91
|
end
|
109
92
|
|
@@ -26,7 +26,7 @@ module Bake
|
|
26
26
|
flags += ' /GR' if obj[:rtti?]
|
27
27
|
flags += obj[:optimizations?] ? ' /O2' : ' /Od'
|
28
28
|
flags += ' /Z7' if obj[:debug_symbols?]
|
29
|
-
sh("cl /nologo #{flags} /c /Fo#{output} /Tp#{src}")
|
29
|
+
sys.sh("cl /nologo #{flags} /c /Fo#{output} /Tp#{src}")
|
30
30
|
end
|
31
31
|
|
32
32
|
def ar(lib)
|
@@ -35,9 +35,12 @@ module Bake
|
|
35
35
|
output = lib_fn(lib)
|
36
36
|
if lib[:libtype] == 'dynamic'
|
37
37
|
flags += ' /debug' if lib[:debug_symbols?]
|
38
|
-
sh("link /nologo /dll #{flags} /out:#{output[1]} #{obj_str}")
|
38
|
+
sys.sh("link /nologo /dll #{flags} /out:#{output[1]} #{obj_str}")
|
39
|
+
# need to touch the .exp file because it sometimes
|
40
|
+
# doesn't get updated
|
41
|
+
sys.touch(output[2])
|
39
42
|
else
|
40
|
-
sh("lib /nologo /out:#{output} #{obj_str}")
|
43
|
+
sys.sh("lib /nologo /out:#{output} #{obj_str}")
|
41
44
|
end
|
42
45
|
end
|
43
46
|
|
@@ -46,17 +49,7 @@ module Bake
|
|
46
49
|
|
47
50
|
output = exe_fn(exe)
|
48
51
|
flags += ' /debug' if exe[:debug_symbols?]
|
49
|
-
sh("link /nologo /subsystem:console #{flags} /out:#{output} #{obj_str}")
|
50
|
-
end
|
51
|
-
|
52
|
-
def run(runner)
|
53
|
-
sh(exe_fn(runner.deps.first))
|
54
|
-
FileUtils.touch(runner_fn(runner))
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
def build_flags(flag, args)
|
59
|
-
return args.inject('') { |str, arg| str + "#{flag}#{arg} " }
|
52
|
+
sys.sh("link /nologo /subsystem:console #{flags} /out:#{output} #{obj_str}")
|
60
53
|
end
|
61
54
|
|
62
55
|
def obj_fn(obj)
|
@@ -78,8 +71,9 @@ module Bake
|
|
78
71
|
return File.join(exe[:outdir], exe.name + '.exe')
|
79
72
|
end
|
80
73
|
|
81
|
-
|
82
|
-
|
74
|
+
private
|
75
|
+
def build_flags(flag, args)
|
76
|
+
return args.inject('') { |str, arg| str + "#{flag}#{arg} " }
|
83
77
|
end
|
84
78
|
|
85
79
|
def process_inputs(target)
|