rscons 1.9.3 → 1.10.0

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