rscons 1.8.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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