rscons 0.0.14 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -15,4 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
- build_tests_run
18
+ build_test_run
data/README.md CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  Software construction library inspired by SCons and implemented in Ruby
4
4
 
5
+ [![Gem Version](https://badge.fury.io/rb/rscons.png)](http://badge.fury.io/rb/rscons)
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
8
10
 
9
- gem 'rscons'
11
+ gem "rscons"
10
12
 
11
13
  And then execute:
12
14
 
@@ -18,20 +20,135 @@ Or install it yourself as:
18
20
 
19
21
  ## Usage
20
22
 
21
- RScons::Environment.new do |env|
22
- env.Program('program', Dir['*.c'])
23
- end
23
+ Rscons is a Ruby library.
24
+ It can be called from a standalone Ruby script or it can be used with rake and
25
+ called from your Rakefile.
26
+
27
+ ### Example: Building a C Program
28
+
29
+ ```ruby
30
+ RScons::Environment.new do |env|
31
+ env["CFLAGS"] << "-Wall"
32
+ env.Program("program", Dir["**/*.c"])
33
+ end
34
+ ```
35
+
36
+ ### Example: Building a D Program
37
+
38
+ ```ruby
39
+ RScons::Environment.new do |env|
40
+ env["DFLAGS"] << "-Wall"
41
+ env.Program("program", Dir["**/*.d"])
42
+ end
43
+ ```
44
+
45
+ ### Example: Cloning an Environment
24
46
 
25
- main_env = RScons::Environment.new do |env|
26
- env.build_dir('src', 'build/main')
27
- env.Program('program', Dir['src/**/*.cc'])
47
+ ```ruby
48
+ main_env = RScons::Environment.new do |env|
49
+ # Store object files from sources under "src" in "build/main"
50
+ env.build_dir("src", "build/main")
51
+ env["CFLAGS"] = ["-DSOME_DEFINE", "-O3"]
52
+ env["LIBS"] = ["SDL"]
53
+ env.Program("program", Dir["src/**/*.cc"])
54
+ end
55
+
56
+ debug_env = main_env.clone do |env|
57
+ # Store object files from sources under "src" in "build/debug"
58
+ env.build_dir("src", "build/debug")
59
+ env["CFLAGS"] -= ["-O3"]
60
+ env["CFLAGS"] += ["-g", "-O0"]
61
+ env.Program("program-debug", Dir["src/**/*.cc"])
62
+ end
63
+ ```
64
+
65
+ ### Example: Custom Builder
66
+
67
+ ```ruby
68
+ class GenerateFoo < Rscons::Builder
69
+ def run(target, sources, cache, env, vars)
70
+ File.open(target, "w") do |fh|
71
+ fh.puts <<EOF
72
+ #define GENERATED 42
73
+ EOF
28
74
  end
75
+ end
76
+ end
77
+
78
+ Rscons::Environment.new do |env|
79
+ env.GenerateFoo("foo.h", [])
80
+ env.Program("a.out", Dir["*.c"])
81
+ end
82
+ ```
29
83
 
30
- debug_env = main_env.clone do |env|
31
- env.build_dir('src', 'build/debug')
32
- env['CFLAGS'] = ['-g', '-O0']
33
- env.Program('program-debug', Dir['src/**/*.cc'])
84
+ ### Example: Using different compilation flags for some sources
85
+
86
+ ```ruby
87
+ Rscons::Environment.new do |env|
88
+ env["CFLAGS"] = ["-O3", "-Wall", "-DDEFINE"]
89
+ env.add_build_hook do |build_op|
90
+ if build_op[:target] =~ %r{build/third-party}
91
+ build_op[:vars]["CFLAGS"] -= ["-Wall"]
34
92
  end
93
+ end
94
+ env.build_dir("src", "build")
95
+ env.Program("program", Dir["**/*.cc"])
96
+ end
97
+ ```
98
+
99
+ ### Example: Creating a static library
100
+
101
+ ```ruby
102
+ Rscons::Environment.new do |env|
103
+ env.Library("mylib.a", Dir["src/**/*.c"])
104
+ end
105
+ ```
106
+
107
+ ## Details
108
+
109
+ ### Default Builders
110
+
111
+ Rscons ships with a number of default builders:
112
+
113
+ * Library, which collects object files into a static library archive file
114
+ * Object, which compiles source files to produce an object file
115
+ * Program, which links object files to produce an executable
116
+
117
+ If you want to create an Environment that does not contain any (or select)
118
+ builders, you can use the `exclude_builders` key to the Environment constructor.
119
+
120
+ ### Managing Environments
121
+
122
+ An Rscons::Environment consists of:
123
+
124
+ * a collection of construction variables
125
+ * a collection of builders
126
+ * a mapping of build directories
127
+ * a collection of targets to build
128
+ * a collection of build hooks
129
+
130
+ When cloning an environment, the construction variables, builders, and build
131
+ directories are cloned, but the new environment does not inherit any of the
132
+ targets or build hooks from the source environment.
133
+
134
+ Cloned environments contain "deep copies" of construction variables.
135
+ For example, in:
136
+
137
+ ```ruby
138
+ base_env = Rscons::Environment.new
139
+ base_env["CPPPATH"] = ["one", "two"]
140
+ cloned_env = base_env.clone
141
+ cloned_env["CPPPATH"] << "three"
142
+ ```
143
+
144
+ `base_env["CPPPATH"]` will not include "three".
145
+
146
+ ### Construction Variables
147
+
148
+ The default construction variables that Rscons uses are named using uppercase
149
+ strings.
150
+ Rscons options are lowercase symbols.
151
+ Lowercase strings are reserved as user-defined construction variables.
35
152
 
36
153
  ## Contributing
37
154
 
@@ -7,11 +7,8 @@ end
7
7
 
8
8
  require "bundler/gem_tasks"
9
9
  require "rspec/core/rake_task"
10
- require "rake/clean"
11
10
  require "yard"
12
11
 
13
- CLEAN.include 'build_tests_run'
14
-
15
12
  RSpec::Core::RakeTask.new(:spec)
16
13
 
17
14
  YARD::Rake::YardocTask.new do |yard|
@@ -19,3 +16,11 @@ YARD::Rake::YardocTask.new do |yard|
19
16
  end
20
17
 
21
18
  task :default => :spec
19
+
20
+ task :clean do
21
+ FileUtils.rm_rf(["build_test_run", "doc", "coverage"])
22
+ end
23
+
24
+ task :clobber => :clean do
25
+ FileUtils.rm_rf(["pkg"])
26
+ end
@@ -0,0 +1,6 @@
1
+ import std.stdio;
2
+
3
+ void main()
4
+ {
5
+ writeln("Hello from D!");
6
+ }
@@ -8,7 +8,7 @@ module Rscons
8
8
  'AR' => 'ar',
9
9
  'LIBSUFFIX' => '.a',
10
10
  'ARFLAGS' => [],
11
- 'ARCOM' => ['$AR', 'rcs', '$ARFLAGS', '$_TARGET', '$_SOURCES']
11
+ 'ARCMD' => ['${AR}', 'rcs', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}']
12
12
  }
13
13
  end
14
14
 
@@ -20,7 +20,7 @@ module Rscons
20
20
  '_TARGET' => target,
21
21
  '_SOURCES' => objects,
22
22
  })
23
- command = env.build_command(env['ARCOM'], vars)
23
+ command = env.build_command(env['ARCMD'], vars)
24
24
  standard_build("AR #{target}", target, command, objects, env, cache)
25
25
  end
26
26
  end
@@ -2,17 +2,24 @@ module Rscons
2
2
  # A default RScons builder which knows how to produce an object file from
3
3
  # various types of source files.
4
4
  class Object < Builder
5
+ KNOWN_SUFFIXES = {
6
+ "AS" => "ASSUFFIX",
7
+ "CC" => "CSUFFIX",
8
+ "CXX" => "CXXSUFFIX",
9
+ "DC" => "DSUFFIX",
10
+ }
11
+
5
12
  def default_variables(env)
6
13
  {
7
14
  'OBJSUFFIX' => '.o',
8
15
 
9
- 'AS' => '$CC',
16
+ 'AS' => '${CC}',
10
17
  'ASFLAGS' => [],
11
18
  'ASSUFFIX' => '.S',
12
- 'ASPPPATH' => '$CPPPATH',
13
- 'ASPPFLAGS' => '$CPPFLAGS',
14
- 'ASDEPGEN' => ['-MMD', '-MF', '$_DEPFILE'],
15
- 'ASCOM' => ['$AS', '-c', '-o', '$_TARGET', '$ASDEPGEN', '-I$[ASPPPATH]', '$ASPPFLAGS', '$ASFLAGS', '$_SOURCES'],
19
+ 'ASPPPATH' => '${CPPPATH}',
20
+ 'ASPPFLAGS' => '${CPPFLAGS}',
21
+ 'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
22
+ 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '-I${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
16
23
 
17
24
  'CPPFLAGS' => [],
18
25
  'CPPPATH' => [],
@@ -20,29 +27,27 @@ module Rscons
20
27
  'CC' => 'gcc',
21
28
  'CFLAGS' => [],
22
29
  'CSUFFIX' => '.c',
23
- 'CCDEPGEN' => ['-MMD', '-MF', '$_DEPFILE'],
24
- 'CCCOM' => ['$CC', '-c', '-o', '$_TARGET', '$CCDEPGEN', '-I$[CPPPATH]', '$CPPFLAGS', '$CFLAGS', '$_SOURCES'],
30
+ 'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
31
+ 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${_SOURCES}'],
25
32
 
26
33
  'CXX' => 'g++',
27
34
  'CXXFLAGS' => [],
28
35
  'CXXSUFFIX' => '.cc',
29
- 'CXXDEPGEN' => ['-MMD', '-MF', '$_DEPFILE'],
30
- 'CXXCOM' =>['$CXX', '-c', '-o', '$_TARGET', '$CXXDEPGEN', '-I$[CPPPATH]', '$CPPFLAGS', '$CXXFLAGS', '$_SOURCES'],
36
+ 'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
37
+ 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${_SOURCES}'],
31
38
 
32
39
  'DC' => 'gdc',
33
40
  'DFLAGS' => [],
34
41
  'DSUFFIX' => '.d',
35
42
  'D_IMPORT_PATH' => [],
36
- 'DCCOM' => ['$DC', '-c', '-o', '$_TARGET', '-I$[D_IMPORT_PATH]', '$DFLAGS', '$_SOURCES'],
43
+ 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '-I${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
37
44
  }
38
45
  end
39
46
 
40
47
  def produces?(target, source, env)
41
- target.has_suffix?(env['OBJSUFFIX']) and (
42
- source.has_suffix?(env['ASSUFFIX']) or
43
- source.has_suffix?(env['CSUFFIX']) or
44
- source.has_suffix?(env['CXXSUFFIX']) or
45
- source.has_suffix?(env['DSUFFIX']))
48
+ target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
49
+ source.has_suffix?(env[suffix_var])
50
+ end
46
51
  end
47
52
 
48
53
  def run(target, sources, cache, env, vars = {})
@@ -51,25 +56,19 @@ module Rscons
51
56
  '_SOURCES' => sources,
52
57
  '_DEPFILE' => target.set_suffix('.mf'),
53
58
  })
54
- com_prefix = if sources.first.has_suffix?(env['ASSUFFIX'])
55
- 'AS'
56
- elsif sources.first.has_suffix?(env['CSUFFIX'])
57
- 'CC'
58
- elsif sources.first.has_suffix?(env['CXXSUFFIX'])
59
- 'CXX'
60
- elsif sources.first.has_suffix?(env['DSUFFIX'])
61
- 'DC'
62
- else
63
- raise "Error: unknown input file type: #{sources.first.inspect}"
64
- end
65
- command = env.build_command(env["#{com_prefix}COM"], vars)
59
+ com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
60
+ sources.first.has_suffix?(env[suffix_var])
61
+ end.tap do |v|
62
+ v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
63
+ end.first
64
+ command = env.build_command(env["#{com_prefix}CMD"], vars)
66
65
  unless cache.up_to_date?(target, command, sources)
67
66
  cache.mkdir_p(File.dirname(target))
68
67
  FileUtils.rm_f(target)
69
68
  return false unless env.execute("#{com_prefix} #{target}", command)
70
69
  deps = sources
71
70
  if File.exists?(vars['_DEPFILE'])
72
- deps += env.parse_makefile_deps(vars['_DEPFILE'], target)
71
+ deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target)
73
72
  FileUtils.rm_f(vars['_DEPFILE'])
74
73
  end
75
74
  cache.register_build(target, command, deps.uniq)
@@ -10,31 +10,29 @@ module Rscons
10
10
  'LDFLAGS' => [],
11
11
  'LIBPATH' => [],
12
12
  'LIBS' => [],
13
- 'LDCOM' => ['$LD', '-o', '$_TARGET', '$LDFLAGS', '$_SOURCES', '-L$[LIBPATH]', '-l$[LIBS]']
13
+ 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '-L${LIBPATH}', '-l${LIBS}']
14
14
  }
15
15
  end
16
16
 
17
17
  def run(target, sources, cache, env, vars = {})
18
18
  # build sources to linkable objects
19
19
  objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars)
20
- if objects
21
- ld = if env["LD"]
22
- env["LD"]
23
- elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])}
24
- env["DC"]
25
- elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])}
26
- env["CXX"]
27
- else
28
- env["CC"]
29
- end
30
- vars = vars.merge({
31
- '_TARGET' => target,
32
- '_SOURCES' => objects,
33
- 'LD' => ld,
34
- })
35
- command = env.build_command(env['LDCOM'], vars)
36
- standard_build("LD #{target}", target, command, objects, env, cache)
37
- end
20
+ ld = if env["LD"]
21
+ env["LD"]
22
+ elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])}
23
+ env["DC"]
24
+ elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])}
25
+ env["CXX"]
26
+ else
27
+ env["CC"]
28
+ end
29
+ vars = vars.merge({
30
+ '_TARGET' => target,
31
+ '_SOURCES' => objects,
32
+ 'LD' => ld,
33
+ })
34
+ command = env.build_command(env['LDCMD'], vars)
35
+ standard_build("LD #{target}", target, command, objects, env, cache)
38
36
  end
39
37
  end
40
38
  end
@@ -67,12 +67,12 @@ module Rscons
67
67
  end
68
68
  @cache[:targets] ||= {}
69
69
  @cache[:directories] ||= {}
70
- @cache[:version] ||= VERSION
71
70
  @lookup_checksums = {}
72
71
  end
73
72
 
74
73
  # Write the cache to disk to be loaded next time.
75
74
  def write
75
+ @cache[:version] = VERSION
76
76
  File.open(CACHE_FILE, 'w') do |fh|
77
77
  fh.puts(YAML.dump(@cache))
78
78
  end
@@ -119,9 +119,11 @@ module Rscons
119
119
  end
120
120
 
121
121
  # all cached dependencies must have their checksums match
122
- @cache[:targets][target][:deps].map do |dep_cache|
123
- dep_cache[:checksum] == lookup_checksum(dep_cache[:fname])
124
- end.all?
122
+ @cache[:targets][target][:deps].each do |dep_cache|
123
+ return false unless dep_cache[:checksum] == lookup_checksum(dep_cache[:fname])
124
+ end
125
+
126
+ true
125
127
  end
126
128
 
127
129
  # Store cache information about a target built by a builder
@@ -150,13 +152,11 @@ module Rscons
150
152
  # removal upon a "clean" operation.
151
153
  def mkdir_p(path)
152
154
  parts = path.split(/[\\\/]/)
153
- (0..parts.size).each do |i|
155
+ (0..parts.size-1).each do |i|
154
156
  subpath = File.join(*parts[0, i + 1]).encode(__ENCODING__)
155
157
  unless File.exists?(subpath)
156
158
  FileUtils.mkdir(subpath)
157
- unless @cache[:directories].include?(subpath)
158
- @cache[:directories][subpath] = true
159
- end
159
+ @cache[:directories][subpath] = true
160
160
  end
161
161
  end
162
162
  end
@@ -179,7 +179,7 @@ module Rscons
179
179
  # Calculate and return a file's checksum
180
180
  # @param file [String] The file name.
181
181
  def calculate_checksum(file)
182
- @lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file, {mode: 'rb'})).encode(__ENCODING__) rescue ''
182
+ @lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file, mode: 'rb')).encode(__ENCODING__) rescue ''
183
183
  end
184
184
  end
185
185
  end
@@ -6,7 +6,7 @@ module Rscons
6
6
  # contains a collection of construction variables, options, builders, and
7
7
  # rules for building targets.
8
8
  class Environment
9
- # [Hash] of {"builder_name" => builder_object} pairs.
9
+ # Hash of +{"builder_name" => builder_object}+ pairs.
10
10
  attr_reader :builders
11
11
 
12
12
  # Create an Environment object.
@@ -22,7 +22,7 @@ module Rscons
22
22
  @targets = {}
23
23
  @builders = {}
24
24
  @build_dirs = []
25
- @tweakers = []
25
+ @build_hooks = []
26
26
  @varset[:exclude_builders] ||= []
27
27
  unless @varset[:exclude_builders] == :all
28
28
  exclude_builders = Set.new(@varset[:exclude_builders] || [])
@@ -32,10 +32,7 @@ module Rscons
32
32
  end
33
33
  end
34
34
  end
35
- (@varset[:builders] || []).each do |builder|
36
- add_builder(builder)
37
- end
38
- @varset[:echo] ||= :command
35
+ @varset[:echo] ||= :short
39
36
 
40
37
  if block_given?
41
38
  yield self
@@ -46,7 +43,7 @@ module Rscons
46
43
  # Make a copy of the Environment object.
47
44
  # The cloned environment will contain a copy of all environment options,
48
45
  # construction variables, builders, and build directories. It will not
49
- # contain a copy of the targets or tweakers.
46
+ # contain a copy of the targets or build hooks.
50
47
  # If a block is given, the Environment object is yielded to the block and
51
48
  # when the block returns, the {#process} method is automatically called.
52
49
  def clone(variables = {})
@@ -75,9 +72,9 @@ module Rscons
75
72
  end
76
73
  end
77
74
 
78
- # Add a tweaker block to the Environment.
79
- def add_tweaker(&block)
80
- @tweakers << block
75
+ # Add a build hook to the Environment.
76
+ def add_build_hook(&block)
77
+ @build_hooks << block
81
78
  end
82
79
 
83
80
  # Specify a build directory for this Environment.
@@ -89,8 +86,6 @@ module Rscons
89
86
 
90
87
  # Return the file name to be built from source_fname with suffix suffix.
91
88
  # This method takes into account the Environment's build directories.
92
- # It also creates any parent directories needed to be able to open and
93
- # write to the output file.
94
89
  def get_build_fname(source_fname, suffix)
95
90
  build_fname = source_fname.set_suffix(suffix).gsub('\\', '/')
96
91
  @build_dirs.each do |src_dir, obj_dir|
@@ -122,41 +117,33 @@ module Rscons
122
117
  @varset.send(:append, *args)
123
118
  end
124
119
 
125
- # Return a list of target file names
126
- def targets
127
- @targets.keys
128
- end
129
-
130
- # Return a list of sources needed to build target target.
131
- def target_sources(target)
132
- @targets[target][:source] rescue nil
133
- end
134
-
135
120
  # Build all target specified in the Environment.
136
121
  # When a block is passed to Environment.new, this method is automatically
137
122
  # called after the block returns.
138
123
  def process
139
124
  cache = Cache.new
140
- targets_processed = Set.new
125
+ targets_processed = {}
141
126
  process_target = proc do |target|
142
- if @targets[target][:source].map do |src|
143
- targets_processed.include?(src) or not @targets.include?(src) or process_target.call(src)
144
- end.all?
145
- run_builder(@targets[target][:builder],
146
- target,
147
- @targets[target][:source],
148
- cache,
149
- @targets[target][:vars] || {})
150
- else
151
- false
127
+ targets_processed[target] ||= begin
128
+ @targets[target][:source].each do |src|
129
+ if @targets.include?(src) and not targets_processed.include?(src)
130
+ process_target.call(src)
131
+ end
132
+ end
133
+ result = run_builder(@targets[target][:builder],
134
+ target,
135
+ @targets[target][:source],
136
+ cache,
137
+ @targets[target][:vars] || {})
138
+ unless result
139
+ cache.write
140
+ raise BuildError.new("Failed to build #{target}")
141
+ end
142
+ result
152
143
  end
153
144
  end
154
145
  @targets.each do |target, info|
155
- next if targets_processed.include?(target)
156
- unless process_target.call(target)
157
- cache.write
158
- raise BuildError.new("Failed to build #{target}")
159
- end
146
+ process_target.call(target)
160
147
  end
161
148
  cache.write
162
149
  end
@@ -177,7 +164,7 @@ module Rscons
177
164
  # @param short_desc [String] Message to print if the Environment's :echo
178
165
  # mode is set to :short
179
166
  # @param command [Array] The command to execute.
180
- # @param options [Hash] Optional options to pass to {Kernel#system}.
167
+ # @param options [Hash] Optional options to pass to Kernel#system.
181
168
  def execute(short_desc, command, options = {})
182
169
  print_command = proc do
183
170
  puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
@@ -214,30 +201,6 @@ module Rscons
214
201
  end
215
202
  end
216
203
 
217
- # Parse dependencies for a given target from a Makefile.
218
- # This method is used internally by RScons builders.
219
- # @param mf_fname [String] File name of the Makefile to read.
220
- # @param target [String] Name of the target to gather dependencies for.
221
- def parse_makefile_deps(mf_fname, target)
222
- deps = []
223
- buildup = ''
224
- File.read(mf_fname).each_line do |line|
225
- if line =~ /^(.*)\\\s*$/
226
- buildup += ' ' + $1
227
- else
228
- buildup += ' ' + line
229
- if buildup =~ /^(.*): (.*)$/
230
- mf_target, mf_deps = $1.strip, $2
231
- if mf_target == target
232
- deps += mf_deps.split(' ').map(&:strip)
233
- end
234
- end
235
- buildup = ''
236
- end
237
- end
238
- deps
239
- end
240
-
241
204
  # Build a list of source files into files containing one of the suffixes
242
205
  # given by suffixes.
243
206
  # This method is used internally by RScons builders.
@@ -275,16 +238,40 @@ module Rscons
275
238
  # Return the result of the builder's run() method.
276
239
  def run_builder(builder, target, sources, cache, vars)
277
240
  vars = @varset.merge(vars)
278
- @tweakers.each do |tweaker_block|
241
+ @build_hooks.each do |build_hook_block|
279
242
  build_operation = {
280
243
  builder: builder,
281
244
  target: target,
282
245
  sources: sources,
283
246
  vars: vars,
284
247
  }
285
- tweaker_block.call(build_operation)
248
+ build_hook_block.call(build_operation)
286
249
  end
287
250
  builder.run(target, sources, cache, self, vars)
288
251
  end
252
+
253
+ # Parse dependencies for a given target from a Makefile.
254
+ # This method is used internally by RScons builders.
255
+ # @param mf_fname [String] File name of the Makefile to read.
256
+ # @param target [String] Name of the target to gather dependencies for.
257
+ def self.parse_makefile_deps(mf_fname, target)
258
+ deps = []
259
+ buildup = ''
260
+ File.read(mf_fname).each_line do |line|
261
+ if line =~ /^(.*)\\\s*$/
262
+ buildup += ' ' + $1
263
+ else
264
+ buildup += ' ' + line
265
+ if buildup =~ /^(.*): (.*)$/
266
+ mf_target, mf_deps = $1.strip, $2
267
+ if mf_target == target
268
+ deps += mf_deps.split(' ').map(&:strip)
269
+ end
270
+ end
271
+ buildup = ''
272
+ end
273
+ end
274
+ deps
275
+ end
289
276
  end
290
277
  end