rscons 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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