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/plugins/cpp/qt.rb
CHANGED
@@ -5,42 +5,45 @@ module Bake
|
|
5
5
|
module Plugins
|
6
6
|
module Cpp
|
7
7
|
module Qt
|
8
|
-
class Moc
|
9
|
-
|
8
|
+
class Moc < Toolset
|
9
|
+
def initialize(sys)
|
10
|
+
super
|
11
|
+
command(:moc)
|
12
|
+
end
|
10
13
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
def moc(context, *srcs)
|
15
|
+
return srcs.collect do |src|
|
16
|
+
file_target = FileTarget.new(
|
17
|
+
context.current, toolset, src)
|
18
|
+
MocFile.new(context.current, self, file_target)
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
|
-
def
|
19
|
-
|
22
|
+
def build(target)
|
23
|
+
if !target.is_a?(MocFile)
|
24
|
+
raise "unknown target '#{target}'"
|
25
|
+
end
|
26
|
+
src = target.src
|
27
|
+
sys.sh("moc -o #{target.path} #{target.src}")
|
20
28
|
end
|
29
|
+
end
|
21
30
|
|
22
|
-
|
23
|
-
|
24
|
-
return
|
31
|
+
class MocFile < Source
|
32
|
+
def src
|
33
|
+
return @source.path
|
25
34
|
end
|
26
35
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
def path
|
37
|
+
src = @source.path
|
38
|
+
ext = File.extname(src)
|
39
|
+
basename = File.basename(src, ext) + '.moc' + ext
|
40
|
+
return File.join(get(:outdir), basename)
|
32
41
|
end
|
33
|
-
end
|
34
42
|
|
35
|
-
|
36
|
-
attr_reader :output
|
37
|
-
attr_accessor :src
|
43
|
+
alias :products :path
|
38
44
|
|
39
|
-
def
|
40
|
-
|
41
|
-
ext = File.extname(src)
|
42
|
-
@output = File.basename(src, ext) + '.moc' + ext
|
43
|
-
@src = src
|
45
|
+
def build
|
46
|
+
toolset.build(self)
|
44
47
|
end
|
45
48
|
end
|
46
49
|
end
|
@@ -5,76 +5,41 @@ require 'set'
|
|
5
5
|
module Bake
|
6
6
|
module Plugins
|
7
7
|
module Cpp
|
8
|
-
class ToolsetBase
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
constructor :lib, Library
|
14
|
-
constructor :exe, Executable
|
15
|
-
constructor :run, Runner
|
8
|
+
class ToolsetBase < Toolset
|
9
|
+
module Object
|
10
|
+
def products
|
11
|
+
return toolset.obj_fn(self)
|
12
|
+
end
|
16
13
|
end
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
15
|
+
module Library
|
16
|
+
def products
|
17
|
+
return toolset.lib_fn(self)
|
38
18
|
end
|
39
19
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
20
|
+
|
21
|
+
module Executable
|
22
|
+
def products
|
23
|
+
return toolset.exe_fn(self)
|
69
24
|
end
|
70
|
-
return false
|
71
25
|
end
|
72
|
-
|
73
|
-
def
|
74
|
-
|
26
|
+
|
27
|
+
def initialize(sys)
|
28
|
+
super
|
29
|
+
constructor :syslib, Cpp::SystemLibrary
|
30
|
+
constructor :lib, Cpp::Library
|
31
|
+
constructor :exe, Cpp::Executable
|
32
|
+
end
|
33
|
+
|
34
|
+
def build(target)
|
75
35
|
if target.is_a?(Cpp::Object)
|
76
|
-
|
77
|
-
|
36
|
+
compile(target)
|
37
|
+
elsif target.is_a?(Cpp::Library)
|
38
|
+
ar(target)
|
39
|
+
elsif target.is_a?(Cpp::Executable)
|
40
|
+
link(target)
|
41
|
+
else
|
42
|
+
raise "unknown Cpp target of class '#{target.class}"
|
78
43
|
end
|
79
44
|
end
|
80
45
|
|
@@ -84,13 +49,6 @@ module Bake
|
|
84
49
|
return out.to_a if out.respond_to?(:to_a)
|
85
50
|
return [ out ]
|
86
51
|
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
52
|
end
|
95
53
|
end
|
96
54
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'bake/target'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Bake
|
5
|
+
module Plugins
|
6
|
+
class Runner < Target
|
7
|
+
def post_initialize(exe)
|
8
|
+
@exe = nil
|
9
|
+
dep(exe)
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_dep(target)
|
13
|
+
@exe = target if !@exe
|
14
|
+
deps << target
|
15
|
+
end
|
16
|
+
|
17
|
+
def path
|
18
|
+
return @exe.path if @exe.is_a?(FileTarget)
|
19
|
+
return @exe.run_command
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :id :path
|
23
|
+
|
24
|
+
def build
|
25
|
+
toolset.sys.sh(path)
|
26
|
+
toolset.sys.touch(products)
|
27
|
+
end
|
28
|
+
|
29
|
+
def products
|
30
|
+
return File.join(get(:outdir), output_basename)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def output_basename
|
35
|
+
return path.basename + '.success'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
data/lib/bake/plugins/system.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
require 'bake/
|
1
|
+
require 'bake/toolset'
|
2
2
|
|
3
3
|
module Bake
|
4
4
|
module Plugins
|
5
|
-
class System
|
6
|
-
|
7
|
-
|
8
|
-
def initialize
|
5
|
+
class System < Toolset
|
6
|
+
def initialize(sys)
|
7
|
+
super
|
9
8
|
command(:glob)
|
9
|
+
constructor(:run, Plugins::Runner)
|
10
10
|
end
|
11
11
|
|
12
12
|
def glob(context, *args)
|
13
13
|
has_options = args.last.respond_to?(:to_hash)
|
14
14
|
options = has_options ? args.pop.to_hash : {}
|
15
|
-
exclude =
|
15
|
+
exclude = options[:exclude].make_array
|
16
16
|
files = []
|
17
17
|
args.each do |pat|
|
18
18
|
matches = Dir[pat]
|
@@ -22,24 +22,8 @@ module Bake
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
-
if block_given?
|
26
|
-
for i in 0...files.size
|
27
|
-
yield(files[i])
|
28
|
-
end
|
29
|
-
end
|
30
25
|
return files
|
31
26
|
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
27
|
end
|
44
28
|
end
|
45
29
|
end
|
data/lib/bake/project.rb
CHANGED
@@ -2,11 +2,11 @@ require 'bake/target'
|
|
2
2
|
|
3
3
|
module Bake
|
4
4
|
class Project < Target
|
5
|
-
|
5
|
+
attr_reader :loader
|
6
6
|
|
7
|
-
def
|
8
|
-
super(parent, nil)
|
7
|
+
def post_initialize(loader)
|
9
8
|
@loader = loader
|
9
|
+
@mappings = {}
|
10
10
|
end
|
11
11
|
|
12
12
|
def current_project
|
@@ -24,26 +24,67 @@ module Bake
|
|
24
24
|
return child || loader.load_project(self, name)
|
25
25
|
end
|
26
26
|
|
27
|
+
def map(mappings)
|
28
|
+
@mappings.merge!(mappings)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the target found at +path+ relative to this project.
|
32
|
+
# Raises a +RuntimeError+ if no such target is found.
|
33
|
+
#
|
34
|
+
# The +path+ argument is of the form:
|
35
|
+
# <dir>:<name> | <name> | <dir>
|
27
36
|
def resolve(path)
|
37
|
+
search_projects = ([ self ] + get(:search_projects))
|
28
38
|
index = path.index(':')
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
if
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
raise "invalid target path '#{path}'" if !proj
|
39
|
+
if index
|
40
|
+
# search for a fully qualified target given by dir:name
|
41
|
+
dir = path.slice(0, index)
|
42
|
+
name = path.slice(index + 1, path.length - index - 1)
|
43
|
+
else
|
44
|
+
if !path.index('/') && path != '.' && path != '..'
|
45
|
+
# search for target named by path in search_projects
|
46
|
+
target = nil
|
47
|
+
search_projects.each do |proj|
|
48
|
+
target = proj.find_target(path)
|
49
|
+
return target if target
|
50
|
+
end
|
42
51
|
end
|
52
|
+
# search for a project at given path
|
53
|
+
dir = path
|
54
|
+
name = nil
|
43
55
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
56
|
+
|
57
|
+
# iterate the search_projects looking for target given by dir:name
|
58
|
+
search_projects.each do |proj|
|
59
|
+
dir.split('/').each do |el|
|
60
|
+
if el == '.'
|
61
|
+
next
|
62
|
+
elsif el == '..'
|
63
|
+
proj = proj.parent_project
|
64
|
+
break if !proj
|
65
|
+
else
|
66
|
+
begin
|
67
|
+
proj = proj.child_project(el)
|
68
|
+
rescue ProjectLoadError
|
69
|
+
proj = nil
|
70
|
+
break
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# found a project at dir, find a child named name
|
75
|
+
if proj
|
76
|
+
return proj if !name
|
77
|
+
target = proj.find_target(name)
|
78
|
+
return target if target
|
79
|
+
end
|
80
|
+
end
|
81
|
+
raise "invalid target path '#{path}'"
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
def find_target(name)
|
86
|
+
return resolve(@mappings[name]) if @mappings.has_key?(name)
|
87
|
+
return children.find { |child| child.name == name }
|
47
88
|
end
|
48
89
|
end
|
49
90
|
end
|
data/lib/bake/project_loader.rb
CHANGED
@@ -2,6 +2,8 @@ require 'bake/target'
|
|
2
2
|
require 'bake/project'
|
3
3
|
|
4
4
|
module Bake
|
5
|
+
class ProjectLoadError < RuntimeError; end
|
6
|
+
|
5
7
|
class ProjectLoader
|
6
8
|
attr_reader :invok_project
|
7
9
|
|
@@ -11,10 +13,17 @@ module Bake
|
|
11
13
|
load_invok_project
|
12
14
|
end
|
13
15
|
|
16
|
+
# Loads a child project of the project given by +parent+. It does this
|
17
|
+
# by searching for directory called +name+ in +parent+'s +:cwdir+.
|
18
|
+
# Raises a +ProjectLoadError+ if no such directory exists. If the
|
19
|
+
# directory contains a bakefile, it will be processed in this
|
20
|
+
# +ProjectLoader+'s context.
|
14
21
|
def load_project(parent, name)
|
15
22
|
dir = File.join(parent[:cwdir], name)
|
16
|
-
|
17
|
-
|
23
|
+
if !File.directory?(dir)
|
24
|
+
raise ProjectLoadError, "no such directory '#{dir}'"
|
25
|
+
end
|
26
|
+
proj = Project.new(parent, @context.default_toolset, self)
|
18
27
|
proj.name = name
|
19
28
|
proj.opt(:projname => name)
|
20
29
|
proj.opt(:cwdir => dir)
|
@@ -30,8 +39,8 @@ module Bake
|
|
30
39
|
while true
|
31
40
|
bakefile = File.join(dir, 'root.bake')
|
32
41
|
if File.exists?(bakefile)
|
33
|
-
project = Project.new(nil, self)
|
34
|
-
project.
|
42
|
+
project = Project.new(nil, @context.default_toolset, self)
|
43
|
+
project.opt(:rootdir => dir)
|
35
44
|
project.opt(:projname => 'root')
|
36
45
|
project.opt(:cwdir => dir)
|
37
46
|
project.opt(:outdir => '${cwdir}')
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Bake
|
4
|
+
class SystemUtils
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = options
|
7
|
+
if options[:dry_run]
|
8
|
+
@file_utils = FileUtils::DryRun
|
9
|
+
elsif options[:verbose]
|
10
|
+
@file_utils = FileUtils::Verbose
|
11
|
+
else
|
12
|
+
@file_utils = FileUtils
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def dry_run?
|
17
|
+
return @options[:dry_run]
|
18
|
+
end
|
19
|
+
|
20
|
+
def verbose?
|
21
|
+
return @options[:dry_run] || @options[:verbose]
|
22
|
+
end
|
23
|
+
|
24
|
+
def sh(*args)
|
25
|
+
cmd = args.join(' ')
|
26
|
+
puts cmd if verbose?
|
27
|
+
if !dry_run?
|
28
|
+
system(*args)
|
29
|
+
raise "error: #{cmd}" if !$? || !$?.success?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def fwrite(file, contents)
|
34
|
+
puts "writing '#{file}'" if verbose?
|
35
|
+
File.open(file, "w") { |f| f.puts(contents) } if !dry_run?
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_missing(name, *args)
|
39
|
+
@file_utils.send(name, *args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|