bake 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|