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 +36 -1
- data/lib/rscons.rb +4 -6
- data/lib/rscons/builder.rb +11 -2
- data/lib/rscons/builders/library.rb +22 -22
- data/lib/rscons/builders/object.rb +66 -64
- data/lib/rscons/builders/program.rb +36 -34
- data/lib/rscons/cache.rb +35 -13
- data/lib/rscons/environment.rb +62 -32
- data/lib/rscons/monkey/string.rb +5 -0
- data/lib/rscons/version.rb +1 -1
- data/spec/build_tests_spec.rb +34 -2
- data/spec/rscons/cache_spec.rb +62 -12
- data/spec/rscons/environment_spec.rb +63 -20
- metadata +4 -7
- data/lib/rscons/monkey/module.rb +0 -7
- data/spec/rscons/monkey/module_spec.rb +0 -6
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 <
|
24
|
-
end
|
22
|
+
class BuildError < RuntimeError; end
|
25
23
|
|
26
24
|
# Remove all generated files
|
27
25
|
def self.clean
|
data/lib/rscons/builder.rb
CHANGED
@@ -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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def default_variables(env)
|
14
|
+
{
|
15
|
+
'OBJSUFFIX' => '.o',
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
25
|
+
'CPPFLAGS' => [],
|
26
|
+
'CPPPATH' => [],
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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]
|
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 ==
|
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(
|
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
|
-
|
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
|
-
|
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
|
|
data/lib/rscons/environment.rb
CHANGED
@@ -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
|
-
|
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
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
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(
|
24
|
-
@varset = VarSet.new
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
@
|
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
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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.
|
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.
|
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
|
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 @
|
197
|
+
if @echo == :command
|
181
198
|
print_command.call
|
182
|
-
elsif @
|
199
|
+
elsif @echo == :short
|
183
200
|
puts short_desc
|
184
201
|
end
|
185
202
|
system(*command, options).tap do |result|
|
186
|
-
unless result or @
|
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
|
data/lib/rscons/monkey/string.rb
CHANGED
data/lib/rscons/version.rb
CHANGED
data/spec/build_tests_spec.rb
CHANGED
@@ -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
|
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")
|
data/spec/rscons/cache_spec.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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
|
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
|
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
|
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.
|
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-
|
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: -
|
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: -
|
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
|
data/lib/rscons/monkey/module.rb
DELETED