bake 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,45 +1,72 @@
1
1
  require 'bake/configuration'
2
- require 'bake/string_utils'
2
+ require 'bake/toolset'
3
3
 
4
4
  module Bake
5
5
  class Target
6
6
  include Configuration
7
7
 
8
- attr_reader :parent, :children, :deps, :toolset
8
+ attr_reader :parent, :children, :deps, :posts, :toolset
9
9
  attr_accessor :name
10
10
 
11
- def initialize(parent, toolset)
11
+ def initialize(parent, *args)
12
12
  @parent = parent
13
- @toolset = toolset
14
13
  @children = []
15
14
  @deps = []
15
+ @posts = []
16
+ @stale = nil
16
17
  parent.children << self if parent
17
18
 
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))
23
- end
24
- end
25
- post_initialize if respond_to?(:post_initialize)
19
+ @toolset = args.first.is_a?(Toolset) ? args.shift : nil
20
+ @building = false
21
+ props = args.last.respond_to?(:to_hash) ? args.pop : {}
22
+ props.each_pair { |name, val| opt(name => val) }
23
+
24
+ post_initialize(*args) if respond_to?(:post_initialize)
25
+ mix_in_toolset
26
+ end
27
+
28
+ def stale?
29
+ return @stale if !@stale.nil?
30
+ tmin = mtimes.min
31
+ @stale = deps.any? { |dep| dep.stale? || dep.mtimes.max > tmin }
32
+ return @stale
26
33
  end
27
34
 
28
- def build
35
+ def products
36
+ return nil
37
+ end
38
+
39
+ def built?
40
+ return @built
41
+ end
42
+
43
+ def build_r
29
44
  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)
45
+ raise "circular dependency detected in '#{self}'" if @building
46
+ @building = true
47
+ deps.each { |dep| dep.build_r }
48
+ Dir.chdir(get(:cwdir)) do
49
+ if stale?
50
+ if products
51
+ outdir = get(:outdir)
52
+ toolset.sys.mkdir_p(outdir) if !File.exists?(outdir)
53
+ end
54
+ build if respond_to?(:build)
35
55
  end
36
56
  end
57
+ @building = false
37
58
  @built = true
59
+ posts.each { |post| post.build_r }
60
+ end
61
+
62
+ def clean_r
63
+ children.each { |child| child.clean_r }
64
+ clean
38
65
  end
39
66
 
40
67
  def clean
41
- children.each { |child| child.clean }
42
- toolset.clean(self) if toolset
68
+ prods = products.make_array
69
+ toolset.sys.rm_f(prods) if !prods.empty?
43
70
  end
44
71
 
45
72
  def dep(*targets)
@@ -51,25 +78,75 @@ module Bake
51
78
  deps << target
52
79
  end
53
80
 
81
+ def post(*targets)
82
+ normalize_targets(*targets).each { |target| posts << target }
83
+ end
84
+
54
85
  def current_project
55
86
  return parent.current_project
56
87
  end
88
+
89
+ def mtimes
90
+ prods = products.make_array
91
+ return [ Time.now ] if prods.empty?
92
+ return products.make_array.collect do |prod|
93
+ File.exists?(prod) ? File.mtime(prod) : Time.at(0)
94
+ end
95
+ end
96
+
97
+ alias :id :name
98
+
99
+ def to_s
100
+ return "<#{class_name}: #{id}>"
101
+ end
102
+
103
+ protected
104
+ def class_name
105
+ return self.class.name.split('::').last
106
+ end
57
107
 
58
108
  private
59
109
  def normalize_targets(*targets)
60
110
  normalized_targets = []
61
111
  targets.flatten.each do |target|
62
112
  if !target.is_a?(Target)
63
- if File.exists?(target)
64
- target = FileTarget.new(self, target)
65
- else
113
+ begin
114
+ # resolve normal targets
66
115
  target = current_project.resolve(target)
116
+ rescue RuntimeError => e
117
+ # when no normal target exists, see if a file exists
118
+ if File.exists?(target)
119
+ target = FileTarget.new(self, toolset, target)
120
+ else
121
+ raise e
122
+ end
67
123
  end
68
124
  end
69
125
  normalized_targets << target
70
126
  end
71
127
  return normalized_targets
72
128
  end
129
+
130
+ def mix_in_toolset
131
+ return if !toolset
132
+ mixin_name = self.class.name.split('::').last
133
+ # collect all the relevant mixins
134
+ modules = []
135
+ toolset_class = toolset.class
136
+ while toolset_class && !toolset_class.equal?(::Object)
137
+ if toolset_class.const_defined?(mixin_name)
138
+ modules << toolset_class.const_get(mixin_name)
139
+ end
140
+ toolset_class = toolset_class.superclass
141
+ end
142
+ # add them in reverse order to preserve inheritance relations
143
+ modules.reverse_each do |mod|
144
+ extend(mod)
145
+ if mod.instance_methods.include?('post_initialize')
146
+ post_initialize
147
+ end
148
+ end
149
+ end
73
150
  end
74
151
  end
75
152
 
@@ -1,8 +1,15 @@
1
1
  require 'bake/plugin'
2
+ require 'fileutils'
2
3
 
3
4
  module Bake
4
- module Toolset
5
+ class Toolset
5
6
  include Addon
7
+
8
+ attr_reader :sys
9
+
10
+ def initialize(sys)
11
+ @sys = sys
12
+ end
6
13
 
7
14
  def constructor(name, target_class)
8
15
  toolset = self
@@ -1,5 +1,5 @@
1
1
  module Bake
2
- VERSION = [ 0, 1, 1 ]
2
+ VERSION = [ 0, 1, 2 ]
3
3
  VERSION_STRING = VERSION.join('.')
4
4
  end
5
5
 
@@ -0,0 +1,2 @@
1
+ require 'test_configuration'
2
+
@@ -0,0 +1,58 @@
1
+ $: << File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'test/unit'
4
+ require 'bake/configuration'
5
+
6
+ class ConfigTree
7
+ include Bake::Configuration
8
+
9
+ def initialize(parent = nil)
10
+ @parent = parent
11
+ parent.children << self if parent
12
+ @children = []
13
+ end
14
+
15
+ protected
16
+ attr_reader :parent, :children
17
+ end
18
+
19
+ class TestConfigTree < Test::Unit::TestCase
20
+ def setup
21
+ @cfg = ConfigTree.new
22
+ @parent = ConfigTree.new
23
+ @child = ConfigTree.new(@parent)
24
+ end
25
+
26
+ def test_opt
27
+ assert_raise(RuntimeError) { @cfg.opt(:yes => true, :no => false) }
28
+ assert_raise(RuntimeError) { @cfg.opt(:yes => true, :no => false) }
29
+
30
+ @cfg.opt(:defines => 'DEBUG')
31
+ assert_equal(1, @cfg[:defines].size)
32
+ assert(@cfg[:defines].include?('DEBUG'))
33
+
34
+ @cfg.opt(:defines => 'WIN32')
35
+ assert_equal(2, @cfg[:defines].size)
36
+ assert(@cfg[:defines].include?('DEBUG'))
37
+ assert(@cfg[:defines].include?('WIN32'))
38
+
39
+ @cfg.opt(:libtype => 'static')
40
+ assert_equal('static', @cfg[:libtype])
41
+
42
+ @cfg.opt(:libtype => 'dynamic')
43
+ assert_equal('dynamic', @cfg[:libtype])
44
+
45
+ assert_raise(Bake::PropertyNotFoundException) { @cfg[:random] }
46
+
47
+ assert_equal(0, @child[:defines].size)
48
+
49
+ @parent.opt(:defines => 'DEBUG')
50
+ @child.opt(:defines => 'WIN32')
51
+ assert_equal(1, @parent[:defines].size)
52
+ assert(@child[:defines].include?('DEBUG'))
53
+ assert_equal(2, @child[:defines].size)
54
+ assert(@child[:defines].include?('DEBUG'))
55
+ assert(@child[:defines].include?('WIN32'))
56
+ end
57
+ end
58
+
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: bake
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.1
7
- date: 2007-05-02 00:00:00 -04:00
6
+ version: 0.1.2
7
+ date: 2007-05-17 00:00:00 -04:00
8
8
  summary: Project-based build utility
9
9
  require_paths:
10
10
  - lib
@@ -35,17 +35,23 @@ files:
35
35
  - lib/bake/addon.rb
36
36
  - lib/bake/configuration.rb
37
37
  - lib/bake/context.rb
38
+ - lib/bake/extensions
39
+ - lib/bake/extensions.rb
38
40
  - lib/bake/file_target.rb
39
41
  - lib/bake/plugin.rb
40
42
  - lib/bake/plugins
41
43
  - lib/bake/project.rb
42
44
  - lib/bake/project_loader.rb
43
- - lib/bake/string_utils.rb
45
+ - lib/bake/system_utils.rb
44
46
  - lib/bake/target.rb
45
47
  - lib/bake/toolset.rb
48
+ - lib/bake/extensions/class.rb
49
+ - lib/bake/extensions/object.rb
50
+ - lib/bake/extensions/string.rb
46
51
  - lib/bake/plugins/cpp
47
52
  - lib/bake/plugins/cpp.rb
48
53
  - lib/bake/plugins/macro.rb
54
+ - lib/bake/plugins/runner.rb
49
55
  - lib/bake/plugins/system.rb
50
56
  - lib/bake/plugins/cpp/darwin.rb
51
57
  - lib/bake/plugins/cpp/gcc.rb
@@ -53,11 +59,8 @@ files:
53
59
  - lib/bake/plugins/cpp/msvc.rb
54
60
  - lib/bake/plugins/cpp/qt.rb
55
61
  - lib/bake/plugins/cpp/toolset_base.rb
56
- - test/bake_test.rb
57
- - test/configuration_test.rb
58
- - test/context_test.rb
59
- - test/scheme_test.rb
60
- - test/target_test.rb
62
+ - test/test_bake.rb
63
+ - test/test_configuration.rb
61
64
  - README
62
65
  - MIT-LICENSE
63
66
  - TUTORIAL
@@ -1,5 +0,0 @@
1
- require 'configuration_test'
2
- require 'scheme_test'
3
- require 'context_test'
4
- require 'target_test'
5
-
@@ -1,102 +0,0 @@
1
- $: << File.dirname(__FILE__) + '/../lib'
2
-
3
- require 'test/unit'
4
- require 'bake/configuration'
5
-
6
- class ConfigTree
7
- include Bake::Configuration
8
-
9
- def initialize(parent = nil)
10
- @parent = parent
11
- parent.children << self if parent
12
- @children = []
13
- end
14
-
15
- protected
16
- attr_reader :parent, :children
17
- end
18
-
19
- class ConfigurationTest < Test::Unit::TestCase
20
- def setup
21
- @cfg = ConfigTree.new
22
- @parent = ConfigTree.new
23
- @child = ConfigTree.new(@parent)
24
- end
25
-
26
- def test_opt
27
- assert_raise(RuntimeError) { @cfg.opt(:yes => true, :no => false) }
28
- assert_raise(RuntimeError) { @cfg.opt(:yes => true, :no => false) }
29
-
30
- @cfg.opt(:defines => 'DEBUG')
31
- assert_equal(1, @cfg[:defines].size)
32
- assert(@cfg[:defines].include?('DEBUG'))
33
-
34
- @cfg.opt(:defines => 'WIN32')
35
- assert_equal(2, @cfg[:defines].size)
36
- assert(@cfg[:defines].include?('DEBUG'))
37
- assert(@cfg[:defines].include?('WIN32'))
38
-
39
- @cfg.opt(:libtype => 'static')
40
- assert_equal('static', @cfg[:libtype])
41
-
42
- @cfg.opt(:libtype => 'dynamic')
43
- assert_equal('dynamic', @cfg[:libtype])
44
-
45
- assert_nil(@cfg[:random])
46
-
47
- assert_equal(0, @child[:defines].size)
48
-
49
- @parent.opt(:defines => 'DEBUG')
50
- @child.opt(:defines => 'WIN32')
51
- assert_equal(1, @parent[:defines].size)
52
- assert(@child[:defines].include?('DEBUG'))
53
- assert_equal(2, @child[:defines].size)
54
- assert(@child[:defines].include?('DEBUG'))
55
- assert(@child[:defines].include?('WIN32'))
56
- end
57
-
58
- def test_req
59
- assert_raise(RuntimeError) { @cfg.req(:yes => true, :no => false) }
60
-
61
- assert_raise(RuntimeError) { @cfg.req(:defines) }
62
- assert_raise(RuntimeError) { @cfg.req(:defines => 'DEBUG') }
63
-
64
- @cfg.req(:libtype => 'static')
65
- assert_equal('static', @cfg[:libtype])
66
-
67
- assert_nothing_raised { @cfg.req(:libtype => 'static') }
68
- assert_raise(RuntimeError) { @cfg.req(:libtype => 'dynamic') }
69
-
70
- @parent.req(:libtype => 'static')
71
- assert_equal('static', @parent[:libtype])
72
- assert_equal('static', @child[:libtype])
73
-
74
- assert_nothing_raised { @child.req(:libtype => 'static') }
75
- assert_raise(RuntimeError) { @child.req(:libtype => 'dynamic') }
76
-
77
- @child.req(:outdir => 'bin')
78
- assert_nil(@parent[:outdir])
79
- assert_equal('bin', @child[:outdir])
80
- end
81
-
82
- def test_opt_req
83
- @cfg.opt(:libtype => 'static')
84
- assert_equal('static', @cfg[:libtype])
85
- @cfg.req(:libtype => 'dynamic')
86
- assert_equal('dynamic', @cfg[:libtype])
87
-
88
- @parent.req(:outdir => 'bin')
89
- assert_equal('bin', @parent[:outdir])
90
- assert_equal('bin', @child[:outdir])
91
- @child.opt(:outdir => 'output')
92
- assert_equal('bin', @child[:outdir])
93
-
94
- @parent.opt(:libtype => 'static')
95
- assert_equal('static', @parent[:libtype])
96
- assert_equal('static', @child[:libtype])
97
- @child.req(:libtype => 'dynamic')
98
- assert_equal('static', @parent[:libtype])
99
- assert_equal('dynamic', @child[:libtype])
100
- end
101
- end
102
-
@@ -1,94 +0,0 @@
1
- $: << File.dirname(__FILE__) + '/../lib'
2
-
3
- require 'test/unit'
4
- require 'bake/context'
5
- require 'bake/scheme'
6
- require 'bake/target'
7
- require 'bake/toolset'
8
-
9
- module Cpp
10
- class Object < Bake::Target
11
- end
12
-
13
- class Gcc < Bake::Toolset
14
- end
15
-
16
- class Vc6 < Bake::Toolset
17
- end
18
- end
19
-
20
- module Common
21
- class Directory < Bake::Target
22
- ACCESSORS = :dir
23
- end
24
-
25
- class Toolset < Bake::Toolset
26
- end
27
- end
28
-
29
- class MockSchemeLoader
30
- def initialize
31
- @schemes =
32
- {
33
- 'cpp' => Bake::Scheme.new(Cpp),
34
- 'common' => Bake::Scheme.new(Common)
35
- }
36
- end
37
-
38
- def scheme(name)
39
- return @schemes[name]
40
- end
41
-
42
- def schemes
43
- return @schemes.values
44
- end
45
- end
46
-
47
- class ContextTest < Test::Unit::TestCase
48
- def setup
49
- @loader = MockSchemeLoader.new
50
- @context = Bake::Context.new(@loader)
51
- end
52
-
53
- def test_context_eval
54
- test_case = self
55
- ctx = @context
56
- proj = Bake::Project.new(nil)
57
- @context.context_eval(proj) { test_case.assert_same(ctx, self) }
58
- @context.context_eval(proj) { name 'a name' }
59
- assert_equal('a name', proj.name)
60
- @context.context_eval(proj, "name 'another'")
61
- assert_equal('another', proj.name)
62
- end
63
-
64
- def test_using
65
- assert_raise(RuntimeError) { @context.using('invalid.gcc') }
66
- assert_raise(RuntimeError) { @context.using('cpp.invalid') }
67
- assert_raise(RuntimeError) { @context.using('cpp') }
68
- assert_raise(RuntimeError) { @context.using(12345) }
69
- @context.using('cpp.gcc')
70
- assert_instance_of(Cpp::Gcc, @loader.scheme('cpp').toolset)
71
- @context.using('cpp.vc6')
72
- assert_instance_of(Cpp::Vc6, @loader.scheme('cpp').toolset)
73
- end
74
-
75
- def test_accessor_calls
76
- assert_raise(NoMethodError) { @context.no_dir }
77
-
78
- test_case = self
79
- assert_instance_of(Common::Directory, @context.dir)
80
- dir = @context.dir do
81
- name 'yup'
82
- end
83
- assert_equal('yup', dir.name)
84
-
85
- proj = Bake::Project.new(nil)
86
- @context.context_eval(proj) do
87
- dir { name 'a dir' }
88
- end
89
- assert_equal(1, proj.children.size)
90
- assert_instance_of(Common::Directory, proj.children[0])
91
- assert_equal('a dir', proj.children[0].name)
92
- end
93
- end
94
-