rscons 1.9.3 → 1.10.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,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8dbbb85ee44633f0af254208d3babe2415b70a37
4
- data.tar.gz: 5f360f841852afe46237d5f26984a38f155704da
3
+ metadata.gz: 8ceb5baf09b2d108fcb231a024434805e133d3fa
4
+ data.tar.gz: c38980efedd1fca10de580afa672a8fe5ad444cd
5
5
  SHA512:
6
- metadata.gz: 13333e94ec23446f681ad30a5d219e2e5658bc50f244d55788d7407541480d2a631394a6b42ec02f73767876969085bc7f09b92173661ed844bf6e236b28119d
7
- data.tar.gz: ac8cb2130e604b31c2de4901cb074538cb75288b85ea8a2e7ad606c03f454a42b4e911270f7c045d5e7def59984b1753c8e261186a6056f6a3bf3db122866b76
6
+ metadata.gz: f58839f1655e17599d94cc7e694cda950c61ed224520fa9a1b38e3c9d5171b9b978571f5554f8c73854557a9c714f3de98b274204a073ac91f07da734a73c60c
7
+ data.tar.gz: 858a9dbdb7d95ec61e24eac775a22532c55a2482bf1df57420bd18b31b034893c52210f1e436d1f5ca16940f2da9df99c9e455872c8dedc6dbb6fb6a0ff69cde
@@ -2,6 +2,8 @@ require_relative "rscons/build_target"
2
2
  require_relative "rscons/builder"
3
3
  require_relative "rscons/cache"
4
4
  require_relative "rscons/environment"
5
+ require_relative "rscons/job_set"
6
+ require_relative "rscons/threaded_command"
5
7
  require_relative "rscons/varset"
6
8
  require_relative "rscons/version"
7
9
 
@@ -15,6 +17,8 @@ require_relative "rscons/builders/library"
15
17
  require_relative "rscons/builders/object"
16
18
  require_relative "rscons/builders/preprocess"
17
19
  require_relative "rscons/builders/program"
20
+ require_relative "rscons/builders/shared_library"
21
+ require_relative "rscons/builders/shared_object"
18
22
  require_relative "rscons/builders/simple_builder"
19
23
 
20
24
  # Namespace module for rscons classes
@@ -33,6 +37,8 @@ module Rscons
33
37
  :Object,
34
38
  :Preprocess,
35
39
  :Program,
40
+ :SharedLibrary,
41
+ :SharedObject,
36
42
  ]
37
43
 
38
44
  # Class to represent a fatal error while building a target.
@@ -40,6 +46,10 @@ module Rscons
40
46
 
41
47
  class << self
42
48
 
49
+ # @return [Integer]
50
+ # The number of threads to use when scheduling subprocesses.
51
+ attr_accessor :n_threads
52
+
43
53
  # Remove all generated files.
44
54
  #
45
55
  # @return [void]
@@ -65,7 +75,11 @@ module Rscons
65
75
  #
66
76
  # @return [Boolean] Whether the given path is an absolute filesystem path.
67
77
  def absolute_path?(path)
68
- path =~ %r{^(/|\w:[\\/])}
78
+ if RUBY_PLATFORM =~ /mingw/
79
+ path =~ %r{^(?:\w:)?[\\/]}
80
+ else
81
+ path.start_with?("/")
82
+ end
69
83
  end
70
84
 
71
85
  # Return whether the given target is a phony target.
@@ -146,7 +160,45 @@ module Rscons
146
160
  @command_executer = val
147
161
  end
148
162
 
163
+ private
164
+
165
+ # Determine the number of threads to use by default.
166
+ #
167
+ # @return [Integer]
168
+ # The number of threads to use by default.
169
+ def determine_n_threads
170
+ # If the user specifies the number of threads in the environment, then
171
+ # respect that.
172
+ if ENV["RSCONS_NTHREADS"] =~ /^(\d+)$/
173
+ return $1.to_i
174
+ end
175
+
176
+ # Otherwise try to figure out how many threads are available on the
177
+ # host hardware.
178
+ begin
179
+ case RbConfig::CONFIG["host_os"]
180
+ when /linux/
181
+ return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size
182
+ when /mswin|mingw/
183
+ if `wmic cpu get NumberOfLogicalProcessors /value` =~ /NumberOfLogicalProcessors=(\d+)/
184
+ return $1.to_i
185
+ end
186
+ when /darwin/
187
+ if `sysctl -n hw.ncpu` =~ /(\d+)/
188
+ return $1.to_i
189
+ end
190
+ end
191
+ rescue
192
+ end
193
+
194
+ # If we can't figure it out, default to 1.
195
+ 1
196
+ end
197
+
149
198
  end
199
+
200
+ @n_threads = determine_n_threads
201
+
150
202
  end
151
203
 
152
204
  # Unbuffer $stdout
@@ -24,6 +24,14 @@ module Rscons
24
24
  {}
25
25
  end
26
26
 
27
+ # Return a set of build features that this builder provides.
28
+ #
29
+ # @return [Array<String>]
30
+ # Set of build features that this builder provides.
31
+ def features
32
+ []
33
+ end
34
+
27
35
  # Create a BuildTarget object for this build target.
28
36
  #
29
37
  # Builder sub-classes can override this method to manipulate parameters
@@ -36,6 +44,8 @@ module Rscons
36
44
  # The user-supplied target name.
37
45
  # @option options [Array<String>] :sources
38
46
  # The user-supplied source file name(s).
47
+ # @option options [Hash,VarSet] :vars
48
+ # Extra construction variables.
39
49
  #
40
50
  # @return [BuildTarget]
41
51
  def create_build_target(options)
@@ -45,9 +55,12 @@ module Rscons
45
55
  # Return whether this builder object is capable of producing a given target
46
56
  # file name from a given source file name.
47
57
  #
48
- # @param target [String] The target file name.
49
- # @param source [String] The source file name.
50
- # @param env [Environment] The Environment.
58
+ # @param target [String]
59
+ # The target file name.
60
+ # @param source [String]
61
+ # The source file name.
62
+ # @param env [Environment]
63
+ # The Environment.
51
64
  #
52
65
  # @return [Boolean]
53
66
  # Whether this builder object is capable of producing a given target
@@ -56,22 +69,128 @@ module Rscons
56
69
  false
57
70
  end
58
71
 
72
+ # Set up a build operation using this builder.
73
+ #
74
+ # This method is called when a build target is registered using this
75
+ # builder. This method should not do any building, but should perform any
76
+ # setup needed and register any prerequisite build targets that need to be
77
+ # built before the target being requested here.
78
+ #
79
+ # If the builder needs no special setup, it does not need to override this
80
+ # method. If there is any information produced in this method that will be
81
+ # needed later in the build, it can be stored in the return value from this
82
+ # method, which will be passed to the {#run} method.
83
+ #
84
+ # @since 1.10.0
85
+ #
86
+ # @param options [Hash]
87
+ # Options.
88
+ # @option options [String] :target
89
+ # Target file name.
90
+ # @option options [Array<String>] :sources
91
+ # Source file name(s).
92
+ # @option options [Environment] :env
93
+ # The Environment executing the builder.
94
+ # @option options [Hash,VarSet] :vars
95
+ # Extra construction variables.
96
+ #
97
+ # @return [Object]
98
+ # Any object that the builder author wishes to be saved and passed back
99
+ # in to the {#run} method.
100
+ def setup(options)
101
+ end
102
+
59
103
  # Run the builder to produce a build target.
60
104
  #
61
- # @param target [String] Target file name.
62
- # @param sources [Array<String>] Source file name(s).
63
- # @param cache [Cache] The Cache object.
64
- # @param env [Environment] The Environment executing the builder.
65
- # @param vars [Hash,VarSet] Extra construction variables.
105
+ # The run method supports two different signatures - an older signature
106
+ # with five separate arguments, and a newer one with one Hash argument. A
107
+ # builder author can use either signature, and Rscons will automatically
108
+ # determine which arguments to pass when invoking the run method based on
109
+ # the method's arity.
66
110
  #
67
- # @return [String,false]
111
+ # @overload run(target, sources, cache, env, vars)
112
+ #
113
+ # @param target [String]
114
+ # Target file name.
115
+ # @param sources [Array<String>]
116
+ # Source file name(s).
117
+ # @param cache [Cache]
118
+ # The Cache object.
119
+ # @param env [Environment]
120
+ # The Environment executing the builder.
121
+ # @param vars [Hash,VarSet]
122
+ # Extra construction variables.
123
+ #
124
+ # @overload run(options)
125
+ #
126
+ # @since 1.10.0
127
+ #
128
+ # @param options [Hash]
129
+ # Run options.
130
+ # @option options [String] :target
131
+ # Target file name.
132
+ # @option options [Array<String>] :sources
133
+ # Source file name(s).
134
+ # @option options [Cache] :cache
135
+ # The Cache object.
136
+ # @option options [Environment] :env
137
+ # The Environment executing the builder.
138
+ # @option options [Hash,VarSet] :vars
139
+ # Extra construction variables.
140
+ # @option options [Object] :setup_info
141
+ # Whatever value was returned from this builder's {#setup} method call.
142
+ #
143
+ # @return [ThreadedCommand,String,false]
68
144
  # Name of the target file on success or false on failure.
69
- def run(target, sources, cache, env, vars)
145
+ # Since 1.10.0, this method may return an instance of {ThreadedCommand}.
146
+ # In that case, the build operation has not actually been completed yet
147
+ # but the command to do so will be executed by Rscons in a separate
148
+ # thread. This allows for build parallelization. If a {ThreadedCommand}
149
+ # object is returned, the {#finalize} method will be called after the
150
+ # command has completed. The {#finalize} method should then be used to
151
+ # record cache info, if needed, and to return the true result of the
152
+ # build operation. The builder can store information to be passed in to
153
+ # the {#finalize} method by populating the :builder_info field of the
154
+ # {ThreadedCommand} object returned here.
155
+ def run(options)
70
156
  raise "This method must be overridden in a subclass"
71
157
  end
72
158
 
159
+ # Finalize a build operation.
160
+ #
161
+ # This method is called after the {#run} method if the {#run} method
162
+ # returns a {ThreadedCommand} object.
163
+ #
164
+ # @since 1.10.0
165
+ #
166
+ # @param options [Hash]
167
+ # Options.
168
+ # @option options [String] :target
169
+ # Target file name.
170
+ # @option options [Array<String>] :sources
171
+ # Source file name(s).
172
+ # @option options [Cache] :cache
173
+ # The Cache object.
174
+ # @option options [Environment] :env
175
+ # The Environment executing the builder.
176
+ # @option options [Hash,VarSet] :vars
177
+ # Extra construction variables.
178
+ # @option options [Object] :setup_info
179
+ # Whatever value was returned from this builder's {#setup} method call.
180
+ # @option options [true,false,nil] :command_status
181
+ # If the {#run} method returns a {ThreadedCommand}, this field will
182
+ # contain the return value from executing the command with
183
+ # Kernel.system().
184
+ # @option options [ThreadedCommand] :tc
185
+ # The {ThreadedCommand} object that was returned by the #run method.
186
+ #
187
+ # @return [String,false]
188
+ # Name of the target file on success or false on failure.
189
+ def finalize(options)
190
+ end
191
+
73
192
  # Check if the cache is up to date for the target and if not execute the
74
- # build command.
193
+ # build command. This method does not support parallelization.
75
194
  #
76
195
  # @param short_cmd_string [String]
77
196
  # Short description of build action to be printed when env.echo ==
@@ -96,5 +215,59 @@ module Rscons
96
215
  end
97
216
  target
98
217
  end
218
+
219
+ # Check if the cache is up to date for the target and if not create a
220
+ # {ThreadedCommand} object to execute the build command in a thread.
221
+ #
222
+ # @since 1.10.0
223
+ #
224
+ # @param short_cmd_string [String]
225
+ # Short description of build action to be printed when env.echo ==
226
+ # :short.
227
+ # @param target [String] Name of the target file.
228
+ # @param command [Array<String>]
229
+ # The command to execute to build the target.
230
+ # @param sources [Array<String>] Source file name(s).
231
+ # @param env [Environment] The Environment executing the builder.
232
+ # @param cache [Cache] The Cache object.
233
+ # @param options [Hash] Options.
234
+ # @options options [String] :stdout
235
+ # File name to redirect standard output to.
236
+ #
237
+ # @return [String,ThreadedCommand]
238
+ # The name of the target if it is already up to date or the
239
+ # {ThreadedCommand} object created to update it.
240
+ def standard_threaded_build(short_cmd_string, target, command, sources, env, cache, options = {})
241
+ if cache.up_to_date?(target, command, sources, env)
242
+ target
243
+ else
244
+ unless Rscons.phony_target?(target)
245
+ cache.mkdir_p(File.dirname(target))
246
+ FileUtils.rm_f(target)
247
+ end
248
+ tc_options = {short_description: short_cmd_string}
249
+ if options[:stdout]
250
+ tc_options[:system_options] = {out: options[:stdout]}
251
+ end
252
+ ThreadedCommand.new(command, tc_options)
253
+ end
254
+ end
255
+
256
+ # Register build results from a {ThreadedCommand} with the cache.
257
+ #
258
+ # @since 1.10.0
259
+ #
260
+ # @param options [Hash]
261
+ # Builder finalize options.
262
+ #
263
+ # @return [String, nil]
264
+ # The target name on success or nil on failure.
265
+ def standard_finalize(options)
266
+ if options[:command_status]
267
+ target, sources, cache, env = options.values_at(:target, :sources, :cache, :env)
268
+ cache.register_build(target, options[:tc].command, sources, env)
269
+ target
270
+ end
271
+ end
99
272
  end
100
273
  end
@@ -7,6 +7,7 @@ module Rscons
7
7
  # env.CFile("parser.tab.cc", "parser.yy")
8
8
  # env.CFile("lex.yy.cc", "parser.ll")
9
9
  class CFile < Builder
10
+
10
11
  # Return default construction variables for the builder.
11
12
  #
12
13
  # @param env [Environment] The Environment using the builder.
@@ -17,9 +18,11 @@ module Rscons
17
18
  "YACC" => "bison",
18
19
  "YACC_FLAGS" => ["-d"],
19
20
  "YACC_CMD" => ["${YACC}", "${YACC_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
21
+ "YACCSUFFIX" => [".y", ".yy"],
20
22
  "LEX" => "flex",
21
23
  "LEX_FLAGS" => [],
22
24
  "LEX_CMD" => ["${LEX}", "${LEX_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
25
+ "LEXSUFFIX" => [".l", ".ll"],
23
26
  }
24
27
  end
25
28
 
@@ -40,16 +43,28 @@ module Rscons
40
43
  })
41
44
  cmd =
42
45
  case
43
- when sources.first.end_with?(".l", ".ll")
46
+ when sources.first.end_with?(*env.expand_varref("${LEXSUFFIX}"))
44
47
  "LEX"
45
- when sources.first.end_with?(".y", ".yy")
48
+ when sources.first.end_with?(*env.expand_varref("${YACCSUFFIX}"))
46
49
  "YACC"
47
50
  else
48
51
  raise "Unknown source file #{sources.first.inspect} for CFile builder"
49
52
  end
50
53
  command = env.build_command("${#{cmd}_CMD}", vars)
51
- standard_build("#{cmd} #{target}", target, command, sources, env, cache)
54
+ standard_threaded_build("#{cmd} #{target}", target, command, sources, env, cache)
55
+ end
56
+
57
+ # Finalize a build.
58
+ #
59
+ # @param options [Hash]
60
+ # Finalize options.
61
+ #
62
+ # @return [String, nil]
63
+ # The target name on success or nil on failure.
64
+ def finalize(options)
65
+ standard_finalize(options)
52
66
  end
67
+
53
68
  end
54
69
  end
55
70
  end
@@ -9,25 +9,40 @@ module Rscons
9
9
  # env.Command("docs.html", "docs.md",
10
10
  # CMD => %w[pandoc -fmarkdown -thtml -o${_TARGET} ${_SOURCES}])
11
11
  class Command < Builder
12
+
12
13
  # Run the builder to produce a build target.
13
14
  #
14
- # @param target [String] Target file name.
15
- # @param sources [Array<String>] Source file name(s).
16
- # @param cache [Cache] The Cache object.
17
- # @param env [Environment] The Environment executing the builder.
18
- # @param vars [Hash,VarSet] Extra construction variables.
15
+ # @param options [Hash] Builder run options.
19
16
  #
20
- # @return [String,false]
21
- # Name of the target file on success or false on failure.
22
- def run(target, sources, cache, env, vars)
17
+ # @return [String, ThreadedCommand]
18
+ # Target file name if target is up to date or a {ThreadedCommand}
19
+ # to execute to build the target.
20
+ def run(options)
21
+ target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
23
22
  vars = vars.merge({
24
23
  "_TARGET" => target,
25
24
  "_SOURCES" => sources,
26
25
  })
27
26
  command = env.build_command("${CMD}", vars)
28
27
  cmd_desc = vars["CMD_DESC"] || "Command"
29
- standard_build("#{cmd_desc} #{target}", target, command, sources, env, cache)
28
+ options = {}
29
+ if vars["CMD_STDOUT"]
30
+ options[:stdout] = env.expand_varref("${CMD_STDOUT}", vars)
31
+ end
32
+ standard_threaded_build("#{cmd_desc} #{target}", target, command, sources, env, cache, options)
30
33
  end
34
+
35
+ # Finalize a build.
36
+ #
37
+ # @param options [Hash]
38
+ # Finalize options.
39
+ #
40
+ # @return [String, nil]
41
+ # The target name on success or nil on failure.
42
+ def finalize(options)
43
+ standard_finalize(options)
44
+ end
45
+
31
46
  end
32
47
  end
33
48
  end
@@ -2,6 +2,7 @@ module Rscons
2
2
  module Builders
3
3
  # The Disassemble builder produces a disassembly listing of a source file.
4
4
  class Disassemble < Builder
5
+
5
6
  # Return default construction variables for the builder.
6
7
  #
7
8
  # @param env [Environment] The Environment using the builder.
@@ -28,13 +29,28 @@ module Rscons
28
29
  def run(target, sources, cache, env, vars)
29
30
  vars = vars.merge("_SOURCES" => sources)
30
31
  command = env.build_command("${DISASM_CMD}", vars)
31
- unless cache.up_to_date?(target, command, sources, env)
32
+ if cache.up_to_date?(target, command, sources, env)
33
+ target
34
+ else
32
35
  cache.mkdir_p(File.dirname(target))
33
- return false unless env.execute("Disassemble #{target}", command, options: {out: target})
34
- cache.register_build(target, command, sources, env)
36
+ ThreadedCommand.new(
37
+ command,
38
+ short_description: "Disassemble #{target}",
39
+ system_options: {out: target})
35
40
  end
36
- target
37
41
  end
42
+
43
+ # Finalize a build.
44
+ #
45
+ # @param options [Hash]
46
+ # Finalize options.
47
+ #
48
+ # @return [String, nil]
49
+ # The target name on success or nil on failure.
50
+ def finalize(options)
51
+ standard_finalize(options)
52
+ end
53
+
38
54
  end
39
55
  end
40
56
  end