bake 0.1.0 → 0.1.1
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 +16 -0
- data/CONCEPTS +52 -0
- data/TUTORIAL +12 -23
- data/lib/bake.rb +7 -34
- data/lib/bake/addon.rb +20 -0
- data/lib/bake/context.rb +40 -60
- data/lib/bake/file_target.rb +14 -0
- data/lib/bake/plugin.rb +72 -0
- data/lib/bake/plugins/cpp.rb +122 -0
- data/lib/bake/plugins/cpp/darwin.rb +27 -0
- data/lib/bake/plugins/cpp/gcc.rb +9 -0
- data/lib/bake/plugins/cpp/gcc_toolset_base.rb +118 -0
- data/lib/bake/plugins/cpp/msvc.rb +124 -0
- data/lib/bake/plugins/cpp/qt.rb +50 -0
- data/lib/bake/plugins/cpp/toolset_base.rb +98 -0
- data/lib/bake/plugins/macro.rb +18 -0
- data/lib/bake/plugins/system.rb +46 -0
- data/lib/bake/project.rb +50 -0
- data/lib/bake/project_loader.rb +11 -15
- data/lib/bake/string_utils.rb +4 -0
- data/lib/bake/target.rb +43 -80
- data/lib/bake/toolset.rb +13 -6
- data/lib/bake_version.rb +1 -1
- metadata +19 -7
- data/lib/bake/common_scheme.rb +0 -42
- data/lib/bake/cpp_scheme.rb +0 -460
- data/lib/bake/qt_scheme.rb +0 -62
- data/lib/bake/scheme.rb +0 -104
- data/lib/bake/scheme_loader.rb +0 -28
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'bake/toolset'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module Bake
|
6
|
+
module Plugins
|
7
|
+
module Cpp
|
8
|
+
class ToolsetBase
|
9
|
+
include Toolset
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
constructor :syslib, SystemLibrary
|
13
|
+
constructor :lib, Library
|
14
|
+
constructor :exe, Executable
|
15
|
+
constructor :run, Runner
|
16
|
+
end
|
17
|
+
|
18
|
+
def build(target)
|
19
|
+
if stale?(target)
|
20
|
+
FileUtils.mkdir_p(target[:outdir])
|
21
|
+
if target.is_a?(Cpp::Object)
|
22
|
+
compile(target)
|
23
|
+
# refresh the .includes file
|
24
|
+
includes = target.includes
|
25
|
+
filename = "#{target[:outdir]}/#{target.src.basename}.includes"
|
26
|
+
File.open(filename, "w") do |file|
|
27
|
+
includes.each { |inc| file.puts(inc) }
|
28
|
+
end
|
29
|
+
elsif target.is_a?(Cpp::Library)
|
30
|
+
ar(target)
|
31
|
+
elsif target.is_a?(Cpp::Executable)
|
32
|
+
link(target)
|
33
|
+
elsif target.is_a?(Cpp::Runner)
|
34
|
+
run(target)
|
35
|
+
else
|
36
|
+
raise "unknown Cpp target of class '#{target.class}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def stale?(target)
|
42
|
+
t = Time.now
|
43
|
+
output_files(target).each do |out|
|
44
|
+
return true if !File.exists?(out)
|
45
|
+
out_time = File.mtime(out)
|
46
|
+
t = out_time if out_time < t
|
47
|
+
end
|
48
|
+
if target.is_a?(Cpp::Object)
|
49
|
+
return true if File.mtime(target.src) > t
|
50
|
+
target.includes.each { |file| return true if File.mtime(file) > t }
|
51
|
+
elsif target.is_a?(Cpp::Runner)
|
52
|
+
return File.mtime(output_files(target.deps[0])[0]) > t
|
53
|
+
else
|
54
|
+
is_linked = target.is_a?(Cpp::Executable) ||
|
55
|
+
(target.is_a?(Cpp::Library) && target[:libtype] == 'dynamic')
|
56
|
+
target.children.each do |child|
|
57
|
+
output_files(child).each do |file|
|
58
|
+
return true if File.mtime(file) > t
|
59
|
+
end
|
60
|
+
end
|
61
|
+
target.deps.each do |dep|
|
62
|
+
if is_linked && dep.is_a?(Cpp::Library) &&
|
63
|
+
dep[:libtype] != 'dynamic'
|
64
|
+
output_files(dep).each do |file|
|
65
|
+
return true if File.mtime(file) > t
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
def clean(target)
|
74
|
+
output_files(target).each { |file| FileUtils.rm_f(file) }
|
75
|
+
if target.is_a?(Cpp::Object)
|
76
|
+
filename = "#{target[:outdir]}/#{target.src.basename}.includes"
|
77
|
+
FileUtils.rm_f(filename)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def output_files(target)
|
82
|
+
out = output(target)
|
83
|
+
return [] if !out
|
84
|
+
return out.to_a if out.respond_to?(:to_a)
|
85
|
+
return [ out ]
|
86
|
+
end
|
87
|
+
|
88
|
+
def sh(*args)
|
89
|
+
cmd = args.join(' ')
|
90
|
+
puts cmd
|
91
|
+
system(*args)
|
92
|
+
raise "error: #{cmd}" if !$? || !$?.success?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'bake/addon'
|
2
|
+
|
3
|
+
module Bake
|
4
|
+
module Plugins
|
5
|
+
class System
|
6
|
+
include Addon
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
command(:glob)
|
10
|
+
end
|
11
|
+
|
12
|
+
def glob(context, *args)
|
13
|
+
has_options = args.last.respond_to?(:to_hash)
|
14
|
+
options = has_options ? args.pop.to_hash : {}
|
15
|
+
exclude = array_opt(options, :exclude)
|
16
|
+
files = []
|
17
|
+
args.each do |pat|
|
18
|
+
matches = Dir[pat]
|
19
|
+
matches.each do |file|
|
20
|
+
if !exclude.find { |exc| File.fnmatch(exc, file) }
|
21
|
+
files.push(file)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
if block_given?
|
26
|
+
for i in 0...files.size
|
27
|
+
yield(files[i])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return files
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def array_opt(options, name)
|
35
|
+
opt = options[name]
|
36
|
+
return [] if !opt
|
37
|
+
if opt.respond_to?(:to_ary)
|
38
|
+
opt = opt.to_ary
|
39
|
+
else
|
40
|
+
opt = [ opt ]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
data/lib/bake/project.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'bake/target'
|
2
|
+
|
3
|
+
module Bake
|
4
|
+
class Project < Target
|
5
|
+
attr_accessor :loader
|
6
|
+
|
7
|
+
def initialize(parent, loader)
|
8
|
+
super(parent, nil)
|
9
|
+
@loader = loader
|
10
|
+
end
|
11
|
+
|
12
|
+
def current_project
|
13
|
+
return self
|
14
|
+
end
|
15
|
+
|
16
|
+
def parent_project
|
17
|
+
return parent ? parent.current_project : nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def child_project(name)
|
21
|
+
child = children.find do |child|
|
22
|
+
child.name == name && child.is_a?(Project)
|
23
|
+
end
|
24
|
+
return child || loader.load_project(self, name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def resolve(path)
|
28
|
+
index = path.index(':')
|
29
|
+
raise "invalid path '#{path}'" if !index
|
30
|
+
dir = path.slice(0, index)
|
31
|
+
name = path.slice(index + 1, path.length - index - 1)
|
32
|
+
proj = self
|
33
|
+
dir.split('/').each do |el|
|
34
|
+
if el == '.'
|
35
|
+
next
|
36
|
+
elsif el == '..'
|
37
|
+
proj = proj.parent_project
|
38
|
+
raise "invalid target path '#{path}'" if !proj
|
39
|
+
else
|
40
|
+
proj = proj.child_project(el)
|
41
|
+
raise "invalid target path '#{path}'" if !proj
|
42
|
+
end
|
43
|
+
end
|
44
|
+
target = proj.children.find { |child| child.name == name }
|
45
|
+
raise "invalid target path '#{path}'" if !target
|
46
|
+
return target
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
data/lib/bake/project_loader.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'bake/target'
|
2
|
+
require 'bake/project'
|
2
3
|
|
3
4
|
module Bake
|
4
5
|
class ProjectLoader
|
@@ -10,18 +11,14 @@ module Bake
|
|
10
11
|
load_invok_project
|
11
12
|
end
|
12
13
|
|
13
|
-
def load_project(
|
14
|
-
|
15
|
-
if !
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
proj.opt(:projname => name)
|
22
|
-
proj.opt(:cwdir => dir)
|
23
|
-
process(proj)
|
24
|
-
end
|
14
|
+
def load_project(parent, name)
|
15
|
+
dir = File.join(parent[:cwdir], name)
|
16
|
+
raise "no such directory '#{dir}'" if !File.directory?(dir)
|
17
|
+
proj = Project.new(parent, self)
|
18
|
+
proj.name = name
|
19
|
+
proj.opt(:projname => name)
|
20
|
+
proj.opt(:cwdir => dir)
|
21
|
+
process(proj)
|
25
22
|
return proj
|
26
23
|
end
|
27
24
|
|
@@ -33,8 +30,7 @@ module Bake
|
|
33
30
|
while true
|
34
31
|
bakefile = File.join(dir, 'root.bake')
|
35
32
|
if File.exists?(bakefile)
|
36
|
-
project = Project.new(nil)
|
37
|
-
project.loader = self
|
33
|
+
project = Project.new(nil, self)
|
38
34
|
project.req(:rootdir => dir)
|
39
35
|
project.opt(:projname => 'root')
|
40
36
|
project.opt(:cwdir => dir)
|
@@ -56,7 +52,7 @@ module Bake
|
|
56
52
|
def load_invok_project
|
57
53
|
project = @root_project
|
58
54
|
@invok_path.reverse_each do |name|
|
59
|
-
project = load_project(
|
55
|
+
project = load_project(project, name)
|
60
56
|
end
|
61
57
|
@invok_project = project
|
62
58
|
return project
|
data/lib/bake/string_utils.rb
CHANGED
data/lib/bake/target.rb
CHANGED
@@ -1,115 +1,78 @@
|
|
1
1
|
require 'bake/configuration'
|
2
|
+
require 'bake/string_utils'
|
2
3
|
|
3
4
|
module Bake
|
4
5
|
class Target
|
5
6
|
include Configuration
|
6
7
|
|
7
|
-
attr_reader :parent, :children, :deps
|
8
|
+
attr_reader :parent, :children, :deps, :toolset
|
8
9
|
attr_accessor :name
|
9
10
|
|
10
|
-
def initialize(parent)
|
11
|
+
def initialize(parent, toolset)
|
11
12
|
@parent = parent
|
13
|
+
@toolset = toolset
|
12
14
|
@children = []
|
13
15
|
@deps = []
|
14
16
|
parent.children << self if parent
|
15
|
-
opt(:built? => false)
|
16
|
-
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
if toolset
|
19
|
+
mixin_name = self.class.name.split('::').last
|
20
|
+
toolset.class
|
21
|
+
if toolset.class.const_defined?(mixin_name)
|
22
|
+
extend(toolset.class.const_get(mixin_name))
|
22
23
|
end
|
23
24
|
end
|
24
|
-
|
25
|
+
post_initialize if respond_to?(:post_initialize)
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def dep(*targets)
|
36
|
-
ret = []
|
37
|
-
targets.each do |target|
|
38
|
-
if !target.is_a?(Target)
|
39
|
-
real_target = parent.find(target) if parent
|
40
|
-
raise "uknown target '#{target}'" if !real_target
|
41
|
-
target = real_target
|
28
|
+
def build
|
29
|
+
return if @built
|
30
|
+
deps.each { |dep| dep.build }
|
31
|
+
children.each { |child| child.build }
|
32
|
+
if toolset
|
33
|
+
Dir.chdir(get(:cwdir)) do
|
34
|
+
toolset.build(self)
|
42
35
|
end
|
43
|
-
deps << target
|
44
|
-
ret << target
|
45
36
|
end
|
46
|
-
|
37
|
+
@built = true
|
47
38
|
end
|
48
39
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
if !deps.empty?
|
53
|
-
str += ' => '
|
54
|
-
deps.each do |target|
|
55
|
-
str += target.name + ' (' + target.class.name + ') '
|
56
|
-
end
|
57
|
-
end
|
58
|
-
str += "\n"
|
59
|
-
if !children.empty?
|
60
|
-
children.each { |target| str += target.to_s(level + 1) }
|
61
|
-
end
|
62
|
-
return str
|
40
|
+
def clean
|
41
|
+
children.each { |child| child.clean }
|
42
|
+
toolset.clean(self) if toolset
|
63
43
|
end
|
64
|
-
end
|
65
44
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
45
|
+
def dep(*targets)
|
46
|
+
targets = normalize_targets(*targets)
|
47
|
+
targets.each { |target| add_dep(target) }
|
48
|
+
end
|
70
49
|
|
71
|
-
def
|
72
|
-
|
73
|
-
@mappings = {}
|
50
|
+
def add_dep(target)
|
51
|
+
deps << target
|
74
52
|
end
|
75
53
|
|
76
|
-
def
|
77
|
-
|
78
|
-
raise "target '#{name}' already mapped" if @mappings[name]
|
79
|
-
@mappings[name] = loc
|
80
|
-
end
|
54
|
+
def current_project
|
55
|
+
return parent.current_project
|
81
56
|
end
|
82
57
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
if
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
58
|
+
private
|
59
|
+
def normalize_targets(*targets)
|
60
|
+
normalized_targets = []
|
61
|
+
targets.flatten.each do |target|
|
62
|
+
if !target.is_a?(Target)
|
63
|
+
if File.exists?(target)
|
64
|
+
target = FileTarget.new(self, target)
|
65
|
+
else
|
66
|
+
target = current_project.resolve(target)
|
92
67
|
end
|
93
|
-
target = proj.child(name)
|
94
|
-
@mappings[name] = target
|
95
|
-
raise "invalid mapping #{@mappings[name]}" if !target
|
96
|
-
elsif mapping.is_a?(Target)
|
97
|
-
target = mapping
|
98
|
-
else
|
99
|
-
raise "mapping has invalid class '#{mapping.class.name}'"
|
100
68
|
end
|
69
|
+
normalized_targets << target
|
101
70
|
end
|
102
|
-
return
|
103
|
-
end
|
104
|
-
|
105
|
-
def find(name)
|
106
|
-
target = mapping(name)
|
107
|
-
target ||= children.find do |child|
|
108
|
-
!child.is_a?(Project) && child.name == name
|
109
|
-
end
|
110
|
-
target ||= parent.find(name) if parent
|
111
|
-
return target
|
71
|
+
return normalized_targets
|
112
72
|
end
|
113
73
|
end
|
114
74
|
end
|
115
75
|
|
76
|
+
require 'bake/file_target'
|
77
|
+
require 'bake/project'
|
78
|
+
|
data/lib/bake/toolset.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
|
+
require 'bake/plugin'
|
2
|
+
|
1
3
|
module Bake
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Toolset
|
5
|
+
include Addon
|
6
|
+
|
7
|
+
def constructor(name, target_class)
|
8
|
+
toolset = self
|
9
|
+
command(name) do |*args|
|
10
|
+
block = args.last.is_a?(Proc) ? args.pop : nil
|
11
|
+
target = target_class.new(current, toolset, *args)
|
12
|
+
context_eval(target, &block) if block
|
13
|
+
return target
|
14
|
+
end
|
8
15
|
end
|
9
16
|
end
|
10
17
|
end
|