rscons 1.4.3 → 1.5.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.
Files changed (48) hide show
  1. data/lib/rscons.rb +75 -5
  2. data/lib/rscons/build_target.rb +36 -0
  3. data/lib/rscons/builder.rb +41 -3
  4. data/lib/rscons/builders/cfile.rb +15 -0
  5. data/lib/rscons/builders/disassemble.rb +15 -0
  6. data/lib/rscons/builders/library.rb +17 -2
  7. data/lib/rscons/builders/object.rb +37 -5
  8. data/lib/rscons/builders/preprocess.rb +15 -0
  9. data/lib/rscons/builders/program.rb +42 -2
  10. data/lib/rscons/cache.rb +26 -6
  11. data/lib/rscons/environment.rb +259 -19
  12. data/lib/rscons/varset.rb +33 -10
  13. data/lib/rscons/version.rb +1 -1
  14. data/rscons.gemspec +8 -10
  15. metadata +38 -103
  16. checksums.yaml +0 -15
  17. data/.gitignore +0 -18
  18. data/.rspec +0 -2
  19. data/Gemfile +0 -4
  20. data/README.md +0 -384
  21. data/Rakefile.rb +0 -26
  22. data/build_tests/build_dir/src/one/one.c +0 -6
  23. data/build_tests/build_dir/src/two/two.c +0 -7
  24. data/build_tests/build_dir/src/two/two.h +0 -6
  25. data/build_tests/clone_env/src/program.c +0 -6
  26. data/build_tests/custom_builder/program.c +0 -7
  27. data/build_tests/d/main.d +0 -6
  28. data/build_tests/header/header.c +0 -7
  29. data/build_tests/header/header.h +0 -6
  30. data/build_tests/library/one.c +0 -8
  31. data/build_tests/library/three.c +0 -0
  32. data/build_tests/library/two.c +0 -0
  33. data/build_tests/simple/simple.c +0 -6
  34. data/build_tests/simple_cc/simple.cc +0 -8
  35. data/build_tests/two_sources/one.c +0 -8
  36. data/build_tests/two_sources/two.c +0 -3
  37. data/spec/build_tests_spec.rb +0 -527
  38. data/spec/rscons/builders/cfile_spec.rb +0 -28
  39. data/spec/rscons/builders/disassemble_spec.rb +0 -17
  40. data/spec/rscons/builders/library_spec.rb +0 -18
  41. data/spec/rscons/builders/object_spec.rb +0 -23
  42. data/spec/rscons/builders/preprocess_spec.rb +0 -18
  43. data/spec/rscons/builders/program_spec.rb +0 -18
  44. data/spec/rscons/cache_spec.rb +0 -271
  45. data/spec/rscons/environment_spec.rb +0 -361
  46. data/spec/rscons/varset_spec.rb +0 -163
  47. data/spec/rscons_spec.rb +0 -26
  48. data/spec/spec_helper.rb +0 -7
@@ -1,7 +0,0 @@
1
- #include <stdio.h>
2
- #include "inc.h"
3
-
4
- int main(int argc, char *argv[])
5
- {
6
- printf("The value is %d\n", THE_VALUE);
7
- }
@@ -1,6 +0,0 @@
1
- import std.stdio;
2
-
3
- void main()
4
- {
5
- writeln("Hello from D!");
6
- }
@@ -1,7 +0,0 @@
1
- #include <stdio.h>
2
- #include "header.h"
3
-
4
- int main(int argc, char *argv[])
5
- {
6
- printf("The value is %d\n", VALUE);
7
- }
@@ -1,6 +0,0 @@
1
- #ifndef HEADER_H
2
- #define HEADER_H
3
-
4
- #define VALUE 2
5
-
6
- #endif
@@ -1,8 +0,0 @@
1
- #include <stdio.h>
2
-
3
- #ifdef make_lib
4
- int main(int argc, char *argv[])
5
- {
6
- printf("Library\n");
7
- }
8
- #endif
File without changes
File without changes
@@ -1,6 +0,0 @@
1
- #include <stdio.h>
2
-
3
- int main(int argc, char *argv[])
4
- {
5
- printf("This is a simple C program\n");
6
- }
@@ -1,8 +0,0 @@
1
- #include <iostream>
2
-
3
- using namespace std;
4
-
5
- int main(int argc, char *argv[])
6
- {
7
- cout << "This is a simple C++ program" << endl;
8
- }
@@ -1,8 +0,0 @@
1
- #include <stdio.h>
2
-
3
- #ifdef ONE
4
- int main(int argc, char *argv[])
5
- {
6
- printf("This is a C program with two sources.\n");
7
- }
8
- #endif
@@ -1,3 +0,0 @@
1
- #ifdef ONE
2
- #error ONE should not be defined
3
- #endif
@@ -1,527 +0,0 @@
1
- require 'fileutils'
2
-
3
- class Dir
4
- class << self
5
- alias_method :orig_bracket, :[]
6
- end
7
- def self.[](*args)
8
- orig_bracket(*args).sort
9
- end
10
- end
11
-
12
- describe Rscons do
13
- BUILD_TEST_RUN_DIR = "build_test_run"
14
-
15
- before(:all) do
16
- FileUtils.rm_rf(BUILD_TEST_RUN_DIR)
17
- @owd = Dir.pwd
18
- end
19
-
20
- before(:each) do
21
- @output = ""
22
- $stdout.stub(:write) do |content|
23
- @output += content
24
- end
25
- $stderr.stub(:write) do |content|
26
- @output += content
27
- end
28
- end
29
-
30
- after(:each) do
31
- Dir.chdir(@owd)
32
- FileUtils.rm_rf(BUILD_TEST_RUN_DIR)
33
- end
34
-
35
- def test_dir(build_test_directory)
36
- FileUtils.cp_r("build_tests/#{build_test_directory}", BUILD_TEST_RUN_DIR)
37
- Dir.chdir(BUILD_TEST_RUN_DIR)
38
- end
39
-
40
- def file_sub(fname)
41
- contents = File.read(fname)
42
- replaced = ''
43
- contents.each_line do |line|
44
- replaced += yield(line)
45
- end
46
- File.open(fname, 'w') do |fh|
47
- fh.write(replaced)
48
- end
49
- end
50
-
51
- def lines
52
- @output.lines.map(&:rstrip).tap do |v|
53
- @output = ""
54
- end
55
- end
56
-
57
- ###########################################################################
58
- # Tests
59
- ###########################################################################
60
-
61
- it 'builds a C program with one source file' do
62
- test_dir('simple')
63
- Rscons::Environment.new do |env|
64
- env.Program('simple', Dir['*.c'])
65
- end
66
- File.exists?('simple.o').should be_true
67
- `./simple`.should == "This is a simple C program\n"
68
- end
69
-
70
- it 'prints commands as they are executed' do
71
- test_dir('simple')
72
- Rscons::Environment.new(echo: :command) do |env|
73
- env["LD"] = "gcc"
74
- env.Program('simple', Dir['*.c'])
75
- end
76
- lines.should == [
77
- 'gcc -c -o simple.o -MMD -MF simple.mf simple.c',
78
- 'gcc -o simple simple.o',
79
- ]
80
- end
81
-
82
- it 'prints short representations of the commands being executed' do
83
- test_dir('header')
84
- Rscons::Environment.new do |env|
85
- env.Program('header', Dir['*.c'])
86
- end
87
- lines.should == [
88
- 'CC header.o',
89
- 'LD header',
90
- ]
91
- end
92
-
93
- it 'builds a C program with one source file and one header file' do
94
- test_dir('header')
95
- Rscons::Environment.new do |env|
96
- env.Program('header', Dir['*.c'])
97
- end
98
- File.exists?('header.o').should be_true
99
- `./header`.should == "The value is 2\n"
100
- end
101
-
102
- it 'rebuilds a C module when a header it depends on changes' do
103
- test_dir('header')
104
- env = Rscons::Environment.new do |env|
105
- env.Program('header', Dir['*.c'])
106
- end
107
- `./header`.should == "The value is 2\n"
108
- file_sub('header.h') {|line| line.sub(/2/, '5')}
109
- env.process
110
- `./header`.should == "The value is 5\n"
111
- end
112
-
113
- it 'does not rebuild a C module when its dependencies have not changed' do
114
- test_dir('header')
115
- env = Rscons::Environment.new do |env|
116
- env.Program('header', Dir['*.c'])
117
- end
118
- `./header`.should == "The value is 2\n"
119
- lines.should == [
120
- 'CC header.o',
121
- 'LD header',
122
- ]
123
- env.process
124
- lines.should == []
125
- end
126
-
127
- it "does not rebuild a C module when only the file's timestampe has changed" do
128
- test_dir('header')
129
- env = Rscons::Environment.new do |env|
130
- env.Program('header', Dir['*.c'])
131
- end
132
- `./header`.should == "The value is 2\n"
133
- lines.should == [
134
- 'CC header.o',
135
- 'LD header',
136
- ]
137
- file_sub('header.c') {|line| line}
138
- env.process
139
- lines.should == []
140
- end
141
-
142
- it 're-links a program when the link flags have changed' do
143
- test_dir('simple')
144
- Rscons::Environment.new(echo: :command) do |env|
145
- env.Program('simple', Dir['*.c'])
146
- end
147
- lines.should == [
148
- 'gcc -c -o simple.o -MMD -MF simple.mf simple.c',
149
- 'gcc -o simple simple.o',
150
- ]
151
- Rscons::Environment.new(echo: :command) do |env|
152
- env["LIBS"] += ["c"]
153
- env.Program('simple', Dir['*.c'])
154
- end
155
- lines.should == ['gcc -o simple simple.o -lc']
156
- end
157
-
158
- it 'builds object files in a different build directory' do
159
- test_dir('build_dir')
160
- Rscons::Environment.new do |env|
161
- env.append('CPPPATH' => Dir['src/**/*/'])
162
- env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
163
- env.Program('build_dir', Dir['src/**/*.c'])
164
- end
165
- `./build_dir`.should == "Hello from two()\n"
166
- File.exists?('build_one/one.o').should be_true
167
- File.exists?('build_two/two.o').should be_true
168
- end
169
-
170
- it 'uses build directories before build root' do
171
- test_dir('build_dir')
172
- Rscons::Environment.new do |env|
173
- env.append('CPPPATH' => Dir['src/**/*/'])
174
- env.build_dir("src", "build")
175
- env.build_root = "build_root"
176
- env.Program('build_dir', Dir['src/**/*.c'])
177
- end
178
- lines.should == ["CC build/one/one.o", "CC build/two/two.o", "LD build_dir"]
179
- end
180
-
181
- it 'uses build_root if no build directories match' do
182
- test_dir('build_dir')
183
- Rscons::Environment.new do |env|
184
- env.append('CPPPATH' => Dir['src/**/*/'])
185
- env.build_dir("src2", "build")
186
- env.build_root = "build_root"
187
- env.Program('build_dir', Dir['src/**/*.c'])
188
- end
189
- lines.should == ["CC build_root/src/one/one.o", "CC build_root/src/two/two.o", "LD build_dir"]
190
- end
191
-
192
- it "expands target and source paths starting with ^/ to be relative to the build root" do
193
- test_dir('build_dir')
194
- Rscons::Environment.new(echo: :command) do |env|
195
- env.append('CPPPATH' => Dir['src/**/*/'])
196
- env.build_root = "build_root"
197
- FileUtils.mkdir_p(env.build_root)
198
- FileUtils.mv("src/one/one.c", "build_root")
199
- env.Object("^/one.o", "^/one.c")
200
- env.Program('build_dir', Dir['src/**/*.c'] + ["^/one.o"])
201
- end
202
- lines.should == [
203
- %q{gcc -c -o build_root/one.o -MMD -MF build_root/one.mf -Isrc/one/ -Isrc/two/ build_root/one.c},
204
- %q{gcc -c -o build_root/src/two/two.o -MMD -MF build_root/src/two/two.mf -Isrc/one/ -Isrc/two/ src/two/two.c},
205
- %q{gcc -o build_dir build_root/src/two/two.o build_root/one.o},
206
- ]
207
- end
208
-
209
- it 'cleans built files' do
210
- test_dir('build_dir')
211
- Rscons::Environment.new do |env|
212
- env.append('CPPPATH' => Dir['src/**/*/'])
213
- env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
214
- env.Program('build_dir', Dir['src/**/*.c'])
215
- end
216
- `./build_dir`.should == "Hello from two()\n"
217
- File.exists?('build_one/one.o').should be_true
218
- File.exists?('build_two/two.o').should be_true
219
- Rscons.clean
220
- File.exists?('build_one/one.o').should be_false
221
- File.exists?('build_two/two.o').should be_false
222
- File.exists?('build_one').should be_false
223
- File.exists?('build_two').should be_false
224
- File.exists?('src/one/one.c').should be_true
225
- end
226
-
227
- it 'does not clean created directories if other non-rscons-generated files reside there' do
228
- test_dir('build_dir')
229
- Rscons::Environment.new do |env|
230
- env.append('CPPPATH' => Dir['src/**/*/'])
231
- env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
232
- env.Program('build_dir', Dir['src/**/*.c'])
233
- end
234
- `./build_dir`.should == "Hello from two()\n"
235
- File.exists?('build_one/one.o').should be_true
236
- File.exists?('build_two/two.o').should be_true
237
- File.open('build_two/tmp', 'w') { |fh| fh.puts "dum" }
238
- Rscons.clean
239
- File.exists?('build_one/one.o').should be_false
240
- File.exists?('build_two/two.o').should be_false
241
- File.exists?('build_one').should be_false
242
- File.exists?('build_two').should be_true
243
- File.exists?('src/one/one.c').should be_true
244
- end
245
-
246
- it 'allows Ruby classes as custom builders to be used to construct files' do
247
- test_dir('custom_builder')
248
- class MySource < Rscons::Builder
249
- def run(target, sources, cache, env, vars)
250
- File.open(target, 'w') do |fh|
251
- fh.puts <<EOF
252
- #define THE_VALUE 5678
253
- EOF
254
- end
255
- target
256
- end
257
- end
258
-
259
- Rscons::Environment.new do |env|
260
- env.add_builder(MySource.new)
261
- env.MySource('inc.h', [])
262
- env.Program('program', Dir['*.c'])
263
- end
264
-
265
- lines.should == ['CC program.o', 'LD program']
266
- File.exists?('inc.h').should be_true
267
- `./program`.should == "The value is 5678\n"
268
- end
269
-
270
- it 'supports custom builders with multiple targets' do
271
- test_dir('custom_builder')
272
- class CHGen < Rscons::Builder
273
- def run(target, sources, cache, env, vars)
274
- c_fname = target
275
- h_fname = target.sub(/\.c$/, ".h")
276
- unless cache.up_to_date?([c_fname, h_fname], "", sources, env)
277
- puts "CHGen #{c_fname}"
278
- File.open(c_fname, "w") {|fh| fh.puts "int THE_VALUE = 42;"}
279
- File.open(h_fname, "w") {|fh| fh.puts "extern int THE_VALUE;"}
280
- cache.register_build([c_fname, h_fname], "", sources, env)
281
- end
282
- target
283
- end
284
- end
285
-
286
- env = Rscons::Environment.new do |env|
287
- env.add_builder(CHGen.new)
288
- env.CHGen("inc.c", ["program.c"])
289
- env.Program("program", Dir["*.c"] + ["inc.c"])
290
- end
291
-
292
- lines.should == ["CHGen inc.c", "CC program.o", "CC inc.o", "LD program"]
293
- File.exists?("inc.c").should be_true
294
- File.exists?("inc.h").should be_true
295
- `./program`.should == "The value is 42\n"
296
-
297
- File.open("inc.c", "w") {|fh| fh.puts "int THE_VALUE = 33;"}
298
- env.process
299
- lines.should == ["CHGen inc.c"]
300
- `./program`.should == "The value is 42\n"
301
- end
302
-
303
- it 'allows cloning Environment objects' do
304
- test_dir('clone_env')
305
-
306
- debug = Rscons::Environment.new(echo: :command) do |env|
307
- env.build_dir('src', 'debug')
308
- env['CFLAGS'] = '-O2'
309
- env['CPPFLAGS'] = '-DSTRING="Debug Version"'
310
- env.Program('program-debug', Dir['src/*.c'])
311
- end
312
-
313
- release = debug.clone do |env|
314
- env["CPPFLAGS"] = '-DSTRING="Release Version"'
315
- env.build_dir('src', 'release')
316
- env.Program('program-release', Dir['src/*.c'])
317
- end
318
-
319
- lines.should == [
320
- %q{gcc -c -o debug/program.o -MMD -MF debug/program.mf '-DSTRING="Debug Version"' -O2 src/program.c},
321
- %q{gcc -o program-debug debug/program.o},
322
- %q{gcc -c -o release/program.o -MMD -MF release/program.mf '-DSTRING="Release Version"' -O2 src/program.c},
323
- %q{gcc -o program-release release/program.o},
324
- ]
325
- end
326
-
327
- it 'allows cloning all attributes of an Environment object' do
328
- test_dir('clone_env')
329
-
330
- env1 = Rscons::Environment.new(echo: :command) do |env|
331
- env.build_dir('src', 'build')
332
- env['CFLAGS'] = '-O2'
333
- env.add_build_hook do |build_op|
334
- build_op[:vars]['CPPFLAGS'] = '-DSTRING="Hello"'
335
- end
336
- env.Program('program', Dir['src/*.c'])
337
- end
338
-
339
- env2 = env1.clone(clone: :all) do |env|
340
- env.Program('program2', Dir['src/*.c'])
341
- end
342
-
343
- lines.should == [
344
- %q{gcc -c -o build/program.o -MMD -MF build/program.mf -DSTRING="Hello" -O2 src/program.c},
345
- %q{gcc -o program build/program.o},
346
- %q{gcc -o program2 build/program.o},
347
- ]
348
- end
349
-
350
- it 'builds a C++ program with one source file' do
351
- test_dir('simple_cc')
352
- Rscons::Environment.new do |env|
353
- env.Program('simple', Dir['*.cc'])
354
- end
355
- File.exists?('simple.o').should be_true
356
- `./simple`.should == "This is a simple C++ program\n"
357
- end
358
-
359
- it 'allows overriding construction variables for individual builder calls' do
360
- test_dir('two_sources')
361
- Rscons::Environment.new(echo: :command) do |env|
362
- env.Object("one.o", "one.c", 'CPPFLAGS' => ['-DONE'])
363
- env.Program('two_sources', ['one.o', 'two.c'])
364
- end
365
- lines.should == [
366
- 'gcc -c -o one.o -MMD -MF one.mf -DONE one.c',
367
- 'gcc -c -o two.o -MMD -MF two.mf two.c',
368
- 'gcc -o two_sources one.o two.o',
369
- ]
370
- File.exists?('two_sources').should be_true
371
- `./two_sources`.should == "This is a C program with two sources.\n"
372
- end
373
-
374
- it 'builds a static library archive' do
375
- test_dir('library')
376
- Rscons::Environment.new(echo: :command) do |env|
377
- env.Program('library', ['lib.a', 'three.c'])
378
- env.Library("lib.a", ['one.c', 'two.c'], 'CPPFLAGS' => ['-Dmake_lib'])
379
- end
380
- lines.should == [
381
- 'gcc -c -o one.o -MMD -MF one.mf -Dmake_lib one.c',
382
- 'gcc -c -o two.o -MMD -MF two.mf -Dmake_lib two.c',
383
- 'ar rcs lib.a one.o two.o',
384
- 'gcc -c -o three.o -MMD -MF three.mf three.c',
385
- 'gcc -o library lib.a three.o',
386
- ]
387
- File.exists?('library').should be_true
388
- `ar t lib.a`.should == "one.o\ntwo.o\n"
389
- end
390
-
391
- it 'supports build hooks to override construction variables' do
392
- test_dir("build_dir")
393
- Rscons::Environment.new(echo: :command) do |env|
394
- env.append('CPPPATH' => Dir['src/**/*/'])
395
- env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
396
- env.add_build_hook do |build_op|
397
- if build_op[:target] =~ %r{build_one/.*\.o}
398
- build_op[:vars]["CFLAGS"] << "-O1"
399
- elsif build_op[:target] =~ %r{build_two/.*\.o}
400
- build_op[:vars]["CFLAGS"] << "-O2"
401
- end
402
- end
403
- env.Program('build_hook', Dir['src/**/*.c'])
404
- end
405
- `./build_hook`.should == "Hello from two()\n"
406
- lines.should =~ [
407
- 'gcc -c -o build_one/one.o -MMD -MF build_one/one.mf -Isrc/one/ -Isrc/two/ -O1 src/one/one.c',
408
- 'gcc -c -o build_two/two.o -MMD -MF build_two/two.mf -Isrc/one/ -Isrc/two/ -O2 src/two/two.c',
409
- 'gcc -o build_hook build_one/one.o build_two/two.o',
410
- ]
411
- end
412
-
413
- it 'rebuilds when user-specified dependencies change' do
414
- test_dir('simple')
415
- Rscons::Environment.new do |env|
416
- env.Program('simple', Dir['*.c'])
417
- File.open("file.ld", "w") do |fh|
418
- fh.puts("foo")
419
- end
420
- env.depends('simple', 'file.ld')
421
- end
422
- lines.should == ["CC simple.o", "LD simple"]
423
- File.exists?('simple.o').should be_true
424
- `./simple`.should == "This is a simple C program\n"
425
- Rscons::Environment.new do |env|
426
- env.Program('simple', Dir['*.c'])
427
- File.open("file.ld", "w") do |fh|
428
- fh.puts("bar")
429
- end
430
- env.depends('simple', 'file.ld')
431
- end
432
- lines.should == ["LD simple"]
433
- Rscons::Environment.new do |env|
434
- env.Program('simple', Dir['*.c'])
435
- File.unlink("file.ld")
436
- end
437
- lines.should == ["LD simple"]
438
- Rscons::Environment.new do |env|
439
- env.Program('simple', Dir['*.c'])
440
- end
441
- lines.should == []
442
- end
443
-
444
- unless ENV["omit_gdc_tests"]
445
- it "supports building D sources" do
446
- test_dir("d")
447
- Rscons::Environment.new(echo: :command) do |env|
448
- env.Program("hello-d", Dir["*.d"])
449
- end
450
- lines.should == [
451
- "gdc -c -o main.o main.d",
452
- "gdc -o hello-d main.o",
453
- ]
454
- `./hello-d`.rstrip.should == "Hello from D!"
455
- end
456
- end
457
-
458
- it "supports disassembling object files" do
459
- test_dir("simple")
460
- Rscons::Environment.new do |env|
461
- env.Object("simple.o", "simple.c")
462
- env.Disassemble("simple.txt", "simple.o")
463
- end
464
- File.exists?("simple.txt").should be_true
465
- File.read("simple.txt").should =~ /Disassembly of section .text:/
466
- end
467
-
468
- it "supports preprocessing C sources" do
469
- test_dir("simple")
470
- Rscons::Environment.new do |env|
471
- env.Preprocess("simplepp.c", "simple.c")
472
- env.Program("simple", "simplepp.c")
473
- end
474
- File.read("simplepp.c").should =~ /# \d+ "simple.c"/
475
- `./simple`.should == "This is a simple C program\n"
476
- end
477
-
478
- it "supports preprocessing C++ sources" do
479
- test_dir("simple_cc")
480
- Rscons::Environment.new do |env|
481
- env.Preprocess("simplepp.cc", "simple.cc")
482
- env.Program("simple", "simplepp.cc")
483
- end
484
- File.read("simplepp.cc").should =~ /# \d+ "simple.cc"/
485
- `./simple`.should == "This is a simple C++ program\n"
486
- end
487
-
488
- it "supports invoking builders with no sources and a build_root defined" do
489
- class TestBuilder < Rscons::Builder
490
- def run(target, sources, cache, env, vars)
491
- target
492
- end
493
- end
494
- test_dir("simple")
495
- Rscons::Environment.new do |env|
496
- env.build_root = "build"
497
- env.add_builder(TestBuilder.new)
498
- env.TestBuilder("file")
499
- end
500
- end
501
-
502
- it "expands construction variables in builder target and sources before invoking the builder" do
503
- test_dir('custom_builder')
504
- class MySource < Rscons::Builder
505
- def run(target, sources, cache, env, vars)
506
- File.open(target, 'w') do |fh|
507
- fh.puts <<EOF
508
- #define THE_VALUE 678
509
- EOF
510
- end
511
- target
512
- end
513
- end
514
-
515
- Rscons::Environment.new do |env|
516
- env["hdr"] = "inc.h"
517
- env["src"] = "program.c"
518
- env.add_builder(MySource.new)
519
- env.MySource('${hdr}')
520
- env.Program('program', "${src}")
521
- end
522
-
523
- lines.should == ['CC program.o', 'LD program']
524
- File.exists?('inc.h').should be_true
525
- `./program`.should == "The value is 678\n"
526
- end
527
- end