rscons 1.8.1 → 1.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1d1e6dfd12a1ed7192a3b255d62309f86203bcdb
4
- data.tar.gz: 477a0cd6ef5341a401ddf0fa43f501b5c3efa520
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MWI2OTdhMDUzYjBhZGY4NWRhNDZkOWYwNjBkYzA5OGZhNTJiOGI1Mw==
5
+ data.tar.gz: !binary |-
6
+ M2QwZmE3NjFmNTc5NmU1M2NlYWE1NGIyZGJjNWZiOWI0NGI5ZmExNQ==
5
7
  SHA512:
6
- metadata.gz: 6d64d376161937078c9fc5979ff4cd43e578c216bc10fdb721d3d371e919b0cff1585644d5c157025fa34836578c73810674295864835b9ab68c31be26f4bb72
7
- data.tar.gz: 676b619be05e755bc853263e8468bd115843f3b55f74bdc3a7bdc17cf1d24467dde0ab25f69396eda933d367e37ecbe4e0af0d1eb6b1d69a2966c23e3942a2d9
8
+ metadata.gz: !binary |-
9
+ YTQ3ODI3N2ZlNjQ4OWVmOWQ3NWRmMTQ2M2Y1NTBkOWExMTg3ZDRiODBiMmU2
10
+ NTdlNDliNmUyNWY5OTEyMmM4MzE5OWNkYjJmNjNiMDQxYTQ0N2UzMzhlNTkz
11
+ ZDg5YmNjM2ZjZTE0N2NiNjBiYWUxYjY4NzJmOWJkY2M3MmJkZDk=
12
+ data.tar.gz: !binary |-
13
+ ZTYxNmZjNjQzMjFlOWZjZDZiMzE2MGFmYzAyMzk0MWE2NjRjNWQ3NWMwNDVl
14
+ MDAzODUxOWZjYzNmZDQxZjVjMjA4ODQ3YzkwYjE3Mjc5MGU5MTllZjJlOTU5
15
+ NGVkYTc2OTVmZTY1ZWNkNDVjY2M4ZWMzZWNkMTZjODUwYzRlMWM=
data/bin/rscons ADDED
@@ -0,0 +1,3 @@
1
+ require "rscons/cli"
2
+
3
+ Rscons::Cli.run(ARGV)
data/lib/rscons.rb CHANGED
@@ -6,9 +6,11 @@ require_relative "rscons/varset"
6
6
  require_relative "rscons/version"
7
7
 
8
8
  # default builders
9
- require_relative "rscons/builders/command"
10
9
  require_relative "rscons/builders/cfile"
10
+ require_relative "rscons/builders/command"
11
+ require_relative "rscons/builders/directory"
11
12
  require_relative "rscons/builders/disassemble"
13
+ require_relative "rscons/builders/install"
12
14
  require_relative "rscons/builders/library"
13
15
  require_relative "rscons/builders/object"
14
16
  require_relative "rscons/builders/preprocess"
@@ -17,12 +19,16 @@ require_relative "rscons/builders/simple_builder"
17
19
 
18
20
  # Namespace module for rscons classes
19
21
  module Rscons
22
+
20
23
  # Names of the default builders which will be added to all newly created
21
24
  # {Environment} objects.
22
25
  DEFAULT_BUILDERS = [
23
- :Command,
24
26
  :CFile,
27
+ :Command,
28
+ :Copy,
29
+ :Directory,
25
30
  :Disassemble,
31
+ :Install,
26
32
  :Library,
27
33
  :Object,
28
34
  :Preprocess,
@@ -32,101 +38,114 @@ module Rscons
32
38
  # Class to represent a fatal error while building a target.
33
39
  class BuildError < RuntimeError; end
34
40
 
35
- # Remove all generated files.
36
- #
37
- # @return [void]
38
- def self.clean
39
- cache = Cache.instance
40
- # remove all built files
41
- cache.targets.each do |target|
42
- FileUtils.rm_f(target)
43
- end
44
- # remove all created directories if they are empty
45
- cache.directories.sort {|a, b| b.size <=> a.size}.each do |directory|
46
- next unless File.directory?(directory)
47
- if (Dir.entries(directory) - ['.', '..']).empty?
48
- Dir.rmdir(directory) rescue nil
41
+ class << self
42
+
43
+ # Remove all generated files.
44
+ #
45
+ # @return [void]
46
+ def clean
47
+ cache = Cache.instance
48
+ # remove all built files
49
+ cache.targets.each do |target|
50
+ FileUtils.rm_f(target)
49
51
  end
52
+ # remove all created directories if they are empty
53
+ cache.directories.sort {|a, b| b.size <=> a.size}.each do |directory|
54
+ next unless File.directory?(directory)
55
+ if (Dir.entries(directory) - ['.', '..']).empty?
56
+ Dir.rmdir(directory) rescue nil
57
+ end
58
+ end
59
+ cache.clear
50
60
  end
51
- cache.clear
52
- end
53
61
 
54
- # Return whether the given path is an absolute filesystem path.
55
- #
56
- # @param path [String] the path to examine.
57
- #
58
- # @return [Boolean] Whether the given path is an absolute filesystem path.
59
- def self.absolute_path?(path)
60
- path =~ %r{^(/|\w:[\\/])}
61
- end
62
+ # Return whether the given path is an absolute filesystem path.
63
+ #
64
+ # @param path [String] the path to examine.
65
+ #
66
+ # @return [Boolean] Whether the given path is an absolute filesystem path.
67
+ def absolute_path?(path)
68
+ path =~ %r{^(/|\w:[\\/])}
69
+ end
62
70
 
63
- # Return a new path by changing the suffix in path to suffix.
64
- #
65
- # @param path [String] The path to alter.
66
- # @param suffix [String] The new filename suffix, e.g. ".exe".
67
- #
68
- # @return [String] New path.
69
- def self.set_suffix(path, suffix)
70
- path.sub(/\.[^.]*$/, suffix)
71
- end
71
+ # Return whether the given target is a phony target.
72
+ #
73
+ # @param target [Symbol, String] Target name.
74
+ #
75
+ # @return [Boolean] Whether the given target is a phony target.
76
+ def phony_target?(target)
77
+ target.is_a?(Symbol)
78
+ end
72
79
 
73
- # Return the system shell and arguments for executing a shell command.
74
- #
75
- # @return [Array<String>] The shell and flag.
76
- def self.get_system_shell
77
- @@shell ||=
78
- begin
79
- test_shell = lambda do |*args|
80
- begin
81
- "success" == IO.popen([*args, "echo success"]) do |io|
82
- io.read.strip
80
+ # Return a new path by changing the suffix in path to suffix.
81
+ #
82
+ # @param path [String] The path to alter.
83
+ # @param suffix [String] The new filename suffix, e.g. ".exe".
84
+ #
85
+ # @return [String] New path.
86
+ def set_suffix(path, suffix)
87
+ path.sub(/\.[^.]*$/, "") + suffix
88
+ end
89
+
90
+ # Return the system shell and arguments for executing a shell command.
91
+ #
92
+ # @return [Array<String>] The shell and flag.
93
+ def get_system_shell
94
+ @shell ||=
95
+ begin
96
+ test_shell = lambda do |*args|
97
+ begin
98
+ "success" == IO.popen([*args, "echo success"]) do |io|
99
+ io.read.strip
100
+ end
101
+ rescue
102
+ false
83
103
  end
84
- rescue
85
- false
86
104
  end
87
- end
88
- if ENV["SHELL"] and ENV["SHELL"] != "" and test_shell[ENV["SHELL"], "-c"]
89
- [ENV["SHELL"], "-c"]
90
- elsif Object.const_get("RUBY_PLATFORM") =~ /mingw/
91
- if test_shell["sh", "-c"]
92
- # Using Rscons from MSYS should use MSYS's shell.
93
- ["sh", "-c"]
105
+ if ENV["SHELL"] and ENV["SHELL"] != "" and test_shell[ENV["SHELL"], "-c"]
106
+ [ENV["SHELL"], "-c"]
107
+ elsif Object.const_get("RUBY_PLATFORM") =~ /mingw/
108
+ if test_shell["sh", "-c"]
109
+ # Using Rscons from MSYS should use MSYS's shell.
110
+ ["sh", "-c"]
111
+ else
112
+ ["cmd", "/c"]
113
+ end
94
114
  else
95
- ["cmd", "/c"]
115
+ ["sh", "-c"]
96
116
  end
97
- else
98
- ["sh", "-c"]
99
117
  end
100
- end
101
- end
118
+ end
102
119
 
103
- # Return an Array containing a command used to execute commands.
104
- #
105
- # This will normally be an empty Array, but on Windows if Rscons detects
106
- # that it is running in MSYS then ["env"] will be returned.
107
- #
108
- # @return [Array<String>] Command used to execute commands.
109
- def self.command_executer
110
- @@command_executer ||=
111
- if Object.const_get("RUBY_PLATFORM") =~ /mingw/
112
- if ENV.keys.find {|key| key =~ /MSYS/}
113
- begin
114
- if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success"
115
- ["env"]
120
+ # Return an Array containing a command used to execute commands.
121
+ #
122
+ # This will normally be an empty Array, but on Windows if Rscons detects
123
+ # that it is running in MSYS then ["env"] will be returned.
124
+ #
125
+ # @return [Array<String>] Command used to execute commands.
126
+ def command_executer
127
+ @command_executer ||=
128
+ if Object.const_get("RUBY_PLATFORM") =~ /mingw/
129
+ if ENV.keys.find {|key| key =~ /MSYS/}
130
+ begin
131
+ if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success"
132
+ ["env"]
133
+ end
134
+ rescue
116
135
  end
117
- rescue
118
136
  end
119
- end
120
- end || []
121
- end
137
+ end || []
138
+ end
139
+
140
+ # Set the command executer array.
141
+ #
142
+ # @param val [Array<String>] Command used to execute commands.
143
+ #
144
+ # @return [Array<String>] Command used to execute commands.
145
+ def command_executer=(val)
146
+ @command_executer = val
147
+ end
122
148
 
123
- # Set the command executer array.
124
- #
125
- # @param val [Array<String>] Command used to execute commands.
126
- #
127
- # @return [Array<String>] Command used to execute commands.
128
- def self.command_executer=(val)
129
- @@command_executer = val
130
149
  end
131
150
  end
132
151
 
@@ -87,8 +87,10 @@ module Rscons
87
87
  # The name of the target on success or false on failure.
88
88
  def standard_build(short_cmd_string, target, command, sources, env, cache)
89
89
  unless cache.up_to_date?(target, command, sources, env)
90
- cache.mkdir_p(File.dirname(target))
91
- FileUtils.rm_f(target)
90
+ unless Rscons.phony_target?(target)
91
+ cache.mkdir_p(File.dirname(target))
92
+ FileUtils.rm_f(target)
93
+ end
92
94
  return false unless env.execute(short_cmd_string, command)
93
95
  cache.register_build(target, command, sources, env)
94
96
  end
@@ -25,7 +25,8 @@ module Rscons
25
25
  "_SOURCES" => sources,
26
26
  })
27
27
  command = env.build_command("${CMD}", vars)
28
- standard_build("CMD #{target}", target, command, sources, env, cache)
28
+ cmd_desc = vars["CMD_DESC"] || "Command"
29
+ standard_build("#{cmd_desc} #{target}", target, command, sources, env, cache)
29
30
  end
30
31
  end
31
32
  end
@@ -0,0 +1,31 @@
1
+ module Rscons
2
+ module Builders
3
+ # The Directory builder creates a directory.
4
+ class Directory < Builder
5
+
6
+ # Run the builder to produce a build target.
7
+ #
8
+ # @param target [String] Target file name.
9
+ # @param sources [Array<String>] Source file name(s).
10
+ # @param cache [Cache] The Cache object.
11
+ # @param env [Environment] The Environment executing the builder.
12
+ # @param vars [Hash,VarSet] Extra construction variables.
13
+ #
14
+ # @return [String,false]
15
+ # Name of the target file on success or false on failure.
16
+ def run(target, sources, cache, env, vars)
17
+ if File.directory?(target)
18
+ target
19
+ elsif File.exists?(target)
20
+ $stderr.puts "Error: `#{target}' already exists and is not a directory"
21
+ false
22
+ else
23
+ puts "Directory #{target}"
24
+ cache.mkdir_p(target)
25
+ target
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,64 @@
1
+ require "pathname"
2
+
3
+ module Rscons
4
+ module Builders
5
+ # The Install builder copies files/directories to new locations.
6
+ class Install < Builder
7
+
8
+ # Run the builder to produce a build target.
9
+ #
10
+ # @param target [String] Target file name.
11
+ # @param sources [Array<String>] Source file name(s).
12
+ # @param cache [Cache] The Cache object.
13
+ # @param env [Environment] The Environment executing the builder.
14
+ # @param vars [Hash,VarSet] Extra construction variables.
15
+ #
16
+ # @return [String,false]
17
+ # Name of the target file on success or false on failure.
18
+ def run(target, sources, cache, env, vars)
19
+ target_is_dir = (sources.length > 1) ||
20
+ Dir.exists?(sources.first) ||
21
+ Dir.exists?(target)
22
+ outdir = target_is_dir ? target : File.dirname(target)
23
+ # Collect the list of files to copy over.
24
+ file_map = {}
25
+ if target_is_dir
26
+ sources.each do |src|
27
+ if Dir.exists? src
28
+ Dir.glob("#{src}/**/*", File::FNM_DOTMATCH).select do |f|
29
+ File.file?(f)
30
+ end.each do |subfile|
31
+ subpath = Pathname.new(subfile).relative_path_from(Pathname.new(src)).to_s
32
+ file_map[subfile] = "#{outdir}/#{subpath}"
33
+ end
34
+ else
35
+ file_map[src] = "#{outdir}/#{File.basename(src)}"
36
+ end
37
+ end
38
+ else
39
+ file_map[sources.first] = target
40
+ end
41
+ printed_message = false
42
+ file_map.each do |src, dest|
43
+ # Check the cache and copy if necessary
44
+ unless cache.up_to_date?(dest, :Copy, [src], env)
45
+ unless printed_message
46
+ puts "#{name} #{target}"
47
+ printed_message = true
48
+ end
49
+ cache.mkdir_p(File.dirname(dest))
50
+ FileUtils.cp(src, dest, :preserve => true)
51
+ end
52
+ cache.register_build(dest, :Copy, [src], env)
53
+ end
54
+ target if (target_is_dir ? Dir.exists?(target) : File.exists?(target))
55
+ end
56
+
57
+
58
+ end
59
+
60
+ # The Copy builder is identical to the Install builder.
61
+ class Copy < Install; end
62
+
63
+ end
64
+ end
@@ -1,7 +1,10 @@
1
+ require "fileutils"
2
+
1
3
  module Rscons
2
4
  module Builders
3
5
  # The Preprocess builder invokes the C preprocessor
4
6
  class Preprocess < Builder
7
+
5
8
  # Return default construction variables for the builder.
6
9
  #
7
10
  # @param env [Environment] The Environment using the builder.
@@ -9,7 +12,9 @@ module Rscons
9
12
  # @return [Hash] Default construction variables for the builder.
10
13
  def default_variables(env)
11
14
  {
12
- "CPP_CMD" => ["${_PREPROCESS_CC}", "-E", "-o", "${_TARGET}", "-I${CPPPATH}", "${CPPFLAGS}", "${CFLAGS}", "${_SOURCES}"],
15
+ "CPP_CMD" => %w[
16
+ ${_PREPROCESS_CC} -E ${_PREPROCESS_DEPGEN}
17
+ -o ${_TARGET} -I${CPPPATH} ${CPPFLAGS} ${_SOURCES}],
13
18
  }
14
19
  end
15
20
 
@@ -24,17 +29,32 @@ module Rscons
24
29
  # @return [String,false]
25
30
  # Name of the target file on success or false on failure.
26
31
  def run(target, sources, cache, env, vars)
27
- pp_cc = if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
28
- "${CXX}"
29
- else
30
- "${CC}"
31
- end
32
+ if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
33
+ pp_cc = "${CXX}"
34
+ depgen = "${CXXDEPGEN}"
35
+ else
36
+ pp_cc = "${CC}"
37
+ depgen = "${CCDEPGEN}"
38
+ end
32
39
  vars = vars.merge("_PREPROCESS_CC" => pp_cc,
40
+ "_PREPROCESS_DEPGEN" => depgen,
33
41
  "_TARGET" => target,
34
- "_SOURCES" => sources)
42
+ "_SOURCES" => sources,
43
+ "_DEPFILE" => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)))
35
44
  command = env.build_command("${CPP_CMD}", vars)
36
- standard_build("Preprocess #{target}", target, command, sources, env, cache)
45
+ unless cache.up_to_date?(target, command, sources, env)
46
+ cache.mkdir_p(File.dirname(target))
47
+ return false unless env.execute("Preprocess #{target}", command)
48
+ deps = sources
49
+ if File.exists?(vars["_DEPFILE"])
50
+ deps += Environment.parse_makefile_deps(vars["_DEPFILE"], nil)
51
+ FileUtils.rm_f(vars["_DEPFILE"])
52
+ end
53
+ cache.register_build(target, command, deps.uniq, env)
54
+ end
55
+ target
37
56
  end
57
+
38
58
  end
39
59
  end
40
60
  end
data/lib/rscons/cache.rb CHANGED
@@ -56,6 +56,9 @@ module Rscons
56
56
  # Name of the file to store cache information in
57
57
  CACHE_FILE = ".rsconscache"
58
58
 
59
+ # Prefix for phony cache entries.
60
+ PHONY_PREFIX = ":PHONY:"
61
+
59
62
  # Create a Cache object and load in the previous contents from the cache
60
63
  # file.
61
64
  def initialize
@@ -92,7 +95,8 @@ module Rscons
92
95
 
93
96
  # Check if target(s) are up to date.
94
97
  #
95
- # @param targets [String, Array<String>] The name(s) of the target file(s).
98
+ # @param targets [Symbol, String, Array<String>]
99
+ # The name(s) of the target file(s).
96
100
  # @param command [String, Array, Hash]
97
101
  # The command used to build the target. The command parameter can
98
102
  # actually be a String, Array, or Hash and could contain information
@@ -120,19 +124,25 @@ module Rscons
120
124
  # stored in the cache file
121
125
  def up_to_date?(targets, command, deps, env, options = {})
122
126
  Array(targets).each do |target|
123
- # target file must exist on disk
124
- return false unless File.exists?(target)
127
+ cache_key = get_cache_key(target)
128
+
129
+ unless Rscons.phony_target?(target)
130
+ # target file must exist on disk
131
+ return false unless File.exists?(target)
132
+ end
125
133
 
126
134
  # target must be registered in the cache
127
- return false unless @cache["targets"].has_key?(target)
135
+ return false unless @cache["targets"].has_key?(cache_key)
128
136
 
129
- # target must have the same checksum as when it was built last
130
- return false unless @cache["targets"][target]["checksum"] == lookup_checksum(target)
137
+ unless Rscons.phony_target?(target)
138
+ # target must have the same checksum as when it was built last
139
+ return false unless @cache["targets"][cache_key]["checksum"] == lookup_checksum(target)
140
+ end
131
141
 
132
142
  # command used to build target must be identical
133
- return false unless @cache["targets"][target]["command"] == Digest::MD5.hexdigest(command.inspect)
143
+ return false unless @cache["targets"][cache_key]["command"] == Digest::MD5.hexdigest(command.inspect)
134
144
 
135
- cached_deps = @cache["targets"][target]["deps"] || []
145
+ cached_deps = @cache["targets"][cache_key]["deps"] || []
136
146
  cached_deps_fnames = cached_deps.map { |dc| dc["fname"] }
137
147
  if options[:strict_deps]
138
148
  # depedencies passed in must exactly equal those in the cache
@@ -144,7 +154,7 @@ module Rscons
144
154
 
145
155
  # set of user dependencies must match
146
156
  user_deps = env.get_user_deps(target) || []
147
- cached_user_deps = @cache["targets"][target]["user_deps"] || []
157
+ cached_user_deps = @cache["targets"][cache_key]["user_deps"] || []
148
158
  cached_user_deps_fnames = cached_user_deps.map { |dc| dc["fname"] }
149
159
  return false unless user_deps == cached_user_deps_fnames
150
160
 
@@ -159,7 +169,8 @@ module Rscons
159
169
 
160
170
  # Store cache information about target(s) built by a builder.
161
171
  #
162
- # @param targets [String, Array<String>] The name of the target(s) built.
172
+ # @param targets [Symbol, String, Array<String>]
173
+ # The name of the target(s) built.
163
174
  # @param command [String, Array, Hash]
164
175
  # The command used to build the target. The command parameter can
165
176
  # actually be a String, Array, or Hash and could contain information
@@ -172,9 +183,10 @@ module Rscons
172
183
  # @return [void]
173
184
  def register_build(targets, command, deps, env)
174
185
  Array(targets).each do |target|
175
- @cache["targets"][target] = {
186
+ target_checksum = Rscons.phony_target?(target) ? "" : calculate_checksum(target)
187
+ @cache["targets"][get_cache_key(target)] = {
176
188
  "command" => Digest::MD5.hexdigest(command.inspect),
177
- "checksum" => calculate_checksum(target),
189
+ "checksum" => target_checksum,
178
190
  "deps" => deps.map do |dep|
179
191
  {
180
192
  "fname" => dep,
@@ -228,6 +240,21 @@ module Rscons
228
240
 
229
241
  private
230
242
 
243
+ # Return a String key based on the target name to use in the on-disk cache.
244
+ #
245
+ # @param target_name [Symbol, String]
246
+ # Target name.
247
+ #
248
+ # @return [String]
249
+ # Key name.
250
+ def get_cache_key(target_name)
251
+ if Rscons.phony_target?(target_name)
252
+ PHONY_PREFIX + target_name.to_s
253
+ else
254
+ target_name
255
+ end
256
+ end
257
+
231
258
  # Create a Cache object and load in the previous contents from the cache
232
259
  # file.
233
260
  def initialize!
data/lib/rscons/cli.rb ADDED
@@ -0,0 +1,78 @@
1
+ require "rscons"
2
+ require "optparse"
3
+
4
+ module Rscons
5
+ # Command-Line Interface functionality.
6
+ module Cli
7
+
8
+ # Default files to look for to execute if none specified.
9
+ DEFAULT_RSCONSFILES = %w[Rsconsfile Rsconsfile.rb]
10
+
11
+ class << self
12
+
13
+ # Run the Rscons CLI.
14
+ #
15
+ # @param argv [Array]
16
+ # Command-line parameters.
17
+ #
18
+ # @return [void]
19
+ def run(argv)
20
+ argv = argv.dup
21
+ rsconsfile = nil
22
+
23
+ OptionParser.new do |opts|
24
+ opts.banner = "Usage: #{$0} [options]"
25
+
26
+ opts.separator ""
27
+ opts.separator "Options:"
28
+
29
+ opts.on("-c", "--clean", "Perform clean operation") do
30
+ Rscons.clean
31
+ exit 0
32
+ end
33
+
34
+ opts.on("-f FILE", "Execute FILE (default Rsconsfile)") do |f|
35
+ rsconsfile = f
36
+ end
37
+
38
+ opts.on_tail("--version", "Show version") do
39
+ puts "Rscons version #{Rscons::VERSION}"
40
+ exit 0
41
+ end
42
+
43
+ opts.on_tail("-h", "--help", "Show this help.") do
44
+ puts opts
45
+ exit 0
46
+ end
47
+
48
+ end.parse!(argv)
49
+
50
+ if rsconsfile
51
+ unless File.exists?(rsconsfile)
52
+ $stderr.puts "Cannot read #{rsconsfile}"
53
+ exit 1
54
+ end
55
+ else
56
+ rsconsfile = DEFAULT_RSCONSFILES.find do |f|
57
+ File.exists?(f)
58
+ end
59
+ unless rsconsfile
60
+ $stderr.puts "Could not find the Rsconsfile to execute."
61
+ $stderr.puts "Looked in: [#{DEFAULT_RSCONSFILES.join(", ")}]"
62
+ exit 1
63
+ end
64
+ end
65
+
66
+ begin
67
+ load rsconsfile
68
+ rescue Rscons::BuildError => e
69
+ $stderr.puts e.message
70
+ exit 1
71
+ end
72
+
73
+ exit 0
74
+ end
75
+
76
+ end
77
+ end
78
+ end
@@ -280,33 +280,35 @@ module Rscons
280
280
  #
281
281
  # @return [void]
282
282
  def process
283
- expand_paths!
284
283
  while @targets.size > 0
284
+ expand_paths!
285
285
  targets = @targets
286
286
  @targets = {}
287
287
  cache = Cache.instance
288
288
  cache.clear_checksum_cache!
289
- targets_processed = {}
289
+ targets_processed = Set.new
290
290
  process_target = proc do |target|
291
- targets_processed[target] ||= begin
292
- targets[target][:sources].each do |src|
293
- if targets.include?(src) and not targets_processed.include?(src)
294
- process_target.call(src)
291
+ unless targets_processed.include?(target)
292
+ targets_processed << target
293
+ targets[target].each do |target_params|
294
+ target_params[:sources].each do |src|
295
+ if targets.include?(src) and not targets_processed.include?(src)
296
+ process_target.call(src)
297
+ end
298
+ end
299
+ result = run_builder(target_params[:builder],
300
+ target,
301
+ target_params[:sources],
302
+ cache,
303
+ target_params[:vars] || {})
304
+ unless result
305
+ raise BuildError.new("Failed to build #{target}")
295
306
  end
296
307
  end
297
- result = run_builder(targets[target][:builder],
298
- target,
299
- targets[target][:sources],
300
- cache,
301
- targets[target][:vars] || {})
302
- unless result
303
- raise BuildError.new("Failed to build #{target}")
304
- end
305
- result
306
308
  end
307
309
  end
308
310
  begin
309
- targets.each do |target, target_params|
311
+ targets.each_key do |target|
310
312
  process_target.call(target)
311
313
  end
312
314
  ensure
@@ -404,7 +406,8 @@ module Rscons
404
406
  #
405
407
  # @return [void]
406
408
  def add_target(target, builder, sources, vars, args)
407
- @targets[target] = {
409
+ @targets[target] ||= []
410
+ @targets[target] << {
408
411
  builder: builder,
409
412
  sources: sources,
410
413
  vars: vars,
@@ -679,14 +682,16 @@ module Rscons
679
682
  #
680
683
  # @return [void]
681
684
  def expand_paths!
682
- @targets = @targets.reduce({}) do |result, (target, target_params)|
683
- sources = target_params[:sources].map do |source|
684
- source = expand_path(source) if @build_root
685
- expand_varref(source)
686
- end
685
+ @targets = @targets.reduce({}) do |result, (target, target_params_list)|
687
686
  target = expand_path(target) if @build_root
688
687
  target = expand_varref(target)
689
- result[target] = target_params.merge(sources: sources)
688
+ result[target] = target_params_list.map do |target_params|
689
+ sources = target_params[:sources].map do |source|
690
+ source = expand_path(source) if @build_root
691
+ expand_varref(source)
692
+ end.flatten
693
+ target_params.merge(sources: sources)
694
+ end
690
695
  result
691
696
  end
692
697
  end
@@ -696,7 +701,8 @@ module Rscons
696
701
  # This method is used internally by Rscons builders.
697
702
  #
698
703
  # @param mf_fname [String] File name of the Makefile to read.
699
- # @param target [String] Name of the target to gather dependencies for.
704
+ # @param target [String, nil]
705
+ # Name of the target to gather dependencies for, nil for any/all.
700
706
  #
701
707
  # @return [Array<String>] Paths of dependency files.
702
708
  def self.parse_makefile_deps(mf_fname, target)
@@ -709,7 +715,7 @@ module Rscons
709
715
  buildup += ' ' + line
710
716
  if buildup =~ /^(.*): (.*)$/
711
717
  mf_target, mf_deps = $1.strip, $2
712
- if mf_target == target
718
+ if target.nil? or mf_target == target
713
719
  deps += mf_deps.split(' ').map(&:strip)
714
720
  end
715
721
  end
data/lib/rscons/varset.rb CHANGED
@@ -116,6 +116,8 @@ module Rscons
116
116
  expand_varref(varref[*lambda_args], lambda_args)
117
117
  elsif varref.nil?
118
118
  nil
119
+ elsif varref.is_a?(Symbol)
120
+ varref
119
121
  else
120
122
  raise "Unknown varref type: #{varref.class} (#{varref.inspect})"
121
123
  end
@@ -1,4 +1,4 @@
1
1
  module Rscons
2
2
  # gem version
3
- VERSION = "1.8.1"
3
+ VERSION = "1.9.0"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rscons
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Holtrop
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-22 00:00:00.000000000 Z
11
+ date: 2015-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -28,106 +28,111 @@ dependencies:
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ! '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ! '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: simplecov
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yard
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rdoc
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ! '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ! '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: redcarpet
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ! '>='
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description: Software construction library inspired by SCons and implemented in Ruby.
112
112
  email:
113
113
  - jholtrop@gmail.com
114
- executables: []
114
+ executables:
115
+ - rscons
115
116
  extensions: []
116
117
  extra_rdoc_files: []
117
118
  files:
118
119
  - LICENSE.txt
120
+ - bin/rscons
119
121
  - lib/rscons.rb
120
122
  - lib/rscons/build_target.rb
121
123
  - lib/rscons/builder.rb
122
124
  - lib/rscons/builders/cfile.rb
123
125
  - lib/rscons/builders/command.rb
126
+ - lib/rscons/builders/directory.rb
124
127
  - lib/rscons/builders/disassemble.rb
128
+ - lib/rscons/builders/install.rb
125
129
  - lib/rscons/builders/library.rb
126
130
  - lib/rscons/builders/object.rb
127
131
  - lib/rscons/builders/preprocess.rb
128
132
  - lib/rscons/builders/program.rb
129
133
  - lib/rscons/builders/simple_builder.rb
130
134
  - lib/rscons/cache.rb
135
+ - lib/rscons/cli.rb
131
136
  - lib/rscons/environment.rb
132
137
  - lib/rscons/varset.rb
133
138
  - lib/rscons/version.rb
@@ -142,17 +147,17 @@ require_paths:
142
147
  - lib
143
148
  required_ruby_version: !ruby/object:Gem::Requirement
144
149
  requirements:
145
- - - '>='
150
+ - - ! '>='
146
151
  - !ruby/object:Gem::Version
147
152
  version: '0'
148
153
  required_rubygems_version: !ruby/object:Gem::Requirement
149
154
  requirements:
150
- - - '>='
155
+ - - ! '>='
151
156
  - !ruby/object:Gem::Version
152
157
  version: '0'
153
158
  requirements: []
154
159
  rubyforge_project:
155
- rubygems_version: 2.4.1
160
+ rubygems_version: 2.4.3
156
161
  signing_key:
157
162
  specification_version: 4
158
163
  summary: Software construction library inspired by SCons and implemented in Ruby