rscons 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -66,7 +66,8 @@ end
66
66
 
67
67
  ```ruby
68
68
  class GenerateFoo < Rscons::Builder
69
- def run(target, sources, cache, env, vars)
69
+ def run(target, sources, user_deps, cache, env, vars)
70
+ cache.mkdir_p(File.dirname(target))
70
71
  File.open(target, "w") do |fh|
71
72
  fh.puts <<EOF
72
73
  #define GENERATED 42
@@ -81,6 +82,40 @@ Rscons::Environment.new do |env|
81
82
  end
82
83
  ```
83
84
 
85
+ ### Example: Custom Builder That Only Regenerates When Necessary
86
+
87
+ ```ruby
88
+ class CmdBuilder < Rscons::Builder
89
+ def run(target, sources, user_deps, cache, env, vars)
90
+ cmd = ["cmd", "-i", sources.first, "-o", target]
91
+ unless cache.up_to_date?(target, cmd, sources, user_deps)
92
+ cache.mkdir_p(File.dirname(target))
93
+ system(cmd)
94
+ cache.register_build(target, cmd, sources, user_deps)
95
+ end
96
+ end
97
+ end
98
+
99
+ Rscons::Environment.new do |env|
100
+ env.CmdBuilder("foo.gen", "foo_gen.cfg")
101
+ end
102
+ ```
103
+
104
+ ### Example: Custom Builder Using Builder#standard_build()
105
+
106
+ ```ruby
107
+ class CmdBuilder < Rscons::Builder
108
+ def run(target, sources, user_deps, cache, env, vars)
109
+ cmd = ["cmd", "-i", sources.first, "-o", target]
110
+ standard_build("CmdBld #{target}", target, cmd, sources, user_deps, env, cache)
111
+ end
112
+ end
113
+
114
+ Rscons::Environment.new do |env|
115
+ env.CmdBuilder("foo.gen", "foo_gen.cfg")
116
+ end
117
+ ```
118
+
84
119
  ### Example: Using different compilation flags for some sources
85
120
 
86
121
  ```ruby
data/lib/rscons.rb CHANGED
@@ -4,7 +4,6 @@ require "rscons/environment"
4
4
  require "rscons/varset"
5
5
  require "rscons/version"
6
6
 
7
- require "rscons/monkey/module"
8
7
  require "rscons/monkey/string"
9
8
 
10
9
  # default builders
@@ -15,13 +14,12 @@ require "rscons/builders/program"
15
14
  # Namespace module for rscons classes
16
15
  module Rscons
17
16
  DEFAULT_BUILDERS = [
18
- Library,
19
- Object,
20
- Program,
17
+ :Library,
18
+ :Object,
19
+ :Program,
21
20
  ]
22
21
 
23
- class BuildError < Exception
24
- end
22
+ class BuildError < RuntimeError; end
25
23
 
26
24
  # Remove all generated files
27
25
  def self.clean
@@ -1,8 +1,17 @@
1
1
  require "fileutils"
2
2
 
3
3
  module Rscons
4
+ # Namespace module in which to store builders for convenient grouping
5
+ module Builders; end
6
+
4
7
  # Class to hold an object that knows how to build a certain type of file.
5
8
  class Builder
9
+ # Return the name of the builder.
10
+ # If not overridden this defaults to the last component of the class name.
11
+ def name
12
+ self.class.name.split(":").last
13
+ end
14
+
6
15
  # Return a set of default variable values for the Environment to use
7
16
  # unless the user overrides any.
8
17
  # @param env [Environment] The Environment.
@@ -23,11 +32,11 @@ module Rscons
23
32
  # build command.
24
33
  # Return the name of the target or false on failure.
25
34
  def standard_build(short_cmd_string, target, command, sources, env, cache)
26
- unless cache.up_to_date?(target, command, sources)
35
+ unless cache.up_to_date?(target, command, sources, env)
27
36
  cache.mkdir_p(File.dirname(target))
28
37
  FileUtils.rm_f(target)
29
38
  return false unless env.execute(short_cmd_string, command)
30
- cache.register_build(target, command, sources)
39
+ cache.register_build(target, command, sources, env)
31
40
  end
32
41
  target
33
42
  end
@@ -1,27 +1,27 @@
1
- require 'fileutils'
2
-
3
1
  module Rscons
4
- # A default RScons builder that produces a static library archive.
5
- class Library < Builder
6
- def default_variables(env)
7
- {
8
- 'AR' => 'ar',
9
- 'LIBSUFFIX' => '.a',
10
- 'ARFLAGS' => [],
11
- 'ARCMD' => ['${AR}', 'rcs', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}']
12
- }
13
- end
2
+ module Builders
3
+ # A default RScons builder that produces a static library archive.
4
+ class Rscons::Builders::Library < Rscons::Builder
5
+ def default_variables(env)
6
+ {
7
+ 'AR' => 'ar',
8
+ 'LIBSUFFIX' => '.a',
9
+ 'ARFLAGS' => [],
10
+ 'ARCMD' => ['${AR}', 'rcs', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}']
11
+ }
12
+ end
14
13
 
15
- def run(target, sources, cache, env, vars = {})
16
- # build sources to linkable objects
17
- objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars)
18
- if objects
19
- vars = vars.merge({
20
- '_TARGET' => target,
21
- '_SOURCES' => objects,
22
- })
23
- command = env.build_command(env['ARCMD'], vars)
24
- standard_build("AR #{target}", target, command, objects, env, cache)
14
+ def run(target, sources, cache, env, vars)
15
+ # build sources to linkable objects
16
+ objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars)
17
+ if objects
18
+ vars = vars.merge({
19
+ '_TARGET' => target,
20
+ '_SOURCES' => objects,
21
+ })
22
+ command = env.build_command(env['ARCMD'], vars)
23
+ standard_build("AR #{target}", target, command, objects, env, cache)
24
+ end
25
25
  end
26
26
  end
27
27
  end
@@ -1,79 +1,81 @@
1
1
  module Rscons
2
- # A default RScons builder which knows how to produce an object file from
3
- # various types of source files.
4
- class Object < Builder
5
- KNOWN_SUFFIXES = {
6
- "AS" => "ASSUFFIX",
7
- "CC" => "CSUFFIX",
8
- "CXX" => "CXXSUFFIX",
9
- "DC" => "DSUFFIX",
10
- }
2
+ module Builders
3
+ # A default RScons builder which knows how to produce an object file from
4
+ # various types of source files.
5
+ class Object < Builder
6
+ KNOWN_SUFFIXES = {
7
+ "AS" => "ASSUFFIX",
8
+ "CC" => "CSUFFIX",
9
+ "CXX" => "CXXSUFFIX",
10
+ "DC" => "DSUFFIX",
11
+ }
11
12
 
12
- def default_variables(env)
13
- {
14
- 'OBJSUFFIX' => '.o',
13
+ def default_variables(env)
14
+ {
15
+ 'OBJSUFFIX' => '.o',
15
16
 
16
- 'AS' => '${CC}',
17
- 'ASFLAGS' => [],
18
- 'ASSUFFIX' => '.S',
19
- 'ASPPPATH' => '${CPPPATH}',
20
- 'ASPPFLAGS' => '${CPPFLAGS}',
21
- 'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
22
- 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '-I${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
17
+ 'AS' => '${CC}',
18
+ 'ASFLAGS' => [],
19
+ 'ASSUFFIX' => '.S',
20
+ 'ASPPPATH' => '${CPPPATH}',
21
+ 'ASPPFLAGS' => '${CPPFLAGS}',
22
+ 'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
23
+ 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '-I${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
23
24
 
24
- 'CPPFLAGS' => [],
25
- 'CPPPATH' => [],
25
+ 'CPPFLAGS' => [],
26
+ 'CPPPATH' => [],
26
27
 
27
- 'CC' => 'gcc',
28
- 'CFLAGS' => [],
29
- 'CSUFFIX' => '.c',
30
- 'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
31
- 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${_SOURCES}'],
28
+ 'CC' => 'gcc',
29
+ 'CFLAGS' => [],
30
+ 'CSUFFIX' => '.c',
31
+ 'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
32
+ 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${_SOURCES}'],
32
33
 
33
- 'CXX' => 'g++',
34
- 'CXXFLAGS' => [],
35
- 'CXXSUFFIX' => '.cc',
36
- 'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
37
- 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${_SOURCES}'],
34
+ 'CXX' => 'g++',
35
+ 'CXXFLAGS' => [],
36
+ 'CXXSUFFIX' => '.cc',
37
+ 'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
38
+ 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${_SOURCES}'],
38
39
 
39
- 'DC' => 'gdc',
40
- 'DFLAGS' => [],
41
- 'DSUFFIX' => '.d',
42
- 'D_IMPORT_PATH' => [],
43
- 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '-I${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
44
- }
45
- end
40
+ 'DC' => 'gdc',
41
+ 'DFLAGS' => [],
42
+ 'DSUFFIX' => '.d',
43
+ 'D_IMPORT_PATH' => [],
44
+ 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '-I${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
45
+ }
46
+ end
46
47
 
47
- def produces?(target, source, env)
48
- target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
49
- source.has_suffix?(env[suffix_var])
48
+ def produces?(target, source, env)
49
+ target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
50
+ source.has_suffix?(env[suffix_var])
51
+ end
50
52
  end
51
- end
52
53
 
53
- def run(target, sources, cache, env, vars = {})
54
- vars = vars.merge({
55
- '_TARGET' => target,
56
- '_SOURCES' => sources,
57
- '_DEPFILE' => target.set_suffix('.mf'),
58
- })
59
- com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
60
- sources.first.has_suffix?(env[suffix_var])
61
- end.tap do |v|
62
- v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
63
- end.first
64
- command = env.build_command(env["#{com_prefix}CMD"], vars)
65
- unless cache.up_to_date?(target, command, sources)
66
- cache.mkdir_p(File.dirname(target))
67
- FileUtils.rm_f(target)
68
- return false unless env.execute("#{com_prefix} #{target}", command)
69
- deps = sources
70
- if File.exists?(vars['_DEPFILE'])
71
- deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target)
72
- FileUtils.rm_f(vars['_DEPFILE'])
54
+ def run(target, sources, cache, env, vars)
55
+ vars = vars.merge({
56
+ '_TARGET' => target,
57
+ '_SOURCES' => sources,
58
+ '_DEPFILE' => target.set_suffix('.mf'),
59
+ })
60
+ com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
61
+ sources.first.has_suffix?(env[suffix_var])
62
+ end.tap do |v|
63
+ v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
64
+ end.first
65
+ command = env.build_command(env["#{com_prefix}CMD"], vars)
66
+ unless cache.up_to_date?(target, command, sources, env)
67
+ cache.mkdir_p(File.dirname(target))
68
+ FileUtils.rm_f(target)
69
+ return false unless env.execute("#{com_prefix} #{target}", command)
70
+ deps = sources
71
+ if File.exists?(vars['_DEPFILE'])
72
+ deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target)
73
+ FileUtils.rm_f(vars['_DEPFILE'])
74
+ end
75
+ cache.register_build(target, command, deps.uniq, env)
73
76
  end
74
- cache.register_build(target, command, deps.uniq)
77
+ target
75
78
  end
76
- target
77
79
  end
78
80
  end
79
81
  end
@@ -1,39 +1,41 @@
1
1
  module Rscons
2
- # A default RScons builder that knows how to link object files into an
3
- # executable program.
4
- class Program < Builder
5
- def default_variables(env)
6
- {
7
- 'LD' => nil,
8
- 'OBJSUFFIX' => '.o',
9
- 'LIBSUFFIX' => '.a',
10
- 'LDFLAGS' => [],
11
- 'LIBPATH' => [],
12
- 'LIBS' => [],
13
- 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '-L${LIBPATH}', '-l${LIBS}']
14
- }
15
- end
2
+ module Builders
3
+ # A default RScons builder that knows how to link object files into an
4
+ # executable program.
5
+ class Rscons::Builders::Program < Rscons::Builder
6
+ def default_variables(env)
7
+ {
8
+ 'LD' => nil,
9
+ 'OBJSUFFIX' => '.o',
10
+ 'LIBSUFFIX' => '.a',
11
+ 'LDFLAGS' => [],
12
+ 'LIBPATH' => [],
13
+ 'LIBS' => [],
14
+ 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '-L${LIBPATH}', '-l${LIBS}']
15
+ }
16
+ end
16
17
 
17
- def run(target, sources, cache, env, vars = {})
18
- # build sources to linkable objects
19
- objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars)
20
- return false unless objects
21
- ld = if env["LD"]
22
- env["LD"]
23
- elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])}
24
- env["DC"]
25
- elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])}
26
- env["CXX"]
27
- else
28
- env["CC"]
29
- end
30
- vars = vars.merge({
31
- '_TARGET' => target,
32
- '_SOURCES' => objects,
33
- 'LD' => ld,
34
- })
35
- command = env.build_command(env['LDCMD'], vars)
36
- standard_build("LD #{target}", target, command, objects, env, cache)
18
+ def run(target, sources, cache, env, vars)
19
+ # build sources to linkable objects
20
+ objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars)
21
+ return false unless objects
22
+ ld = if env["LD"]
23
+ env["LD"]
24
+ elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])}
25
+ env["DC"]
26
+ elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])}
27
+ env["CXX"]
28
+ else
29
+ env["CC"]
30
+ end
31
+ vars = vars.merge({
32
+ '_TARGET' => target,
33
+ '_SOURCES' => objects,
34
+ 'LD' => ld,
35
+ })
36
+ command = env.build_command(env['LDCMD'], vars)
37
+ standard_build("LD #{target}", target, command, objects, env, cache)
38
+ end
37
39
  end
38
40
  end
39
41
  end
data/lib/rscons/cache.rb CHANGED
@@ -18,9 +18,15 @@ module Rscons
18
18
  # {
19
19
  # 'fname' => 'program.o',
20
20
  # 'checksum' => '87654321',
21
- # }
21
+ # },
22
22
  # ],
23
- # }
23
+ # 'user_deps' => [
24
+ # {
25
+ # 'fname' => 'lscript.ld',
26
+ # 'checksum' => '77551133',
27
+ # },
28
+ # ],
29
+ # },
24
30
  # 'program.o' => {
25
31
  # 'checksum' => '87654321',
26
32
  # 'command' => ['gcc', '-c', '-o', 'program.o', 'program.c'],
@@ -32,15 +38,16 @@ module Rscons
32
38
  # {
33
39
  # 'fname' => 'program.h',
34
40
  # 'checksum' => '7979764643',
35
- # }
36
- # ]
41
+ # },
42
+ # ],
43
+ # 'user_deps' => [],
37
44
  # }
38
- # }
45
+ # },
39
46
  # directories: {
40
47
  # 'build' => true,
41
48
  # 'build/one' => true,
42
49
  # 'build/two' => true,
43
- # }
50
+ # },
44
51
  # }
45
52
  class Cache
46
53
  #### Constants
@@ -82,6 +89,7 @@ module Rscons
82
89
  # @param target [String] The name of the target file.
83
90
  # @param command [Array] The command used to build the target.
84
91
  # @param deps [Array] List of the target's dependency files.
92
+ # @param env [Environment] The Rscons::Environment.
85
93
  # @param options [Hash] Optional options. Can contain the following keys:
86
94
  # :strict_deps::
87
95
  # Only consider a target up to date if its list of dependencies is
@@ -96,7 +104,7 @@ module Rscons
96
104
  # exactly equal to those cached
97
105
  # - each cached dependency file's current checksum matches the checksum
98
106
  # stored in the cache file
99
- def up_to_date?(target, command, deps, options = {})
107
+ def up_to_date?(target, command, deps, env, options = {})
100
108
  # target file must exist on disk
101
109
  return false unless File.exists?(target)
102
110
 
@@ -109,17 +117,24 @@ module Rscons
109
117
  # command used to build target must be identical
110
118
  return false unless @cache[:targets][target][:command] == command
111
119
 
112
- cached_deps = @cache[:targets][target][:deps].map { |dc| dc[:fname] }
120
+ cached_deps = @cache[:targets][target][:deps] or []
121
+ cached_deps_fnames = cached_deps.map { |dc| dc[:fname] }
113
122
  if options[:strict_deps]
114
123
  # depedencies passed in must exactly equal those in the cache
115
- return false unless deps == cached_deps
124
+ return false unless deps == cached_deps_fnames
116
125
  else
117
126
  # all dependencies passed in must exist in cache (but cache may have more)
118
- return false unless (Set.new(deps) - Set.new(cached_deps)).empty?
127
+ return false unless (Set.new(deps) - Set.new(cached_deps_fnames)).empty?
119
128
  end
120
129
 
130
+ # set of user dependencies must match
131
+ user_deps = env.get_user_deps(target) || []
132
+ cached_user_deps = @cache[:targets][target][:user_deps] or []
133
+ cached_user_deps_fnames = cached_user_deps.map { |dc| dc[:fname] }
134
+ return false unless user_deps == cached_user_deps_fnames
135
+
121
136
  # all cached dependencies must have their checksums match
122
- @cache[:targets][target][:deps].each do |dep_cache|
137
+ (cached_deps + cached_user_deps).each do |dep_cache|
123
138
  return false unless dep_cache[:checksum] == lookup_checksum(dep_cache[:fname])
124
139
  end
125
140
 
@@ -130,7 +145,8 @@ module Rscons
130
145
  # @param target [String] The name of the target.
131
146
  # @param command [Array] The command used to build the target.
132
147
  # @param deps [Array] List of dependencies for the target.
133
- def register_build(target, command, deps)
148
+ # @param env [Environment] The Rscons::Environment.
149
+ def register_build(target, command, deps, env)
134
150
  @cache[:targets][target.encode(__ENCODING__)] = {
135
151
  command: command,
136
152
  checksum: calculate_checksum(target),
@@ -139,7 +155,13 @@ module Rscons
139
155
  fname: dep.encode(__ENCODING__),
140
156
  checksum: lookup_checksum(dep),
141
157
  }
142
- end
158
+ end,
159
+ user_deps: (env.get_user_deps(target) || []).map do |dep|
160
+ {
161
+ fname: dep.encode(__ENCODING__),
162
+ checksum: lookup_checksum(dep),
163
+ }
164
+ end,
143
165
  }
144
166
  end
145
167
 
@@ -9,33 +9,39 @@ module Rscons
9
9
  # Hash of +{"builder_name" => builder_object}+ pairs.
10
10
  attr_reader :builders
11
11
 
12
+ # :command, :short, or :off
13
+ attr_accessor :echo
14
+
12
15
  # String or +nil+
13
- attr_accessor :build_root
16
+ attr_reader :build_root
17
+ def build_root=(build_root)
18
+ @build_root = build_root.gsub('\\', '/')
19
+ end
14
20
 
15
21
  # Create an Environment object.
16
- # @param variables [Hash]
17
- # The variables hash can contain construction variables, which are
18
- # uppercase strings (such as "CC" or "LDFLAGS"), user variables, which
19
- # are lowercase strings (such as "sources"), and RScons options, which
20
- # are lowercase symbols (such as :echo).
22
+ # @param options [Hash]
23
+ # Possible options keys:
24
+ # :echo => :command, :short, or :off (default :short)
25
+ # :build_root => String specifying build root directory (default nil)
26
+ # :exclude_builders => true to omit adding default builders (default false)
21
27
  # If a block is given, the Environment object is yielded to the block and
22
28
  # when the block returns, the {#process} method is automatically called.
23
- def initialize(variables = {})
24
- @varset = VarSet.new(variables)
29
+ def initialize(options = {})
30
+ @varset = VarSet.new
25
31
  @targets = {}
32
+ @user_deps = {}
26
33
  @builders = {}
27
34
  @build_dirs = []
28
35
  @build_hooks = []
29
- @varset[:exclude_builders] ||= []
30
- unless @varset[:exclude_builders] == :all
31
- exclude_builders = Set.new(@varset[:exclude_builders] || [])
32
- DEFAULT_BUILDERS.each do |builder_class|
33
- unless exclude_builders.include?(builder_class.short_name)
34
- add_builder(builder_class.new)
35
- end
36
+ unless options[:exclude_builders]
37
+ DEFAULT_BUILDERS.each do |builder_class_name|
38
+ builder_class = Builders.const_get(builder_class_name)
39
+ builder_class or raise "Could not find builder class #{builder_class_name}"
40
+ add_builder(builder_class.new)
36
41
  end
37
42
  end
38
- @varset[:echo] ||= :short
43
+ @echo = options[:echo] || :short
44
+ @build_root = options[:build_root]
39
45
 
40
46
  if block_given?
41
47
  yield self
@@ -45,17 +51,23 @@ module Rscons
45
51
 
46
52
  # Make a copy of the Environment object.
47
53
  # The cloned environment will contain a copy of all environment options,
48
- # construction variables, and builders. It will not contain a copy of the
49
- # targets, build hooks, build directories, or the build root. If a block
50
- # is given, the Environment object is yielded to the block and when the
51
- # block returns, the {#process} method is automatically called.
52
- def clone(variables = {})
53
- env = self.class.new
54
- @builders.each do |builder_name, builder|
55
- env.add_builder(builder)
54
+ # construction variables, and builders (unless :exclude_builders => true is
55
+ # passed as an option). It will not contain a copy of the targets, build
56
+ # hooks, build directories, or the build root. If a block is given, the
57
+ # Environment object is yielded to the block and when the block returns,
58
+ # the {#process} method is automatically called. The possible options keys
59
+ # match those documented in the #initialize method.
60
+ def clone(options = {})
61
+ env = self.class.new(
62
+ echo: options[:echo] || @echo,
63
+ build_root: options[:build_root],
64
+ exclude_builders: true)
65
+ unless options[:exclude_builders]
66
+ @builders.each do |builder_name, builder|
67
+ env.add_builder(builder)
68
+ end
56
69
  end
57
70
  env.append(@varset.clone)
58
- env.append(variables)
59
71
 
60
72
  if block_given?
61
73
  yield env
@@ -66,7 +78,7 @@ module Rscons
66
78
 
67
79
  # Add a {Builder} object to the Environment.
68
80
  def add_builder(builder)
69
- @builders[builder.class.short_name] = builder
81
+ @builders[builder.name] = builder
70
82
  var_defs = builder.default_variables(self)
71
83
  if var_defs
72
84
  var_defs.each_pair do |var, val|
@@ -99,7 +111,7 @@ module Rscons
99
111
  end
100
112
  end
101
113
  if @build_root and not found_match
102
- unless source_fname.start_with?('/') or source_fname =~ %r{^\w:[\\/]}
114
+ unless source_fname.absolute_path? or build_fname.start_with?("#{@build_root}/")
103
115
  build_fname = "#{@build_root}/#{build_fname}"
104
116
  end
105
117
  end
@@ -156,6 +168,11 @@ module Rscons
156
168
  cache.write
157
169
  end
158
170
 
171
+ # Clear all targets registered for the Environment.
172
+ def clear_targets
173
+ @targets = {}
174
+ end
175
+
159
176
  # Build a command line from the given template, resolving references to
160
177
  # variables using the Environment's construction variables and any extra
161
178
  # variables specified.
@@ -169,7 +186,7 @@ module Rscons
169
186
  end
170
187
 
171
188
  # Execute a builder command
172
- # @param short_desc [String] Message to print if the Environment's :echo
189
+ # @param short_desc [String] Message to print if the Environment's echo
173
190
  # mode is set to :short
174
191
  # @param command [Array] The command to execute.
175
192
  # @param options [Hash] Optional options to pass to Kernel#system.
@@ -177,13 +194,13 @@ module Rscons
177
194
  print_command = proc do
178
195
  puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
179
196
  end
180
- if @varset[:echo] == :command
197
+ if @echo == :command
181
198
  print_command.call
182
- elsif @varset[:echo] == :short
199
+ elsif @echo == :short
183
200
  puts short_desc
184
201
  end
185
202
  system(*command, options).tap do |result|
186
- unless result or @varset[:echo] == :command
203
+ unless result or @echo == :command
187
204
  $stdout.write "Failed command was: "
188
205
  print_command.call
189
206
  end
@@ -209,6 +226,19 @@ module Rscons
209
226
  end
210
227
  end
211
228
 
229
+ # Manually record a given target as depending on the specified
230
+ # dependency files.
231
+ def depends(target, *user_deps)
232
+ @user_deps[target] ||= []
233
+ @user_deps[target] = (@user_deps[target] + user_deps).uniq
234
+ end
235
+
236
+ # Return the list of user dependencies for a given target, or +nil+ for
237
+ # none.
238
+ def get_user_deps(target)
239
+ @user_deps[target]
240
+ end
241
+
212
242
  # Build a list of source files into files containing one of the suffixes
213
243
  # given by suffixes.
214
244
  # This method is used internally by RScons builders.
@@ -217,7 +247,7 @@ module Rscons
217
247
  # @param cache [Cache] The Cache.
218
248
  # @param vars [Hash] Extra variables to pass to the builder.
219
249
  # Return a list of the converted file names.
220
- def build_sources(sources, suffixes, cache, vars = {})
250
+ def build_sources(sources, suffixes, cache, vars)
221
251
  sources.map do |source|
222
252
  if source.has_suffix?(suffixes)
223
253
  source
@@ -17,4 +17,9 @@ class String
17
17
  def set_suffix(suffix = '')
18
18
  sub(/\.[^.]*$/, suffix)
19
19
  end
20
+
21
+ # Return whether the string represents an absolute filesystem path
22
+ def absolute_path?
23
+ self =~ %r{^(/|\w:[\\/])}
24
+ end
20
25
  end
@@ -1,4 +1,4 @@
1
1
  module Rscons
2
2
  # gem version
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
@@ -220,7 +220,7 @@ describe Rscons do
220
220
  it 'allows Ruby classes as custom builders to be used to construct files' do
221
221
  test_dir('custom_builder')
222
222
  class MySource < Rscons::Builder
223
- def run(target, sources, cache, env, vars = {})
223
+ def run(target, sources, user_deps, cache, env, vars = {})
224
224
  File.open(target, 'w') do |fh|
225
225
  fh.puts <<EOF
226
226
  #define THE_VALUE 5678
@@ -251,7 +251,8 @@ EOF
251
251
  env.Program('program-debug', Dir['src/*.c'])
252
252
  end
253
253
 
254
- release = debug.clone('CPPFLAGS' => '-DSTRING="Release Version"') do |env|
254
+ release = debug.clone do |env|
255
+ env["CPPFLAGS"] = '-DSTRING="Release Version"'
255
256
  env.build_dir('src', 'release')
256
257
  env.Program('program-release', Dir['src/*.c'])
257
258
  end
@@ -327,6 +328,37 @@ EOF
327
328
  ]
328
329
  end
329
330
 
331
+ it 'rebuilds when user-specified dependencies change' do
332
+ test_dir('simple')
333
+ Rscons::Environment.new do |env|
334
+ env.Program('simple', Dir['*.c'])
335
+ File.open("file.ld", "w") do |fh|
336
+ fh.puts("foo")
337
+ end
338
+ env.depends('simple', 'file.ld')
339
+ end
340
+ lines.should == ["CC simple.o", "LD simple"]
341
+ File.exists?('simple.o').should be_true
342
+ `./simple`.should == "This is a simple C program\n"
343
+ Rscons::Environment.new do |env|
344
+ env.Program('simple', Dir['*.c'])
345
+ File.open("file.ld", "w") do |fh|
346
+ fh.puts("bar")
347
+ end
348
+ env.depends('simple', 'file.ld')
349
+ end
350
+ lines.should == ["LD simple"]
351
+ Rscons::Environment.new do |env|
352
+ env.Program('simple', Dir['*.c'])
353
+ File.unlink("file.ld")
354
+ end
355
+ lines.should == ["LD simple"]
356
+ Rscons::Environment.new do |env|
357
+ env.Program('simple', Dir['*.c'])
358
+ end
359
+ lines.should == []
360
+ end
361
+
330
362
  unless ENV["omit_gdc_tests"]
331
363
  it "supports building D sources" do
332
364
  test_dir("d")
@@ -38,14 +38,19 @@ module Rscons
38
38
  end
39
39
 
40
40
  describe "#up_to_date?" do
41
+ empty_env = "env"
42
+ before do
43
+ empty_env.stub(:get_user_deps) { nil }
44
+ end
45
+
41
46
  it "returns false when target file does not exist" do
42
47
  File.should_receive(:exists?).with("target").and_return(false)
43
- build_from({}).up_to_date?("target", "command", []).should be_false
48
+ build_from({}).up_to_date?("target", "command", [], empty_env).should be_false
44
49
  end
45
50
 
46
51
  it "returns false when target is not registered in the cache" do
47
52
  File.should_receive(:exists?).with("target").and_return(true)
48
- build_from({}).up_to_date?("target", "command", []).should be_false
53
+ build_from({}).up_to_date?("target", "command", [], empty_env).should be_false
49
54
  end
50
55
 
51
56
  it "returns false when the target's checksum does not match" do
@@ -53,7 +58,7 @@ module Rscons
53
58
  cache = build_from(_cache)
54
59
  File.should_receive(:exists?).with("target").and_return(true)
55
60
  cache.should_receive(:calculate_checksum).with("target").and_return("def")
56
- cache.up_to_date?("target", "command", []).should be_false
61
+ cache.up_to_date?("target", "command", [], empty_env).should be_false
57
62
  end
58
63
 
59
64
  it "returns false when the build command has changed" do
@@ -61,7 +66,7 @@ module Rscons
61
66
  cache = build_from(_cache)
62
67
  File.should_receive(:exists?).with("target").and_return(true)
63
68
  cache.should_receive(:calculate_checksum).with("target").and_return("abc")
64
- cache.up_to_date?("target", "command", []).should be_false
69
+ cache.up_to_date?("target", "command", [], empty_env).should be_false
65
70
  end
66
71
 
67
72
  it "returns false when there is a new dependency" do
@@ -71,7 +76,7 @@ module Rscons
71
76
  cache = build_from(_cache)
72
77
  File.should_receive(:exists?).with("target").and_return(true)
73
78
  cache.should_receive(:calculate_checksum).with("target").and_return("abc")
74
- cache.up_to_date?("target", "command", ["dep.1", "dep.2"]).should be_false
79
+ cache.up_to_date?("target", "command", ["dep.1", "dep.2"], empty_env).should be_false
75
80
  end
76
81
 
77
82
  it "returns false when a dependency's checksum has changed" do
@@ -82,13 +87,14 @@ module Rscons
82
87
  {fname: "dep.2",
83
88
  checksum: "dep.2.chk"},
84
89
  {fname: "extra.dep",
85
- checksum: "extra.dep.chk"}]}}}
90
+ checksum: "extra.dep.chk"}],
91
+ user_deps: []}}}
86
92
  cache = build_from(_cache)
87
93
  File.should_receive(:exists?).with("target").and_return(true)
88
94
  cache.should_receive(:calculate_checksum).with("target").and_return("abc")
89
95
  cache.should_receive(:calculate_checksum).with("dep.1").and_return("dep.1.chk")
90
96
  cache.should_receive(:calculate_checksum).with("dep.2").and_return("dep.2.changed")
91
- cache.up_to_date?("target", "command", ["dep.1", "dep.2"]).should be_false
97
+ cache.up_to_date?("target", "command", ["dep.1", "dep.2"], empty_env).should be_false
92
98
  end
93
99
 
94
100
  it "returns false with strict_deps=true when cache has an extra dependency" do
@@ -99,11 +105,48 @@ module Rscons
99
105
  {fname: "dep.2",
100
106
  checksum: "dep.2.chk"},
101
107
  {fname: "extra.dep",
102
- checksum: "extra.dep.chk"}]}}}
108
+ checksum: "extra.dep.chk"}],
109
+ user_deps: []}}}
103
110
  cache = build_from(_cache)
104
111
  File.should_receive(:exists?).with("target").and_return(true)
105
112
  cache.should_receive(:calculate_checksum).with("target").and_return("abc")
106
- cache.up_to_date?("target", "command", ["dep.1", "dep.2"], strict_deps: true).should be_false
113
+ cache.up_to_date?("target", "command", ["dep.1", "dep.2"], empty_env, strict_deps: true).should be_false
114
+ end
115
+
116
+ it "returns false when there is a new user dependency" do
117
+ _cache = {targets: {"target" => {checksum: "abc",
118
+ command: "command",
119
+ deps: [{fname: "dep.1"}],
120
+ user_deps: []}}}
121
+ cache = build_from(_cache)
122
+ env = "env"
123
+ env.should_receive(:get_user_deps).with("target").and_return(["file.ld"])
124
+ File.should_receive(:exists?).with("target").and_return(true)
125
+ cache.should_receive(:calculate_checksum).with("target").and_return("abc")
126
+ cache.up_to_date?("target", "command", ["dep.1"], env).should be_false
127
+ end
128
+
129
+ it "returns false when a user dependency checksum has changed" do
130
+ _cache = {targets: {"target" => {checksum: "abc",
131
+ command: "command",
132
+ deps: [{fname: "dep.1",
133
+ checksum: "dep.1.chk"},
134
+ {fname: "dep.2",
135
+ checksum: "dep.2.chk"},
136
+ {fname: "extra.dep",
137
+ checksum: "extra.dep.chk"}],
138
+ user_deps: [{fname: "user.dep",
139
+ checksum: "user.dep.chk"}]}}}
140
+ cache = build_from(_cache)
141
+ env = "env"
142
+ env.should_receive(:get_user_deps).with("target").and_return(["user.dep"])
143
+ File.should_receive(:exists?).with("target").and_return(true)
144
+ cache.should_receive(:calculate_checksum).with("target").and_return("abc")
145
+ cache.should_receive(:calculate_checksum).with("dep.1").and_return("dep.1.chk")
146
+ cache.should_receive(:calculate_checksum).with("dep.2").and_return("dep.2.chk")
147
+ cache.should_receive(:calculate_checksum).with("extra.dep").and_return("extra.dep.chk")
148
+ cache.should_receive(:calculate_checksum).with("user.dep").and_return("INCORRECT")
149
+ cache.up_to_date?("target", "command", ["dep.1", "dep.2"], env).should be_false
107
150
  end
108
151
 
109
152
  it "returns true when no condition for false is met" do
@@ -114,14 +157,15 @@ module Rscons
114
157
  {fname: "dep.2",
115
158
  checksum: "dep.2.chk"},
116
159
  {fname: "extra.dep",
117
- checksum: "extra.dep.chk"}]}}}
160
+ checksum: "extra.dep.chk"}],
161
+ user_deps: []}}}
118
162
  cache = build_from(_cache)
119
163
  File.should_receive(:exists?).with("target").and_return(true)
120
164
  cache.should_receive(:calculate_checksum).with("target").and_return("abc")
121
165
  cache.should_receive(:calculate_checksum).with("dep.1").and_return("dep.1.chk")
122
166
  cache.should_receive(:calculate_checksum).with("dep.2").and_return("dep.2.chk")
123
167
  cache.should_receive(:calculate_checksum).with("extra.dep").and_return("extra.dep.chk")
124
- cache.up_to_date?("target", "command", ["dep.1", "dep.2"]).should be_true
168
+ cache.up_to_date?("target", "command", ["dep.1", "dep.2"], empty_env).should be_true
125
169
  end
126
170
  end
127
171
 
@@ -129,10 +173,13 @@ module Rscons
129
173
  it "stores the given information in the cache" do
130
174
  _cache = {}
131
175
  cache = build_from(_cache)
176
+ env = "env"
177
+ env.should_receive(:get_user_deps).with("the target").and_return(["user.dep"])
132
178
  cache.should_receive(:calculate_checksum).with("the target").and_return("the checksum")
133
179
  cache.should_receive(:calculate_checksum).with("dep 1").and_return("dep 1 checksum")
134
180
  cache.should_receive(:calculate_checksum).with("dep 2").and_return("dep 2 checksum")
135
- cache.register_build("the target", "the command", ["dep 1", "dep 2"])
181
+ cache.should_receive(:calculate_checksum).with("user.dep").and_return("user.dep checksum")
182
+ cache.register_build("the target", "the command", ["dep 1", "dep 2"], env)
136
183
  cached_target = cache.instance_variable_get(:@cache)[:targets]["the target"]
137
184
  cached_target.should_not be_nil
138
185
  cached_target[:command].should == "the command"
@@ -141,6 +188,9 @@ module Rscons
141
188
  {fname: "dep 1", checksum: "dep 1 checksum"},
142
189
  {fname: "dep 2", checksum: "dep 2 checksum"},
143
190
  ]
191
+ cached_target[:user_deps].should == [
192
+ {fname: "user.dep", checksum: "user.dep checksum"},
193
+ ]
144
194
  end
145
195
  end
146
196
 
@@ -1,12 +1,6 @@
1
1
  module Rscons
2
2
  describe Environment do
3
3
  describe "#initialize" do
4
- it "stores the construction variables passed in" do
5
- env = Environment.new("CFLAGS" => ["-g"], "CPPPATH" => ["dir"])
6
- env["CFLAGS"].should == ["-g"]
7
- env["CPPPATH"].should == ["dir"]
8
- end
9
-
10
4
  it "adds the default builders when they are not excluded" do
11
5
  env = Environment.new
12
6
  env.builders.size.should be > 0
@@ -17,18 +11,10 @@ module Rscons
17
11
  end
18
12
 
19
13
  it "excludes the default builders with exclude_builders: :all" do
20
- env = Environment.new(exclude_builders: :all)
14
+ env = Environment.new(exclude_builders: true)
21
15
  env.builders.size.should == 0
22
16
  end
23
17
 
24
- it "excludes the named builders" do
25
- env = Environment.new(exclude_builders: ["Library"])
26
- env.builders.size.should be > 0
27
- env.builders.find {|name, builder| name == "Object"}.should_not be_nil
28
- env.builders.find {|name, builder| name == "Program"}.should_not be_nil
29
- env.builders.find {|name, builder| name == "Library"}.should be_nil
30
- end
31
-
32
18
  context "when a block is given" do
33
19
  it "yields self and invokes #process()" do
34
20
  env = Environment.new do |env|
@@ -60,9 +46,9 @@ module Rscons
60
46
 
61
47
  describe "#add_builder" do
62
48
  it "adds the builder to the list of builders" do
63
- env = Environment.new(exclude_builders: :all)
49
+ env = Environment.new(exclude_builders: true)
64
50
  env.builders.keys.should == []
65
- env.add_builder(Rscons::Object.new)
51
+ env.add_builder(Rscons::Builders::Object.new)
66
52
  env.builders.keys.should == ["Object"]
67
53
  end
68
54
  end
@@ -75,6 +61,18 @@ module Rscons
75
61
  env.get_build_fname("src\\dir\\other.d", ".a").should == "src/dir/other.a"
76
62
  env.get_build_fname("source.cc", ".o").should == "source.o"
77
63
  end
64
+
65
+ context "with a build_root" do
66
+ it "uses the build_root unless the path is absolute" do
67
+ env = Environment.new
68
+ env.build_root = "build/proj"
69
+ env.get_build_fname("src/dir/file.c", ".o").should == "build/proj/src/dir/file.o"
70
+ env.get_build_fname("/some/lib.c", ".a").should == "/some/lib.a"
71
+ env.get_build_fname("C:\\abspath\\mod.cc", ".o").should == "C:/abspath/mod.o"
72
+ env.get_build_fname("build\\proj\\generated.c", ".o").should == "build/proj/generated.o"
73
+ env.get_build_fname("build/proj.XX", ".yy").should == "build/proj/build/proj.yy"
74
+ end
75
+ end
78
76
  end
79
77
 
80
78
  context "with build directories" do
@@ -87,19 +85,36 @@ module Rscons
87
85
  env.get_build_fname("libs/otherlib/otherlib.cc", ".o").should == "build/libs/otherlib/otherlib.o"
88
86
  env.get_build_fname("other_directory/o.d", ".a").should == "other_directory/o.a"
89
87
  end
88
+
89
+ context "with a build_root" do
90
+ it "uses the build_root unless a build directory matches or the path is absolute" do
91
+ env = Environment.new
92
+ env.build_dir("src", "bld")
93
+ env.build_dir(%r{^libs/([^/]+)}, 'build/libs/\1')
94
+ env.build_root = "bldit"
95
+
96
+ env.get_build_fname("src/input.cc", ".o").should == "bld/input.o"
97
+ env.get_build_fname("libs/lib1/some/file.c", ".o").should == "build/libs/lib1/some/file.o"
98
+ env.get_build_fname("libs/otherlib/otherlib.cc", ".o").should == "build/libs/otherlib/otherlib.o"
99
+ env.get_build_fname("other_directory/o.d", ".a").should == "bldit/other_directory/o.a"
100
+ env.get_build_fname("bldit/some/mod.d", ".a").should == "bldit/some/mod.a"
101
+ end
102
+ end
90
103
  end
91
104
  end
92
105
 
93
106
  describe "#[]" do
94
107
  it "allows reading construction variables" do
95
- env = Environment.new("CFLAGS" => ["-g", "-Wall"])
108
+ env = Environment.new
109
+ env["CFLAGS"] = ["-g", "-Wall"]
96
110
  env["CFLAGS"].should == ["-g", "-Wall"]
97
111
  end
98
112
  end
99
113
 
100
114
  describe "#[]=" do
101
115
  it "allows writing construction variables" do
102
- env = Environment.new("CFLAGS" => ["-g", "-Wall"])
116
+ env = Environment.new
117
+ env["CFLAGS"] = ["-g", "-Wall"]
103
118
  env["CFLAGS"] -= ["-g"]
104
119
  env["CFLAGS"] += ["-O3"]
105
120
  env["CFLAGS"].should == ["-Wall", "-O3"]
@@ -110,7 +125,9 @@ module Rscons
110
125
 
111
126
  describe "#append" do
112
127
  it "allows adding many construction variables at once" do
113
- env = Environment.new("CFLAGS" => ["-g"], "CPPPATH" => ["inc"])
128
+ env = Environment.new
129
+ env["CFLAGS"] = ["-g"]
130
+ env["CPPPATH"] = ["inc"]
114
131
  env.append("CFLAGS" => ["-Wall"], "CPPPATH" => ["include"])
115
132
  env["CFLAGS"].should == ["-Wall"]
116
133
  env["CPPPATH"].should == ["include"]
@@ -158,6 +175,18 @@ module Rscons
158
175
  end
159
176
  end
160
177
 
178
+ describe "#clear_targets" do
179
+ it "resets @targets to an empty hash" do
180
+ env = Environment.new
181
+ env.Program("a.out", "main.o")
182
+ expect(env.instance_variable_get(:@targets).keys).to eq(["a.out"])
183
+
184
+ env.clear_targets
185
+
186
+ expect(env.instance_variable_get(:@targets).keys).to eq([])
187
+ end
188
+ end
189
+
161
190
  describe "#build_command" do
162
191
  it "returns a command based on the variables in the Environment" do
163
192
  env = Environment.new
@@ -228,6 +257,20 @@ module Rscons
228
257
  end
229
258
  end
230
259
 
260
+ describe "#depends" do
261
+ it "records the given dependencies in @user_deps" do
262
+ env = Environment.new
263
+ env.depends("foo", "bar", "baz")
264
+ env.instance_variable_get(:@user_deps).should == {"foo" => ["bar", "baz"]}
265
+ end
266
+ it "records user dependencies only once" do
267
+ env = Environment.new
268
+ env.instance_variable_set(:@user_deps, {"foo" => ["bar"]})
269
+ env.depends("foo", "bar", "baz")
270
+ env.instance_variable_get(:@user_deps).should == {"foo" => ["bar", "baz"]}
271
+ end
272
+ end
273
+
231
274
  describe "#build_sources" do
232
275
  class ABuilder < Builder
233
276
  def produces?(target, source, env)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rscons
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-14 00:00:00.000000000 Z
12
+ date: 2013-12-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec-core
@@ -190,7 +190,6 @@ files:
190
190
  - lib/rscons/builders/program.rb
191
191
  - lib/rscons/cache.rb
192
192
  - lib/rscons/environment.rb
193
- - lib/rscons/monkey/module.rb
194
193
  - lib/rscons/monkey/string.rb
195
194
  - lib/rscons/varset.rb
196
195
  - lib/rscons/version.rb
@@ -198,7 +197,6 @@ files:
198
197
  - spec/build_tests_spec.rb
199
198
  - spec/rscons/cache_spec.rb
200
199
  - spec/rscons/environment_spec.rb
201
- - spec/rscons/monkey/module_spec.rb
202
200
  - spec/rscons/varset_spec.rb
203
201
  - spec/rscons_spec.rb
204
202
  - spec/spec_helper.rb
@@ -217,7 +215,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
215
  version: '0'
218
216
  segments:
219
217
  - 0
220
- hash: -950268653
218
+ hash: -915135629
221
219
  required_rubygems_version: !ruby/object:Gem::Requirement
222
220
  none: false
223
221
  requirements:
@@ -226,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
224
  version: '0'
227
225
  segments:
228
226
  - 0
229
- hash: -950268653
227
+ hash: -915135629
230
228
  requirements: []
231
229
  rubyforge_project:
232
230
  rubygems_version: 1.8.23
@@ -237,7 +235,6 @@ test_files:
237
235
  - spec/build_tests_spec.rb
238
236
  - spec/rscons/cache_spec.rb
239
237
  - spec/rscons/environment_spec.rb
240
- - spec/rscons/monkey/module_spec.rb
241
238
  - spec/rscons/varset_spec.rb
242
239
  - spec/rscons_spec.rb
243
240
  - spec/spec_helper.rb
@@ -1,7 +0,0 @@
1
- # Standard Ruby Module class.
2
- class Module
3
- # @return the base module name (not the fully qualified name)
4
- def short_name
5
- name.split(':').last
6
- end
7
- end
@@ -1,6 +0,0 @@
1
- describe "Module#short_name" do
2
- it "returns the inner name of the module" do
3
- Rscons::Environment.short_name.should == "Environment"
4
- Rscons::Object.short_name.should == "Object"
5
- end
6
- end