spec/build_tests_spec.rb in rscons-0.0.14 vs spec/build_tests_spec.rb in rscons-0.1.0
- old
+ new
@@ -1,49 +1,35 @@
require 'fileutils'
describe Rscons do
+ BUILD_TEST_RUN_DIR = "build_test_run"
+
before(:all) do
- FileUtils.rm_rf('build_tests_run')
+ FileUtils.rm_rf(BUILD_TEST_RUN_DIR)
@owd = Dir.pwd
end
+ before(:each) do
+ @output = ""
+ $stdout.stub(:write) do |content|
+ @output += content
+ end
+ $stderr.stub(:write) do |content|
+ @output += content
+ end
+ end
+
after(:each) do
Dir.chdir(@owd)
- FileUtils.rm_rf('build_tests_run')
+ FileUtils.rm_rf(BUILD_TEST_RUN_DIR)
end
- def build_testdir(build_script = "build.rb")
- if File.exists?(build_script)
- build_rb = File.read(build_script)
- File.open(build_script, "w") do |fh|
- fh.puts(<<EOF + build_rb)
-require "simplecov"
-
-SimpleCov.start do
- root("#{@owd}")
- command_name("build_test_#{@build_test_name}")
- add_filter("spec")
-end
-
-require "rscons"
-EOF
- end
- IO.popen(%{ruby -I #{@owd}/lib #{build_script}}) do |io|
- io.readlines.reject do |line|
- line =~ /^Coverage report/
- end
- end.map(&:strip)
- end
+ def test_dir(build_test_directory)
+ FileUtils.cp_r("build_tests/#{build_test_directory}", BUILD_TEST_RUN_DIR)
+ Dir.chdir(BUILD_TEST_RUN_DIR)
end
- def test_dir(build_test_directory, build_script = "build.rb")
- @build_test_name = build_test_directory
- FileUtils.cp_r("build_tests/#{build_test_directory}", 'build_tests_run')
- Dir.chdir("build_tests_run")
- build_testdir(build_script)
- end
-
def file_sub(fname)
contents = File.read(fname)
replaced = ''
contents.each_line do |line|
replaced += yield(line)
@@ -51,93 +37,136 @@
File.open(fname, 'w') do |fh|
fh.write(replaced)
end
end
+ def lines
+ @output.lines.map(&:rstrip).tap do |v|
+ @output = ""
+ end
+ end
+
###########################################################################
# Tests
###########################################################################
it 'builds a C program with one source file' do
test_dir('simple')
+ Rscons::Environment.new do |env|
+ env.Program('simple', Dir['*.c'])
+ end
File.exists?('simple.o').should be_true
`./simple`.should == "This is a simple C program\n"
end
it 'prints commands as they are executed' do
- lines = test_dir('simple')
+ test_dir('simple')
+ Rscons::Environment.new(echo: :command) do |env|
+ env["LD"] = "gcc"
+ env.Program('simple', Dir['*.c'])
+ end
lines.should == [
'gcc -c -o simple.o -MMD -MF simple.mf simple.c',
'gcc -o simple simple.o',
]
end
it 'prints short representations of the commands being executed' do
- lines = test_dir('header')
+ test_dir('header')
+ Rscons::Environment.new do |env|
+ env.Program('header', Dir['*.c'])
+ end
lines.should == [
'CC header.o',
'LD header',
]
end
it 'builds a C program with one source file and one header file' do
test_dir('header')
+ Rscons::Environment.new do |env|
+ env.Program('header', Dir['*.c'])
+ end
File.exists?('header.o').should be_true
`./header`.should == "The value is 2\n"
end
it 'rebuilds a C module when a header it depends on changes' do
test_dir('header')
+ env = Rscons::Environment.new do |env|
+ env.Program('header', Dir['*.c'])
+ end
`./header`.should == "The value is 2\n"
file_sub('header.h') {|line| line.sub(/2/, '5')}
- build_testdir
+ env.process
`./header`.should == "The value is 5\n"
end
it 'does not rebuild a C module when its dependencies have not changed' do
- lines = test_dir('header')
+ test_dir('header')
+ env = Rscons::Environment.new do |env|
+ env.Program('header', Dir['*.c'])
+ end
`./header`.should == "The value is 2\n"
lines.should == [
'CC header.o',
'LD header',
]
- lines = build_testdir
+ env.process
lines.should == []
end
it "does not rebuild a C module when only the file's timestampe has changed" do
- lines = test_dir('header')
+ test_dir('header')
+ env = Rscons::Environment.new do |env|
+ env.Program('header', Dir['*.c'])
+ end
`./header`.should == "The value is 2\n"
lines.should == [
'CC header.o',
'LD header',
]
file_sub('header.c') {|line| line}
- lines = build_testdir
+ env.process
lines.should == []
end
it 're-links a program when the link flags have changed' do
- lines = test_dir('simple')
+ test_dir('simple')
+ Rscons::Environment.new(echo: :command) do |env|
+ env.Program('simple', Dir['*.c'])
+ end
lines.should == [
'gcc -c -o simple.o -MMD -MF simple.mf simple.c',
'gcc -o simple simple.o',
]
- file_sub('build.rb') {|line| line.sub(/.*CHANGE.FLAGS.*/, ' env["LIBS"] += ["c"]')}
- lines = build_testdir
+ Rscons::Environment.new(echo: :command) do |env|
+ env["LIBS"] += ["c"]
+ env.Program('simple', Dir['*.c'])
+ end
lines.should == ['gcc -o simple simple.o -lc']
end
it 'builds object files in a different build directory' do
- lines = test_dir('build_dir')
+ test_dir('build_dir')
+ Rscons::Environment.new do |env|
+ env.append('CPPPATH' => Dir['src/**/*/'])
+ env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
+ env.Program('build_dir', Dir['src/**/*.c'])
+ end
`./build_dir`.should == "Hello from two()\n"
File.exists?('build_one/one.o').should be_true
File.exists?('build_two/two.o').should be_true
end
it 'cleans built files' do
- lines = test_dir('build_dir')
+ test_dir('build_dir')
+ Rscons::Environment.new do |env|
+ env.append('CPPPATH' => Dir['src/**/*/'])
+ env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
+ env.Program('build_dir', Dir['src/**/*.c'])
+ end
`./build_dir`.should == "Hello from two()\n"
File.exists?('build_one/one.o').should be_true
File.exists?('build_two/two.o').should be_true
Rscons.clean
File.exists?('build_one/one.o').should be_false
@@ -146,11 +175,16 @@
File.exists?('build_two').should be_false
File.exists?('src/one/one.c').should be_true
end
it 'does not clean created directories if other non-rscons-generated files reside there' do
- lines = test_dir('build_dir')
+ test_dir('build_dir')
+ Rscons::Environment.new do |env|
+ env.append('CPPPATH' => Dir['src/**/*/'])
+ env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
+ env.Program('build_dir', Dir['src/**/*.c'])
+ end
`./build_dir`.should == "Hello from two()\n"
File.exists?('build_one/one.o').should be_true
File.exists?('build_two/two.o').should be_true
File.open('build_two/tmp', 'w') { |fh| fh.puts "dum" }
Rscons.clean
@@ -160,45 +194,86 @@
File.exists?('build_two').should be_true
File.exists?('src/one/one.c').should be_true
end
it 'allows Ruby classes as custom builders to be used to construct files' do
- lines = test_dir('custom_builder')
+ test_dir('custom_builder')
+ class MySource < Rscons::Builder
+ def run(target, sources, cache, env, vars = {})
+ File.open(target, 'w') do |fh|
+ fh.puts <<EOF
+ #define THE_VALUE 5678
+EOF
+ end
+ target
+ end
+ end
+
+ Rscons::Environment.new do |env|
+ env.add_builder(MySource.new)
+ env.MySource('inc.h', [])
+ env.Program('program', Dir['*.c'])
+ end
+
lines.should == ['CC program.o', 'LD program']
File.exists?('inc.h').should be_true
`./program`.should == "The value is 5678\n"
end
it 'allows cloning Environment objects' do
- lines = test_dir('clone_env')
+ test_dir('clone_env')
+
+ debug = Rscons::Environment.new(echo: :command) do |env|
+ env.build_dir('src', 'debug')
+ env['CFLAGS'] = '-O2'
+ env['CPPFLAGS'] = '-DSTRING="Debug Version"'
+ env.Program('program-debug', Dir['src/*.c'])
+ end
+
+ release = debug.clone('CPPFLAGS' => '-DSTRING="Release Version"') do |env|
+ env.build_dir('src', 'release')
+ env.Program('program-release', Dir['src/*.c'])
+ end
+
lines.should == [
%q{gcc -c -o debug/program.o -MMD -MF debug/program.mf '-DSTRING="Debug Version"' -O2 src/program.c},
%q{gcc -o program-debug debug/program.o},
%q{gcc -c -o release/program.o -MMD -MF release/program.mf '-DSTRING="Release Version"' -O2 src/program.c},
%q{gcc -o program-release release/program.o},
]
end
it 'builds a C++ program with one source file' do
test_dir('simple_cc')
+ Rscons::Environment.new do |env|
+ env.Program('simple', Dir['*.cc'])
+ end
File.exists?('simple.o').should be_true
`./simple`.should == "This is a simple C++ program\n"
end
it 'allows overriding construction variables for individual builder calls' do
- lines = test_dir('two_sources')
+ test_dir('two_sources')
+ Rscons::Environment.new(echo: :command) do |env|
+ env.Object("one.o", "one.c", 'CPPFLAGS' => ['-DONE'])
+ env.Program('two_sources', ['one.o', 'two.c'])
+ end
lines.should == [
'gcc -c -o one.o -MMD -MF one.mf -DONE one.c',
'gcc -c -o two.o -MMD -MF two.mf two.c',
'gcc -o two_sources one.o two.o',
]
File.exists?('two_sources').should be_true
`./two_sources`.should == "This is a C program with two sources.\n"
end
it 'builds a static library archive' do
- lines = test_dir('library')
+ test_dir('library')
+ Rscons::Environment.new(echo: :command) do |env|
+ env.Program('library', ['lib.a', 'three.c'])
+ env.Library("lib.a", ['one.c', 'two.c'], 'CPPFLAGS' => ['-Dmake_lib'])
+ end
lines.should == [
'gcc -c -o one.o -MMD -MF one.mf -Dmake_lib one.c',
'gcc -c -o two.o -MMD -MF two.mf -Dmake_lib two.c',
'ar rcs lib.a one.o two.o',
'gcc -c -o three.o -MMD -MF three.mf three.c',
@@ -206,15 +281,41 @@
]
File.exists?('library').should be_true
`ar t lib.a`.should == "one.o\ntwo.o\n"
end
- it 'supports tweakers to override construction variables' do
- lines = test_dir("build_dir", "tweaker_build.rb")
- `./tweaker`.should == "Hello from two()\n"
+ it 'supports build hooks to override construction variables' do
+ test_dir("build_dir")
+ Rscons::Environment.new(echo: :command) do |env|
+ env.append('CPPPATH' => Dir['src/**/*/'])
+ env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
+ env.add_build_hook do |build_op|
+ if build_op[:target] =~ %r{build_one/.*\.o}
+ build_op[:vars]["CFLAGS"] << "-O1"
+ elsif build_op[:target] =~ %r{build_two/.*\.o}
+ build_op[:vars]["CFLAGS"] << "-O2"
+ end
+ end
+ env.Program('build_hook', Dir['src/**/*.c'])
+ end
+ `./build_hook`.should == "Hello from two()\n"
lines.should =~ [
'gcc -c -o build_one/one.o -MMD -MF build_one/one.mf -Isrc/one/ -Isrc/two/ -O1 src/one/one.c',
'gcc -c -o build_two/two.o -MMD -MF build_two/two.mf -Isrc/one/ -Isrc/two/ -O2 src/two/two.c',
- 'gcc -o tweaker build_one/one.o build_two/two.o',
+ 'gcc -o build_hook build_one/one.o build_two/two.o',
]
+ end
+
+ unless ENV["omit_gdc_tests"]
+ it "supports building D sources" do
+ test_dir("d")
+ Rscons::Environment.new(echo: :command) do |env|
+ env.Program("hello-d", Dir["*.d"])
+ end
+ lines.should == [
+ "gdc -c -o main.o main.d",
+ "gdc -o hello-d main.o",
+ ]
+ `./hello-d`.rstrip.should == "Hello from D!"
+ end
end
end