Compare commits
46 Commits
48d9273cc6
...
7055cad73c
Author | SHA1 | Date | |
---|---|---|---|
7055cad73c | |||
4548f4e3c9 | |||
19dbab3426 | |||
69f5bea2b2 | |||
2ee9dda49d | |||
f011b23499 | |||
80d52f25b8 | |||
0face546e3 | |||
ca747232cd | |||
a7b46093e9 | |||
09892eed63 | |||
117df43f64 | |||
acc12822b6 | |||
8c7b43f60c | |||
7c8becc3f9 | |||
d1a35501ef | |||
28a245f0ab | |||
87a6d9f04f | |||
556c821cc6 | |||
441fc9bc65 | |||
1861874f5c | |||
|
6d51c5cbde | ||
73af83803a | |||
353f4f45bc | |||
5bac91f92f | |||
bbe9563ceb | |||
5ec74604c6 | |||
8e06efe61e | |||
0756874ddb | |||
dded5e2648 | |||
fbe60f6ba2 | |||
8dd9799666 | |||
f2c755c8bb | |||
01ca86de8b | |||
943fabd0d1 | |||
d08e2f6b5c | |||
90365dd197 | |||
8d05516c40 | |||
db49d86866 | |||
e667455c32 | |||
e62332aba6 | |||
397639849d | |||
96d5caf2e5 | |||
f4b10a30af | |||
cf52c3fc6f | |||
5378afb6f8 |
42
CHANGELOG.md
42
CHANGELOG.md
@ -1,3 +1,45 @@
|
|||||||
|
## v2.3.0
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- #125 - Support subsidiary Rsconscript files
|
||||||
|
- #126 - Add PATH manipulation methods
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- #121 - env.depends() does not work with built-root-relative "^/" paths
|
||||||
|
- #130 - Document -f command line option
|
||||||
|
- #133 - Clarify failed command error message indicating to run -F
|
||||||
|
- #134 - Document CMD_STDOUT variable for Command builder
|
||||||
|
- #135 - Write dependency file to build directory when user invokes Object builder directly
|
||||||
|
- #141 - Document phony targets
|
||||||
|
|
||||||
|
## v2.2.0
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- #120 - improve support for MSYS2
|
||||||
|
- #119 - add failure messages for failed configuration checks
|
||||||
|
- #118 - compiler checks should support cross-compilers and freestanding compilers
|
||||||
|
|
||||||
|
## v2.1.0
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- #117 - ruby 2.7 compatibility
|
||||||
|
|
||||||
|
## v2.0.2
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- #113 - distinguish object files built from multiple sources with the same base name but different extensions
|
||||||
|
|
||||||
|
## v2.0.1
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- #112 - Install builder cannot replace a currently executing binary on Linux
|
||||||
|
|
||||||
## v2.0.0
|
## v2.0.0
|
||||||
|
|
||||||
- convert rscons from a Ruby gem to a standalone script
|
- convert rscons from a Ruby gem to a standalone script
|
||||||
|
14
DEVELOPING.md
Normal file
14
DEVELOPING.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Developing
|
||||||
|
|
||||||
|
# Specs
|
||||||
|
|
||||||
|
To run the rscons specs, the following commands must be available:
|
||||||
|
|
||||||
|
* gcc
|
||||||
|
* clang
|
||||||
|
* g++
|
||||||
|
* clang++
|
||||||
|
* gdc
|
||||||
|
* ldc
|
||||||
|
* flex
|
||||||
|
* bison
|
8
Gemfile
8
Gemfile
@ -1,10 +1,14 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem "json"
|
|
||||||
gem "rspec"
|
gem "rspec"
|
||||||
gem "rake"
|
gem "rake"
|
||||||
gem "simplecov"
|
gem "simplecov", "~> 0.15.0"
|
||||||
|
if RbConfig::CONFIG["host"]["msys"]
|
||||||
|
gem "json", "2.1.0"
|
||||||
|
else
|
||||||
|
gem "json"
|
||||||
gem "yard"
|
gem "yard"
|
||||||
gem "rdoc"
|
gem "rdoc"
|
||||||
gem "redcarpet"
|
gem "redcarpet"
|
||||||
gem "syntax"
|
gem "syntax"
|
||||||
|
end
|
||||||
|
42
Gemfile.lock
42
Gemfile.lock
@ -1,32 +1,32 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.4.4)
|
||||||
docile (1.3.2)
|
docile (1.1.5)
|
||||||
json (2.2.0)
|
json (2.5.1)
|
||||||
rake (12.3.2)
|
rake (13.0.6)
|
||||||
rdoc (6.1.1)
|
rdoc (6.3.2)
|
||||||
redcarpet (3.4.0)
|
redcarpet (3.5.1)
|
||||||
rspec (3.8.0)
|
rspec (3.10.0)
|
||||||
rspec-core (~> 3.8.0)
|
rspec-core (~> 3.10.0)
|
||||||
rspec-expectations (~> 3.8.0)
|
rspec-expectations (~> 3.10.0)
|
||||||
rspec-mocks (~> 3.8.0)
|
rspec-mocks (~> 3.10.0)
|
||||||
rspec-core (3.8.2)
|
rspec-core (3.10.1)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.10.0)
|
||||||
rspec-expectations (3.8.4)
|
rspec-expectations (3.10.1)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.10.0)
|
||||||
rspec-mocks (3.8.1)
|
rspec-mocks (3.10.2)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.10.0)
|
||||||
rspec-support (3.8.2)
|
rspec-support (3.10.2)
|
||||||
simplecov (0.15.0)
|
simplecov (0.15.1)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.2)
|
simplecov-html (0.10.2)
|
||||||
syntax (1.2.2)
|
syntax (1.2.2)
|
||||||
yard (0.9.20)
|
yard (0.9.26)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
@ -38,9 +38,9 @@ DEPENDENCIES
|
|||||||
rdoc
|
rdoc
|
||||||
redcarpet
|
redcarpet
|
||||||
rspec
|
rspec
|
||||||
simplecov
|
simplecov (~> 0.15.0)
|
||||||
syntax
|
syntax
|
||||||
yard
|
yard
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.17.3
|
2.1.4
|
||||||
|
22
Rakefile.rb
22
Rakefile.rb
@ -6,7 +6,6 @@ rescue Bundler::BundlerError => e
|
|||||||
end
|
end
|
||||||
|
|
||||||
require "rspec/core/rake_task"
|
require "rspec/core/rake_task"
|
||||||
require "yard"
|
|
||||||
require "rake/clean"
|
require "rake/clean"
|
||||||
require "fileutils"
|
require "fileutils"
|
||||||
|
|
||||||
@ -18,12 +17,16 @@ task :build_dist do
|
|||||||
end
|
end
|
||||||
|
|
||||||
RSpec::Core::RakeTask.new(:spec, :example_string) do |task, args|
|
RSpec::Core::RakeTask.new(:spec, :example_string) do |task, args|
|
||||||
|
ENV["specs"] = "1"
|
||||||
if args.example_string
|
if args.example_string
|
||||||
ENV["partial_specs"] = "1"
|
ENV["partial_specs"] = "1"
|
||||||
task.rspec_opts = %W[-e "#{args.example_string}" -f documentation]
|
task.rspec_opts = %W[-e "#{args.example_string}" -f documentation]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
task :spec => :build_dist
|
task :spec => :build_dist
|
||||||
|
task :spec do
|
||||||
|
ENV.delete("specs")
|
||||||
|
end
|
||||||
|
|
||||||
# dspec task is useful to test the distributable release script, but is not
|
# dspec task is useful to test the distributable release script, but is not
|
||||||
# useful for coverage information.
|
# useful for coverage information.
|
||||||
@ -32,16 +35,11 @@ task :dspec, [:example_string] => :build_dist do |task, args|
|
|||||||
FileUtils.mkdir_p("test")
|
FileUtils.mkdir_p("test")
|
||||||
FileUtils.cp("dist/rscons", "test/rscons.rb")
|
FileUtils.cp("dist/rscons", "test/rscons.rb")
|
||||||
ENV["dist_specs"] = "1"
|
ENV["dist_specs"] = "1"
|
||||||
Rake::Task["spec"].invoke(args.example_string)
|
Rake::Task["spec"].execute(args.example_string)
|
||||||
ENV.delete("dist_specs")
|
ENV.delete("dist_specs")
|
||||||
FileUtils.rm_f(Dir.glob(".rscons-*"))
|
FileUtils.rm_f(Dir.glob(".rscons-*"))
|
||||||
end
|
end
|
||||||
|
|
||||||
YARD::Rake::YardocTask.new do |yard|
|
|
||||||
yard.files = ['lib/**/*.rb']
|
|
||||||
yard.options = ["-ogen/yard"]
|
|
||||||
end
|
|
||||||
|
|
||||||
task :gen_large_project, [:size] => :build_dist do |task, args|
|
task :gen_large_project, [:size] => :build_dist do |task, args|
|
||||||
size = (args.size || 10000).to_i
|
size = (args.size || 10000).to_i
|
||||||
FileUtils.rm_rf("large_project")
|
FileUtils.rm_rf("large_project")
|
||||||
@ -88,15 +86,25 @@ EOF
|
|||||||
FileUtils.cp("dist/rscons", "large_project")
|
FileUtils.cp("dist/rscons", "large_project")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless RbConfig::CONFIG["host"]["msys"]
|
||||||
|
require "yard"
|
||||||
|
YARD::Rake::YardocTask.new do |yard|
|
||||||
|
yard.files = ['lib/**/*.rb']
|
||||||
|
yard.options = ["-ogen/yard"]
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Build user guide"
|
||||||
task :user_guide do
|
task :user_guide do
|
||||||
system("ruby", "-Ilib", "rb/gen_user_guide.rb")
|
system("ruby", "-Ilib", "rb/gen_user_guide.rb")
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
task :default => :spec
|
task :default => :spec
|
||||||
|
|
||||||
task :all => [
|
task :all => [
|
||||||
:build_dist,
|
:build_dist,
|
||||||
:spec,
|
:spec,
|
||||||
|
:dspec,
|
||||||
:yard,
|
:yard,
|
||||||
:user_guide,
|
:user_guide,
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
configure do
|
configure do
|
||||||
|
check_d_compiler
|
||||||
check_d_import "std.stdio", check_d_import_path: ["./usr1"]
|
check_d_import "std.stdio", check_d_import_path: ["./usr1"]
|
||||||
check_d_import "frobulous", check_d_import_path: ["./usr2"]
|
check_d_import "frobulous", check_d_import_path: ["./usr2"]
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
configure do
|
configure do
|
||||||
|
check_d_compiler
|
||||||
check_d_import "std.stdio"
|
check_d_import "std.stdio"
|
||||||
end
|
end
|
||||||
|
5
build_tests/configure/on_fail.rb
Normal file
5
build_tests/configure/on_fail.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
configure do
|
||||||
|
check_c_compiler "foo123c", fail: false, on_fail: "Install the foo123 package"
|
||||||
|
check_d_compiler "foo123d", fail: false
|
||||||
|
check_cxx_compiler "foo123cxx", on_fail: lambda {puts "Install the foo123cxx package"}
|
||||||
|
end
|
@ -6,7 +6,8 @@ build do
|
|||||||
"CMD_DESC" => "Generating")
|
"CMD_DESC" => "Generating")
|
||||||
env["build_root"] = env.build_root
|
env["build_root"] = env.build_root
|
||||||
env["inc_c"] = "inc.c"
|
env["inc_c"] = "inc.c"
|
||||||
env.build_after("${build_root}/program.o", "${inc_c}")
|
env.Object("program.o", "program.c")
|
||||||
env.Program("program.exe", ["program.c", "inc.c"])
|
env.build_after("program.o", "${inc_c}")
|
||||||
|
env.Program("program.exe", ["program.o", "inc.c"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,8 +4,9 @@ build do
|
|||||||
env["inc_h"] = "inc.h"
|
env["inc_h"] = "inc.h"
|
||||||
|
|
||||||
env.Copy("copy_inc.h", "${inc_h}")
|
env.Copy("copy_inc.h", "${inc_h}")
|
||||||
env.depends("${build_root}/program.o", "${inc_h}")
|
env.depends("program.o", "${inc_h}")
|
||||||
env.Program("program.exe", ["program.c", "inc.c"])
|
env.Object("program.o", "program.c")
|
||||||
|
env.Program("program.exe", ["program.o", "inc.c"])
|
||||||
|
|
||||||
inc_c = env.Command("inc.c",
|
inc_c = env.Command("inc.c",
|
||||||
[],
|
[],
|
||||||
|
@ -4,8 +4,9 @@ build do
|
|||||||
env["inc_h"] = "inc.h"
|
env["inc_h"] = "inc.h"
|
||||||
|
|
||||||
env.Copy("copy_inc.h", "${inc_h}")
|
env.Copy("copy_inc.h", "${inc_h}")
|
||||||
env.depends("${build_root}/program.o", "${inc_h}")
|
env.depends("program.o", "${inc_h}")
|
||||||
env.Program("program.exe", ["program.c", "inc.c"])
|
env.Object("program.o", "program.c")
|
||||||
|
env.Program("program.exe", ["program.o", "inc.c"])
|
||||||
|
|
||||||
env.Command("inc.c",
|
env.Command("inc.c",
|
||||||
[],
|
[],
|
||||||
|
@ -4,6 +4,7 @@ build do
|
|||||||
require 'yaml'
|
require 'yaml'
|
||||||
env.add_builder(:JsonToYaml) do |params|
|
env.add_builder(:JsonToYaml) do |params|
|
||||||
unless @cache.up_to_date?(@target, :JsonToYaml, @sources, @env)
|
unless @cache.up_to_date?(@target, :JsonToYaml, @sources, @env)
|
||||||
|
print_run_message("JsonToYaml #{@target}", nil)
|
||||||
@cache.mkdir_p(File.dirname(@target))
|
@cache.mkdir_p(File.dirname(@target))
|
||||||
File.open(@target, 'w') do |f|
|
File.open(@target, 'w') do |f|
|
||||||
f.write(YAML.dump(JSON.load(IO.read(@sources.first))))
|
f.write(YAML.dump(JSON.load(IO.read(@sources.first))))
|
||||||
|
5
build_tests/multiple_basename/Rsconscript
Normal file
5
build_tests/multiple_basename/Rsconscript
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
build do
|
||||||
|
Environment.new do |env|
|
||||||
|
env.Program("foo.exe", glob("*.cc", "*.c"))
|
||||||
|
end
|
||||||
|
end
|
6
build_tests/multiple_basename/foo.c
Normal file
6
build_tests/multiple_basename/foo.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void foo(void)
|
||||||
|
{
|
||||||
|
printf("foo\n");
|
||||||
|
}
|
12
build_tests/multiple_basename/foo.cc
Normal file
12
build_tests/multiple_basename/foo.cc
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void foo(void);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
foo();
|
||||||
|
std::cout << "main" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
3
build_tests/simple/path_append/foobar
Executable file
3
build_tests/simple/path_append/foobar
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo "foobar!"
|
3
build_tests/simple/path_append/gcc
Executable file
3
build_tests/simple/path_append/gcc
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exit 42
|
3
build_tests/simple/path_prepend/flex
Executable file
3
build_tests/simple/path_prepend/flex
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo "flex!"
|
10
build_tests/simple/pathing.rb
Normal file
10
build_tests/simple/pathing.rb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
path_prepend "path_prepend"
|
||||||
|
path_append "path_append"
|
||||||
|
|
||||||
|
build do
|
||||||
|
Environment.new do |env|
|
||||||
|
system("flex")
|
||||||
|
system("foobar")
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
end
|
||||||
|
end
|
18
build_tests/simple/user_dependencies_carat.rb
Normal file
18
build_tests/simple/user_dependencies_carat.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
class FileBuilder < Builder
|
||||||
|
def self.name
|
||||||
|
"File"
|
||||||
|
end
|
||||||
|
def run(options)
|
||||||
|
FileUtils.mkdir_p(File.dirname(@target))
|
||||||
|
File.binwrite(@target, ENV["file_contents"])
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
build do
|
||||||
|
Environment.new do |env|
|
||||||
|
env.add_builder(FileBuilder)
|
||||||
|
env.File("^/file.txt")
|
||||||
|
program = env.Program("^/simple.exe", Dir["*.c"])
|
||||||
|
env.depends("^/simple.exe", "^/file.txt")
|
||||||
|
end
|
||||||
|
end
|
10
build_tests/subsidiary/Rsconscript
Normal file
10
build_tests/subsidiary/Rsconscript
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
configure do
|
||||||
|
rscons "sub/Rsconscript"
|
||||||
|
rscons "sub/Rsconscript2", "configure"
|
||||||
|
puts "top configure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
rscons "sub/Rsconscript2", "build"
|
||||||
|
puts "top build"
|
||||||
|
end
|
10
build_tests/subsidiary/Rsconscript_dir
Normal file
10
build_tests/subsidiary/Rsconscript_dir
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
configure do
|
||||||
|
rscons "sub"
|
||||||
|
rscons "sub", "-f", "Rsconscript2", "configure"
|
||||||
|
puts "top configure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
rscons "sub", "-f", "Rsconscript2", "build"
|
||||||
|
puts "top build"
|
||||||
|
end
|
9
build_tests/subsidiary/Rsconscript_fail
Normal file
9
build_tests/subsidiary/Rsconscript_fail
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
configure do
|
||||||
|
rscons "sub/Rsconscript_fail"
|
||||||
|
puts "top configure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
rscons "sub/Rsconscript2", "build"
|
||||||
|
puts "top build"
|
||||||
|
end
|
4
build_tests/subsidiary/Rsconscript_samedir
Normal file
4
build_tests/subsidiary/Rsconscript_samedir
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
build do
|
||||||
|
rscons "second", "build"
|
||||||
|
puts "top build"
|
||||||
|
end
|
3
build_tests/subsidiary/second
Normal file
3
build_tests/subsidiary/second
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
build do
|
||||||
|
puts "second build"
|
||||||
|
end
|
7
build_tests/subsidiary/sub/Rsconscript
Normal file
7
build_tests/subsidiary/sub/Rsconscript
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
configure do
|
||||||
|
puts "sub Rsconscript configure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
puts "sub Rsconscript build"
|
||||||
|
end
|
7
build_tests/subsidiary/sub/Rsconscript2
Normal file
7
build_tests/subsidiary/sub/Rsconscript2
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
configure do
|
||||||
|
puts "sub Rsconscript2 configure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
puts "sub Rsconscript2 build"
|
||||||
|
end
|
8
build_tests/subsidiary/sub/Rsconscript_fail
Normal file
8
build_tests/subsidiary/sub/Rsconscript_fail
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
configure do
|
||||||
|
puts "sub Rsconscript configure"
|
||||||
|
check_program "foobarfailure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
puts "sub Rsconscript build"
|
||||||
|
end
|
@ -2,9 +2,9 @@ build do
|
|||||||
Environment.new(echo: :command) do |env|
|
Environment.new(echo: :command) do |env|
|
||||||
env.append('CPPPATH' => glob('src/**/*/'))
|
env.append('CPPPATH' => glob('src/**/*/'))
|
||||||
env.add_build_hook do |builder|
|
env.add_build_hook do |builder|
|
||||||
if File.basename(builder.target) == "one.o"
|
if File.basename(builder.sources.first) == "one.c"
|
||||||
builder.vars["CFLAGS"] << "-O1"
|
builder.vars["CFLAGS"] << "-O1"
|
||||||
elsif File.basename(builder.target) == "two.o"
|
elsif File.basename(builder.sources.first) == "two.c"
|
||||||
builder.vars["CFLAGS"] << "-O2"
|
builder.vars["CFLAGS"] << "-O2"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -246,6 +246,15 @@ configure do
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Global configuration options may be supplied to the compiler checks as well.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
configure do
|
||||||
|
check_c_compiler "x86_64-elf-gcc", on_fail: "Install x86_64-elf cross toolchain first!"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
###> Checking for a Header File
|
###> Checking for a Header File
|
||||||
|
|
||||||
The following methods can be used to check for the presence of a header file:
|
The following methods can be used to check for the presence of a header file:
|
||||||
@ -272,18 +281,6 @@ end
|
|||||||
|
|
||||||
Optionally specifies an array of paths to look for the header file in.
|
Optionally specifies an array of paths to look for the header file in.
|
||||||
|
|
||||||
##### `:fail`
|
|
||||||
|
|
||||||
If the `:fail` option is set to `false`, then the absence of the header file
|
|
||||||
will not result in the configure option failing.
|
|
||||||
The `:fail` option defaults to `true` if the `:set_define` option is not
|
|
||||||
defined, and defaults to `false` if the `:set_define` option is defined.
|
|
||||||
|
|
||||||
##### `:set_define`
|
|
||||||
|
|
||||||
If set, a build define of the specified String will be added to the
|
|
||||||
`CPPDEFINES` construction variable array if the requested header is found.
|
|
||||||
|
|
||||||
###> Checking for a D Import
|
###> Checking for a D Import
|
||||||
|
|
||||||
The `check_d_import` method can be used to check for the presence of D import.
|
The `check_d_import` method can be used to check for the presence of D import.
|
||||||
@ -327,18 +324,6 @@ end
|
|||||||
|
|
||||||
Optionally specifies an array of paths to look for the library in.
|
Optionally specifies an array of paths to look for the library in.
|
||||||
|
|
||||||
##### `:fail`
|
|
||||||
|
|
||||||
If the `:fail` option is set to `false`, then the absence of the library
|
|
||||||
will not result in the configure option failing.
|
|
||||||
The `:fail` option defaults to `true` if the `:set_define` option is not
|
|
||||||
defined, and defaults to `false` if the `:set_define` option is defined.
|
|
||||||
|
|
||||||
##### `:set_define`
|
|
||||||
|
|
||||||
If set, a build define of the specified String will be added to the
|
|
||||||
`CPPDEFINES` construction variable array if the requested library is found.
|
|
||||||
|
|
||||||
##### `:use`
|
##### `:use`
|
||||||
|
|
||||||
If not set, the library will be used by default in all `Environment` objects.
|
If not set, the library will be used by default in all `Environment` objects.
|
||||||
@ -387,18 +372,6 @@ used to look for package configuration flags for the specified package.
|
|||||||
If the `:program` option is given, the program specified will be used to look
|
If the `:program` option is given, the program specified will be used to look
|
||||||
for configuration flags.
|
for configuration flags.
|
||||||
|
|
||||||
##### `:fail`
|
|
||||||
|
|
||||||
If the `:fail` option is set to `false`, then the absence of the package or
|
|
||||||
program requested will not result in the configure option failing.
|
|
||||||
The `:fail` option defaults to `true` if the `:set_define` option is not
|
|
||||||
defined, and defaults to `false` if the `:set_define` option is defined.
|
|
||||||
|
|
||||||
##### `:set_define`
|
|
||||||
|
|
||||||
If set, a build define of the specified String will be added to the
|
|
||||||
`CPPDEFINES` construction variable array if the requested package is found.
|
|
||||||
|
|
||||||
##### `:use`
|
##### `:use`
|
||||||
|
|
||||||
If not set, the library will be used by default in all `Environment` objects.
|
If not set, the library will be used by default in all `Environment` objects.
|
||||||
@ -457,6 +430,46 @@ configure do
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
###> Global Configuration Check Options
|
||||||
|
|
||||||
|
#### `:fail`
|
||||||
|
|
||||||
|
If the `:fail` option is set to `false`, then the absence of the package or
|
||||||
|
program requested will not result in the configure option failing.
|
||||||
|
The `:fail` option defaults to `true` if the `:set_define` option is not
|
||||||
|
defined, and defaults to `false` if the `:set_define` option is defined.
|
||||||
|
|
||||||
|
#### `:on_fail`
|
||||||
|
|
||||||
|
The `:on_fail` option can be set to a String or a Proc object. If the
|
||||||
|
configuration operation fails (or would fail), the given message is printed
|
||||||
|
or the Proc is called.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
configure do
|
||||||
|
check_c_compiler "special-gcc", on_fail: "First install special gcc!"
|
||||||
|
end
|
||||||
|
|
||||||
|
configure do
|
||||||
|
package_hint = lambda do
|
||||||
|
puts "The following packages must be installed to build this project:"
|
||||||
|
puts "- libsdl2-dev"
|
||||||
|
puts "- libsdl2-image-dev"
|
||||||
|
puts "- libsdl2-net-dev"
|
||||||
|
end
|
||||||
|
check_lib "SDL2", on_fail: package_hint
|
||||||
|
check_lib "SDL2_image", on_fail: package_hint
|
||||||
|
check_lib "SDL2_net", on_fail: package_hint
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `:set_define`
|
||||||
|
|
||||||
|
If set, a build define of the specified String will be added to the
|
||||||
|
`CPPDEFINES` construction variable array if the requested package is found.
|
||||||
|
|
||||||
##> Build Operations
|
##> Build Operations
|
||||||
|
|
||||||
The `build` block is used to create Environments and register build targets.
|
The `build` block is used to create Environments and register build targets.
|
||||||
@ -599,14 +612,26 @@ There are several default builders that are built-in to Rscons:
|
|||||||
```ruby
|
```ruby
|
||||||
env.Command(target, sources, "CMD" => command)
|
env.Command(target, sources, "CMD" => command)
|
||||||
# Example
|
# Example
|
||||||
env.Command("docs.html", "docs.md",
|
env.Command("user_guide.html", "user_guide.md",
|
||||||
"CMD" => ["pandoc", "-fmarkdown", "-thtml", "-o${_TARGET}", "${_SOURCES}"],
|
"CMD" => ["pandoc", "-fmarkdown", "-thtml", "-o${_TARGET}", "${_SOURCES}"],
|
||||||
"CMD_DESC" => "PANDOC")
|
"CMD_DESC" => "Generating user guide:")
|
||||||
```
|
```
|
||||||
|
|
||||||
The `Command` builder executes a user-defined command in order to produce the
|
The `Command` builder executes a user-defined command in order to produce the
|
||||||
desired target file based on the provided source files.
|
desired target file based on the provided source files.
|
||||||
|
|
||||||
|
The `Command` builder supports the following construction variables:
|
||||||
|
|
||||||
|
* `CMD` (required) specifies the command to execute (an array of strings).
|
||||||
|
`CMD` is expanded for variable references, so the tokens `${_TARGET}` and
|
||||||
|
`${_SOURCES}` can be used, for example.
|
||||||
|
* `CMD_DESC` (optional) specifies the short text description to print when
|
||||||
|
the builder executes. The given description is followed by the target file
|
||||||
|
name.
|
||||||
|
* `CMD_STDOUT` (optional) specifies a file to redirect standard output to.
|
||||||
|
`CMD_STDOUT` is expanded for variable references, so the token `${_TARGET}`
|
||||||
|
can be used, for example.
|
||||||
|
|
||||||
####> The CFile Builder
|
####> The CFile Builder
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
@ -796,6 +821,22 @@ allows it to be used to create a shared library are added.
|
|||||||
Although it can be called explicitly, it is more commonly implicitly called by
|
Although it can be called explicitly, it is more commonly implicitly called by
|
||||||
the `SharedLibrary` builder.
|
the `SharedLibrary` builder.
|
||||||
|
|
||||||
|
###> Phony Targets
|
||||||
|
|
||||||
|
rscons supports phony build targets.
|
||||||
|
Normally, a builder produces an output file, and executes whenever the input
|
||||||
|
files or command have changed.
|
||||||
|
A phony build target can be used to register a builder that does not produce
|
||||||
|
an output file.
|
||||||
|
A custom builder can take some action when the input files change even if it
|
||||||
|
does not produce an output file.
|
||||||
|
Such a builder could perform verification or run a test on its source files,
|
||||||
|
possibly failing if some conditions are not met.
|
||||||
|
It could also simply output something to the console, such as an analysis of
|
||||||
|
the source file, whenever it changes.
|
||||||
|
A phony target is signified by passing a Symbol instead of a String as the
|
||||||
|
first parameter (target) to a builder method.
|
||||||
|
|
||||||
###> Explicit Dependencies
|
###> Explicit Dependencies
|
||||||
|
|
||||||
A target can be marked as depending on another file that Rscons would not
|
A target can be marked as depending on another file that Rscons would not
|
||||||
@ -859,6 +900,70 @@ In other words, build targets are not parallelized across a barrier.
|
|||||||
env.barrier
|
env.barrier
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##> Global Build Script Functionality
|
||||||
|
|
||||||
|
###> Using Subsidiary Build Scripts
|
||||||
|
|
||||||
|
The `rscons` build script method can be used to invoke an rscons subprocess to
|
||||||
|
perform an operation using a subsidiary rscons build script.
|
||||||
|
This can be used, for example, when a subproject is imported and a top-level
|
||||||
|
`configure` or `build` operation should also perform the same operation in the
|
||||||
|
subproject directory.
|
||||||
|
|
||||||
|
The first argument to the `rscons` method specifies either a directory name, or
|
||||||
|
the path to the subsidiary Rsconscript file to execute.
|
||||||
|
Any additional arguments are passed to `rscons` when it executes the subsidiary
|
||||||
|
script.
|
||||||
|
`rscons` will change working directories to the directory containing the
|
||||||
|
subsidiary script when executing it.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
configure do
|
||||||
|
rscons "subproject", "configure"
|
||||||
|
end
|
||||||
|
|
||||||
|
build do
|
||||||
|
rscons "subproject/Rsconscript", "build"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
It is also perfectly valid to perform a different operation in the subsidiary
|
||||||
|
script from the one being performed in the top-level script.
|
||||||
|
For example, in a project that requires a particular cross compiler, the
|
||||||
|
top-level `configure` script could build the necessary cross compiler using a
|
||||||
|
subsidiary build script.
|
||||||
|
This could look something like:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
configure do
|
||||||
|
rscons "cross/Rsconscript"
|
||||||
|
check_c_compiler "i686-elf-gcc"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This would build, and if necessary first configure, using the cross/Rsconscript
|
||||||
|
subsidiary build script.
|
||||||
|
Subsidiary build scripts are executed from within the directory containing the
|
||||||
|
build script.
|
||||||
|
|
||||||
|
###> PATH Management
|
||||||
|
|
||||||
|
`rscons` provides methods for management of the `PATH` environment variable.
|
||||||
|
|
||||||
|
The `path_append` and `path_prepend` methods can be used to append or prepend
|
||||||
|
a path to the `PATH` environment variable.
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
path_prepend "i686-elf-gcc/bin"
|
||||||
|
```
|
||||||
|
|
||||||
|
The `path_set` method sets the `PATH` environment variable to the given
|
||||||
|
Array or String.
|
||||||
|
The `path_components` method returns an Array of the components in the `PATH`
|
||||||
|
environment variable.
|
||||||
|
|
||||||
##> Extending Rscons
|
##> Extending Rscons
|
||||||
|
|
||||||
### Adding New Languages
|
### Adding New Languages
|
||||||
@ -1025,7 +1130,7 @@ Here is our Custom builder example extended to print its status:
|
|||||||
```ruby
|
```ruby
|
||||||
class Rscons::Builders::Custom < Rscons::Builder
|
class Rscons::Builders::Custom < Rscons::Builder
|
||||||
def run(options)
|
def run(options)
|
||||||
print_run_message("Creating <target>#{@target}<reset> from Custom builder")
|
print_run_message("Creating <target>#{@target}<reset> from Custom builder", nil)
|
||||||
File.open(@target, "w") do |fh|
|
File.open(@target, "w") do |fh|
|
||||||
fh.write("Target file created.")
|
fh.write("Target file created.")
|
||||||
end
|
end
|
||||||
@ -1050,7 +1155,7 @@ Here is a Custom builder which combines its source files similar to what the
|
|||||||
class Rscons::Builders::Custom < Rscons::Builder
|
class Rscons::Builders::Custom < Rscons::Builder
|
||||||
def run(options)
|
def run(options)
|
||||||
unless @cache.up_to_date?(@target, nil, @sources, @env)
|
unless @cache.up_to_date?(@target, nil, @sources, @env)
|
||||||
print_run_message("Combining <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>")
|
print_run_message("Combining <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>", nil)
|
||||||
File.open(@target, "wb") do |fh|
|
File.open(@target, "wb") do |fh|
|
||||||
@sources.each do |source|
|
@sources.each do |source|
|
||||||
fh.write(File.read(source, mode: "rb"))
|
fh.write(File.read(source, mode: "rb"))
|
||||||
@ -1277,7 +1382,7 @@ To do this, create a `configure` script with contents similar to the following:
|
|||||||
|
|
||||||
```
|
```
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec "$(dirname "$0")"/rscons "$@"
|
exec "$(dirname "$0")"/rscons configure "$@"
|
||||||
```
|
```
|
||||||
|
|
||||||
and make it executable with `chmod +x configure`.
|
and make it executable with `chmod +x configure`.
|
||||||
|
@ -35,8 +35,8 @@ module Rscons
|
|||||||
:SharedObject,
|
:SharedObject,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Class to represent a fatal error while building a target.
|
# Class to represent a fatal error during an Rscons operation.
|
||||||
class BuildError < RuntimeError; end
|
class RsconsError < RuntimeError; end
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
@ -64,16 +64,6 @@ module Rscons
|
|||||||
target.is_a?(Symbol)
|
target.is_a?(Symbol)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return a new path by changing the suffix in path to suffix.
|
|
||||||
#
|
|
||||||
# @param path [String] The path to alter.
|
|
||||||
# @param suffix [String] The new filename suffix, e.g. ".exe".
|
|
||||||
#
|
|
||||||
# @return [String] New path.
|
|
||||||
def set_suffix(path, suffix)
|
|
||||||
path.sub(/\.[^.]*$/, "") + suffix
|
|
||||||
end
|
|
||||||
|
|
||||||
# Return the system shell and arguments for executing a shell command.
|
# Return the system shell and arguments for executing a shell command.
|
||||||
#
|
#
|
||||||
# @return [Array<String>] The shell and flag.
|
# @return [Array<String>] The shell and flag.
|
||||||
@ -91,7 +81,7 @@ module Rscons
|
|||||||
end
|
end
|
||||||
if ENV["SHELL"] and ENV["SHELL"] != "" and test_shell[ENV["SHELL"], "-c"]
|
if ENV["SHELL"] and ENV["SHELL"] != "" and test_shell[ENV["SHELL"], "-c"]
|
||||||
[ENV["SHELL"], "-c"]
|
[ENV["SHELL"], "-c"]
|
||||||
elsif Object.const_get("RUBY_PLATFORM") =~ /mingw/
|
elsif Object.const_get("RUBY_PLATFORM") =~ /mingw|msys/
|
||||||
if test_shell["sh", "-c"]
|
if test_shell["sh", "-c"]
|
||||||
# Using Rscons from MSYS should use MSYS's shell.
|
# Using Rscons from MSYS should use MSYS's shell.
|
||||||
["sh", "-c"]
|
["sh", "-c"]
|
||||||
@ -112,7 +102,7 @@ module Rscons
|
|||||||
# @return [Array<String>] Command used to execute commands.
|
# @return [Array<String>] Command used to execute commands.
|
||||||
def command_executer
|
def command_executer
|
||||||
@command_executer ||=
|
@command_executer ||=
|
||||||
if Object.const_get("RUBY_PLATFORM") =~ /mingw/
|
if Object.const_get("RUBY_PLATFORM") =~ /mingw|msys/
|
||||||
if ENV.keys.find {|key| key =~ /MSYS/}
|
if ENV.keys.find {|key| key =~ /MSYS/}
|
||||||
begin
|
begin
|
||||||
if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success"
|
if IO.popen(["env", "echo", "success"]) {|io| io.read.strip} == "success"
|
||||||
|
@ -84,7 +84,7 @@ module Rscons
|
|||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether to output ANSI color escape codes.
|
# Whether to output ANSI color escape codes.
|
||||||
def do_ansi?(io)
|
def do_ansi?(io)
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
if RUBY_PLATFORM =~ /mingw|msys/
|
||||||
(ENV["TERM"] == "xterm") && %w[fifo characterSpecial].include?(io.stat.ftype)
|
(ENV["TERM"] == "xterm") && %w[fifo characterSpecial].include?(io.stat.ftype)
|
||||||
else
|
else
|
||||||
io.tty?
|
io.tty?
|
||||||
|
@ -75,6 +75,8 @@ module Rscons
|
|||||||
end
|
end
|
||||||
if rv == 0
|
if rv == 0
|
||||||
build(operation_options)
|
build(operation_options)
|
||||||
|
else
|
||||||
|
rv
|
||||||
end
|
end
|
||||||
when "clean"
|
when "clean"
|
||||||
clean
|
clean
|
||||||
@ -134,8 +136,8 @@ module Rscons
|
|||||||
env.process
|
env.process
|
||||||
end
|
end
|
||||||
0
|
0
|
||||||
rescue BuildError => be
|
rescue RsconsError => e
|
||||||
Ansi.write($stderr, :red, be.message, :reset, "\n")
|
Ansi.write($stderr, :red, e.message, :reset, "\n")
|
||||||
1
|
1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -191,7 +193,11 @@ module Rscons
|
|||||||
co = ConfigureOp.new(options)
|
co = ConfigureOp.new(options)
|
||||||
begin
|
begin
|
||||||
@script.configure(co)
|
@script.configure(co)
|
||||||
rescue ConfigureOp::ConfigureFailure
|
rescue RsconsError => e
|
||||||
|
if e.message and e.message != ""
|
||||||
|
$stderr.puts e.message
|
||||||
|
end
|
||||||
|
Ansi.write($stderr, :red, "Configuration failed", :reset, "\n")
|
||||||
rv = 1
|
rv = 1
|
||||||
end
|
end
|
||||||
co.close(rv == 0)
|
co.close(rv == 0)
|
||||||
|
@ -57,6 +57,7 @@ module Rscons
|
|||||||
printed_message = true
|
printed_message = true
|
||||||
end
|
end
|
||||||
@cache.mkdir_p(File.dirname(dest), install: @install_builder)
|
@cache.mkdir_p(File.dirname(dest), install: @install_builder)
|
||||||
|
FileUtils.rm_f(dest)
|
||||||
FileUtils.cp(src, dest, :preserve => true)
|
FileUtils.cp(src, dest, :preserve => true)
|
||||||
end
|
end
|
||||||
@cache.register_build(dest, :Copy, [src], @env, install: @install_builder)
|
@cache.register_build(dest, :Copy, [src], @env, install: @install_builder)
|
||||||
|
@ -75,10 +75,10 @@ module Rscons
|
|||||||
@vars["_SOURCES"] = @sources
|
@vars["_SOURCES"] = @sources
|
||||||
depfilesuffix = @env.expand_varref("${DEPFILESUFFIX}", vars)
|
depfilesuffix = @env.expand_varref("${DEPFILESUFFIX}", vars)
|
||||||
@vars["_DEPFILE"] =
|
@vars["_DEPFILE"] =
|
||||||
if @vars[:direct]
|
if @vars[:direct] || !@target.start_with?("#{@env.build_root}/")
|
||||||
@env.get_build_fname(target, depfilesuffix, self.class)
|
@env.get_build_fname(@target, depfilesuffix, self.class)
|
||||||
else
|
else
|
||||||
Rscons.set_suffix(target, depfilesuffix)
|
"#{@target}#{depfilesuffix}"
|
||||||
end
|
end
|
||||||
@cache.mkdir_p(File.dirname(@vars["_DEPFILE"]))
|
@cache.mkdir_p(File.dirname(@vars["_DEPFILE"]))
|
||||||
command = @env.build_command(@command_template, @vars)
|
command = @env.build_command(@command_template, @vars)
|
||||||
|
@ -23,7 +23,7 @@ module Rscons
|
|||||||
@vars["_PREPROCESS_DEPGEN"] = depgen
|
@vars["_PREPROCESS_DEPGEN"] = depgen
|
||||||
@vars["_TARGET"] = @target
|
@vars["_TARGET"] = @target
|
||||||
@vars["_SOURCES"] = @sources
|
@vars["_SOURCES"] = @sources
|
||||||
@vars["_DEPFILE"] = Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars))
|
@vars["_DEPFILE"] = "#{target}#{env.expand_varref("${DEPFILESUFFIX}", vars)}"
|
||||||
command = @env.build_command("${CPP_CMD}", @vars)
|
command = @env.build_command("${CPP_CMD}", @vars)
|
||||||
self.produces(@vars["_DEPFILE"])
|
self.produces(@vars["_DEPFILE"])
|
||||||
standard_command("Preprocessing <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>", command)
|
standard_command("Preprocessing <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>", command)
|
||||||
|
@ -6,11 +6,13 @@ USAGE = <<EOF
|
|||||||
Usage: #{$0} [global options] [operation] [operation options]
|
Usage: #{$0} [global options] [operation] [operation options]
|
||||||
|
|
||||||
Global options:
|
Global options:
|
||||||
|
-f FILE Use FILE as Rsconscript
|
||||||
-F, --show-failure Show failed command log from previous build and exit
|
-F, --show-failure Show failed command log from previous build and exit
|
||||||
--version Show rscons version and exit
|
|
||||||
-h, --help Show rscons help and exit
|
-h, --help Show rscons help and exit
|
||||||
|
-j N, --nthreads=N Set number of threads (local default: #{Rscons.application.n_threads})
|
||||||
-r COLOR, --color=COLOR Set color mode (off, auto, force)
|
-r COLOR, --color=COLOR Set color mode (off, auto, force)
|
||||||
-v, --verbose Run verbosely
|
-v, --verbose Run verbosely
|
||||||
|
--version Show rscons version and exit
|
||||||
|
|
||||||
Operations:
|
Operations:
|
||||||
configure Configure the project
|
configure Configure the project
|
||||||
@ -23,10 +25,6 @@ Operations:
|
|||||||
Configure options:
|
Configure options:
|
||||||
-b BUILD, --build=BUILD Set build directory (default: build)
|
-b BUILD, --build=BUILD Set build directory (default: build)
|
||||||
--prefix=PREFIX Set installation prefix (default: /usr/local)
|
--prefix=PREFIX Set installation prefix (default: /usr/local)
|
||||||
|
|
||||||
Build options:
|
|
||||||
-j N, --nthreads=N Set number of threads (local default: #{Rscons.application.n_threads})
|
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
module Rscons
|
module Rscons
|
||||||
|
@ -5,9 +5,6 @@ module Rscons
|
|||||||
# Class to manage a configure operation.
|
# Class to manage a configure operation.
|
||||||
class ConfigureOp
|
class ConfigureOp
|
||||||
|
|
||||||
# Exception raised when a configuration error occurs.
|
|
||||||
class ConfigureFailure < Exception; end
|
|
||||||
|
|
||||||
# Create a ConfigureOp.
|
# Create a ConfigureOp.
|
||||||
#
|
#
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
@ -62,6 +59,10 @@ module Rscons
|
|||||||
# @return [void]
|
# @return [void]
|
||||||
def check_c_compiler(*ccc)
|
def check_c_compiler(*ccc)
|
||||||
$stdout.write("Checking for C compiler... ")
|
$stdout.write("Checking for C compiler... ")
|
||||||
|
options = {}
|
||||||
|
if ccc.last.is_a?(Hash)
|
||||||
|
options = ccc.slice!(-1)
|
||||||
|
end
|
||||||
if ccc.empty?
|
if ccc.empty?
|
||||||
# Default C compiler search array.
|
# Default C compiler search array.
|
||||||
ccc = %w[gcc clang]
|
ccc = %w[gcc clang]
|
||||||
@ -69,7 +70,7 @@ module Rscons
|
|||||||
cc = ccc.find do |cc|
|
cc = ccc.find do |cc|
|
||||||
test_c_compiler(cc)
|
test_c_compiler(cc)
|
||||||
end
|
end
|
||||||
complete(cc ? 0 : 1, success_message: cc)
|
complete(cc ? 0 : 1, options.merge(success_message: cc))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check for a working C++ compiler.
|
# Check for a working C++ compiler.
|
||||||
@ -80,6 +81,10 @@ module Rscons
|
|||||||
# @return [void]
|
# @return [void]
|
||||||
def check_cxx_compiler(*ccc)
|
def check_cxx_compiler(*ccc)
|
||||||
$stdout.write("Checking for C++ compiler... ")
|
$stdout.write("Checking for C++ compiler... ")
|
||||||
|
options = {}
|
||||||
|
if ccc.last.is_a?(Hash)
|
||||||
|
options = ccc.slice!(-1)
|
||||||
|
end
|
||||||
if ccc.empty?
|
if ccc.empty?
|
||||||
# Default C++ compiler search array.
|
# Default C++ compiler search array.
|
||||||
ccc = %w[g++ clang++]
|
ccc = %w[g++ clang++]
|
||||||
@ -87,7 +92,7 @@ module Rscons
|
|||||||
cc = ccc.find do |cc|
|
cc = ccc.find do |cc|
|
||||||
test_cxx_compiler(cc)
|
test_cxx_compiler(cc)
|
||||||
end
|
end
|
||||||
complete(cc ? 0 : 1, success_message: cc)
|
complete(cc ? 0 : 1, options.merge(success_message: cc))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check for a working D compiler.
|
# Check for a working D compiler.
|
||||||
@ -98,6 +103,10 @@ module Rscons
|
|||||||
# @return [void]
|
# @return [void]
|
||||||
def check_d_compiler(*cdc)
|
def check_d_compiler(*cdc)
|
||||||
$stdout.write("Checking for D compiler... ")
|
$stdout.write("Checking for D compiler... ")
|
||||||
|
options = {}
|
||||||
|
if cdc.last.is_a?(Hash)
|
||||||
|
options = cdc.slice!(-1)
|
||||||
|
end
|
||||||
if cdc.empty?
|
if cdc.empty?
|
||||||
# Default D compiler search array.
|
# Default D compiler search array.
|
||||||
cdc = %w[gdc ldc2]
|
cdc = %w[gdc ldc2]
|
||||||
@ -105,7 +114,7 @@ module Rscons
|
|||||||
dc = cdc.find do |dc|
|
dc = cdc.find do |dc|
|
||||||
test_d_compiler(dc)
|
test_d_compiler(dc)
|
||||||
end
|
end
|
||||||
complete(dc ? 0 : 1, success_message: dc)
|
complete(dc ? 0 : 1, options.merge(success_message: dc))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check for a package or configure program output.
|
# Check for a package or configure program output.
|
||||||
@ -387,11 +396,15 @@ module Rscons
|
|||||||
else
|
else
|
||||||
!options[:set_define]
|
!options[:set_define]
|
||||||
end
|
end
|
||||||
|
color = should_fail ? :red : :yellow
|
||||||
|
Ansi.write($stdout, color, "#{fail_message}\n")
|
||||||
|
if options[:on_fail].is_a?(String)
|
||||||
|
$stdout.puts(options[:on_fail])
|
||||||
|
elsif options[:on_fail].is_a?(Proc)
|
||||||
|
options[:on_fail].call
|
||||||
|
end
|
||||||
if should_fail
|
if should_fail
|
||||||
Ansi.write($stdout, :red, "#{fail_message}\n")
|
raise RsconsError.new
|
||||||
raise ConfigureFailure.new
|
|
||||||
else
|
|
||||||
Ansi.write($stdout, :yellow, "#{fail_message}\n")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -408,24 +421,19 @@ module Rscons
|
|||||||
def test_c_compiler(cc)
|
def test_c_compiler(cc)
|
||||||
File.open("#{@work_dir}/cfgtest.c", "wb") do |fh|
|
File.open("#{@work_dir}/cfgtest.c", "wb") do |fh|
|
||||||
fh.puts <<-EOF
|
fh.puts <<-EOF
|
||||||
#include <stdio.h>
|
int fun(int val) {
|
||||||
int main(int argc, char * argv[]) {
|
return val * 2;
|
||||||
printf("Success.\\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
command = %W[#{cc} -o #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.c]
|
command = %W[#{cc} -c -o #{@work_dir}/cfgtest.o #{@work_dir}/cfgtest.c]
|
||||||
merge = {"CC" => cc}
|
merge = {"CC" => cc}
|
||||||
_, _, status = log_and_test_command(command)
|
_, _, status = log_and_test_command(command)
|
||||||
if status == 0
|
if status == 0
|
||||||
stdout, _, status = log_and_test_command(["#{@work_dir}/cfgtest.exe"])
|
|
||||||
if status == 0 and stdout =~ /Success/
|
|
||||||
store_merge(merge)
|
store_merge(merge)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Test a C++ compiler.
|
# Test a C++ compiler.
|
||||||
#
|
#
|
||||||
@ -437,25 +445,20 @@ module Rscons
|
|||||||
def test_cxx_compiler(cc)
|
def test_cxx_compiler(cc)
|
||||||
File.open("#{@work_dir}/cfgtest.cxx", "wb") do |fh|
|
File.open("#{@work_dir}/cfgtest.cxx", "wb") do |fh|
|
||||||
fh.puts <<-EOF
|
fh.puts <<-EOF
|
||||||
#include <iostream>
|
template<typename T>
|
||||||
using namespace std;
|
T fun(T val) {
|
||||||
int main(int argc, char * argv[]) {
|
return val * 2;
|
||||||
cout << "Success." << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
command = %W[#{cc} -o #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.cxx]
|
command = %W[#{cc} -c -o #{@work_dir}/cfgtest.o #{@work_dir}/cfgtest.cxx]
|
||||||
merge = {"CXX" => cc}
|
merge = {"CXX" => cc}
|
||||||
_, _, status = log_and_test_command(command)
|
_, _, status = log_and_test_command(command)
|
||||||
if status == 0
|
if status == 0
|
||||||
stdout, _, status = log_and_test_command(["#{@work_dir}/cfgtest.exe"])
|
|
||||||
if status == 0 and stdout =~ /Success/
|
|
||||||
store_merge(merge)
|
store_merge(merge)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Test a D compiler.
|
# Test a D compiler.
|
||||||
#
|
#
|
||||||
@ -467,9 +470,8 @@ module Rscons
|
|||||||
def test_d_compiler(dc)
|
def test_d_compiler(dc)
|
||||||
File.open("#{@work_dir}/cfgtest.d", "wb") do |fh|
|
File.open("#{@work_dir}/cfgtest.d", "wb") do |fh|
|
||||||
fh.puts <<-EOF
|
fh.puts <<-EOF
|
||||||
import std.stdio;
|
import core.math;
|
||||||
int main() {
|
int fun() {
|
||||||
writeln("Success.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
@ -477,32 +479,28 @@ module Rscons
|
|||||||
[:gdc, :ldc2].find do |dc_test|
|
[:gdc, :ldc2].find do |dc_test|
|
||||||
case dc_test
|
case dc_test
|
||||||
when :gdc
|
when :gdc
|
||||||
command = %W[#{dc} -o #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.d]
|
command = %W[#{dc} -c -o #{@work_dir}/cfgtest.o #{@work_dir}/cfgtest.d]
|
||||||
merge = {"DC" => dc}
|
merge = {"DC" => dc}
|
||||||
when :ldc2
|
when :ldc2
|
||||||
command = %W[#{dc} -of #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.d]
|
# ldc2 on Windows expect an object file suffix of .obj.
|
||||||
|
ldc_objsuffix = RUBY_PLATFORM =~ /mingw|msys/ ? ".obj" : ".o"
|
||||||
|
command = %W[#{dc} -c -of #{@work_dir}/cfgtest#{ldc_objsuffix} #{@work_dir}/cfgtest.d]
|
||||||
env = BasicEnvironment.new
|
env = BasicEnvironment.new
|
||||||
merge = {
|
merge = {
|
||||||
"DC" => dc,
|
"DC" => dc,
|
||||||
"DCCMD" => env["DCCMD"].map {|e| if e == "-o"; "-of"; else; e; end},
|
"DCCMD" => env["DCCMD"].map {|e| e.sub(/^-o$/, "-of")},
|
||||||
"LDCMD" => env["LDCMD"].map {|e| if e == "-o"; "-of"; else; e; end},
|
"LDCMD" => env["LDCMD"].map {|e| e.sub(/^-o$/, "-of")},
|
||||||
"DDEPGEN" => ["-deps=${_DEPFILE}"],
|
"DDEPGEN" => ["-deps=${_DEPFILE}"],
|
||||||
}
|
}
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
merge["OBJSUFFIX"] = [ldc_objsuffix]
|
||||||
# ldc2 on Windows expect an object file suffix of .obj.
|
|
||||||
merge["OBJSUFFIX"] = %w[.obj]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
_, _, status = log_and_test_command(command)
|
_, _, status = log_and_test_command(command)
|
||||||
if status == 0
|
if status == 0
|
||||||
stdout, _, status = log_and_test_command(["#{@work_dir}/cfgtest.exe"])
|
|
||||||
if status == 0 and stdout =~ /Success/
|
|
||||||
store_merge(merge)
|
store_merge(merge)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
# Common functionality for all store methods.
|
# Common functionality for all store methods.
|
||||||
#
|
#
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
|
|
||||||
on_windows = RUBY_PLATFORM =~ /mingw|cygwin/
|
on_windows = RUBY_PLATFORM =~ /mingw|msys|cygwin/
|
||||||
pic_flags = on_windows ? [] : %w[-fPIC]
|
pic_flags = on_windows ? [] : %w[-fPIC]
|
||||||
|
|
||||||
# Default Rscons construction variables.
|
# Default Rscons construction variables.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
require "fileutils"
|
require "fileutils"
|
||||||
require "set"
|
require "set"
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
require "thwait"
|
|
||||||
|
|
||||||
module Rscons
|
module Rscons
|
||||||
# The Environment class is the main programmatic interface to Rscons. It
|
# The Environment class is the main programmatic interface to Rscons. It
|
||||||
@ -251,7 +250,7 @@ module Rscons
|
|||||||
if extra_path = builder_class.extra_path
|
if extra_path = builder_class.extra_path
|
||||||
extra_path = "/#{extra_path}"
|
extra_path = "/#{extra_path}"
|
||||||
end
|
end
|
||||||
"#{@build_root}#{extra_path}/#{Util.make_relative_path(Rscons.set_suffix(source_fname, suffix))}".gsub("\\", "/")
|
"#{@build_root}#{extra_path}/#{Util.make_relative_path("#{source_fname}#{suffix}")}".gsub("\\", "/")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build all build targets specified in the Environment.
|
# Build all build targets specified in the Environment.
|
||||||
@ -287,9 +286,9 @@ module Rscons
|
|||||||
unless @process_failures.empty?
|
unless @process_failures.empty?
|
||||||
msg = @process_failures.join("\n")
|
msg = @process_failures.join("\n")
|
||||||
if Cache.instance["failed_commands"].size > 0
|
if Cache.instance["failed_commands"].size > 0
|
||||||
msg += "\nUse -F to view the failed command log from the previous build operation"
|
msg += "\nUse `#{Util.command_to_execute_me} -F` to view the failed command log from the previous build operation"
|
||||||
end
|
end
|
||||||
raise BuildError.new(msg)
|
raise RsconsError.new(msg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -347,12 +346,12 @@ module Rscons
|
|||||||
if target.is_a?(Builder)
|
if target.is_a?(Builder)
|
||||||
target = target.target
|
target = target.target
|
||||||
end
|
end
|
||||||
target = expand_varref(target.to_s)
|
target = expand_path(expand_varref(target.to_s))
|
||||||
user_deps = user_deps.map do |ud|
|
user_deps = user_deps.map do |ud|
|
||||||
if ud.is_a?(Builder)
|
if ud.is_a?(Builder)
|
||||||
ud = ud.target
|
ud = ud.target
|
||||||
end
|
end
|
||||||
expand_varref(ud)
|
expand_path(expand_varref(ud))
|
||||||
end
|
end
|
||||||
@user_deps[target] ||= []
|
@user_deps[target] ||= []
|
||||||
@user_deps[target] = (@user_deps[target] + user_deps).uniq
|
@user_deps[target] = (@user_deps[target] + user_deps).uniq
|
||||||
@ -702,10 +701,7 @@ module Rscons
|
|||||||
!thread.alive?
|
!thread.alive?
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if @threads.empty?
|
Util.wait_for_thread(*@threads.keys)
|
||||||
raise "No threads to wait for"
|
|
||||||
end
|
|
||||||
ThreadsWait.new(*@threads.keys).next_wait
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,8 +3,87 @@ module Rscons
|
|||||||
# The Script class encapsulates the state of a build script.
|
# The Script class encapsulates the state of a build script.
|
||||||
class Script
|
class Script
|
||||||
|
|
||||||
# DSL available to the Rsconscript.
|
# Global DSL methods.
|
||||||
class Dsl
|
class GlobalDsl
|
||||||
|
|
||||||
|
# Return path components from the PATH variable.
|
||||||
|
#
|
||||||
|
# @return [Array<String>]
|
||||||
|
# Path components from the PATH variable.
|
||||||
|
def path_components
|
||||||
|
ENV["PATH"].split(File::PATH_SEPARATOR)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Prepend a path component to the PATH variable.
|
||||||
|
#
|
||||||
|
# @param path [String]
|
||||||
|
# Path to prepend.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def path_prepend(path)
|
||||||
|
path_set([File.expand_path(path)] + path_components)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Append a path component to the PATH variable.
|
||||||
|
#
|
||||||
|
# @param path [String]
|
||||||
|
# Path to append.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def path_append(path)
|
||||||
|
path_set(path_components + [File.expand_path(path)])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set the PATH variable.
|
||||||
|
#
|
||||||
|
# @param new_path [String, Array<String>]
|
||||||
|
# New PATH variable value as an array or string.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def path_set(new_path)
|
||||||
|
if new_path.is_a?(Array)
|
||||||
|
new_path = new_path.join(File::PATH_SEPARATOR)
|
||||||
|
end
|
||||||
|
ENV["PATH"] = new_path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Invoke rscons in a subprocess for a subsidiary Rsconscript file.
|
||||||
|
#
|
||||||
|
# @param path [String]
|
||||||
|
# Path to subsidiary Rsconscript to execute, or path to subsidiary
|
||||||
|
# directory to run rscons in.
|
||||||
|
# @param args[Array<String>]
|
||||||
|
# Arguments to pass to rscons subprocess.
|
||||||
|
def rscons(path, *args)
|
||||||
|
rscons_path = File.expand_path($0)
|
||||||
|
path = File.expand_path(path)
|
||||||
|
if File.directory?(path)
|
||||||
|
command = [*args]
|
||||||
|
dir = path
|
||||||
|
else
|
||||||
|
command = ["-f", path, *args]
|
||||||
|
dir = File.dirname(path)
|
||||||
|
end
|
||||||
|
if File.exist?("#{dir}/rscons")
|
||||||
|
rscons_path = "#{dir}/rscons"
|
||||||
|
end
|
||||||
|
command = [rscons_path] + command
|
||||||
|
print_dir = dir != "." && dir != File.expand_path(Dir.pwd)
|
||||||
|
if ENV["specs"] and not ENV["dist_specs"] # specs
|
||||||
|
command = ["ruby", $LOAD_PATH.map {|p| ["-I", p]}, command].flatten # specs
|
||||||
|
end # specs
|
||||||
|
puts "rscons: Entering directory '#{dir}'" if print_dir
|
||||||
|
result = system(*command, chdir: dir)
|
||||||
|
puts "rscons: Leaving directory '#{dir}'" if print_dir
|
||||||
|
unless result
|
||||||
|
raise RsconsError.new("Failed command: " + command.join(" "))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# Top-level DSL available to the Rsconscript.
|
||||||
|
class Dsl < GlobalDsl
|
||||||
# Create a Dsl.
|
# Create a Dsl.
|
||||||
def initialize(script)
|
def initialize(script)
|
||||||
@script = script
|
@script = script
|
||||||
@ -59,7 +138,7 @@ module Rscons
|
|||||||
end
|
end
|
||||||
|
|
||||||
# DSL available to the 'configure' block.
|
# DSL available to the 'configure' block.
|
||||||
class ConfigureDsl
|
class ConfigureDsl < GlobalDsl
|
||||||
# Create a ConfigureDsl.
|
# Create a ConfigureDsl.
|
||||||
#
|
#
|
||||||
# @param configure_op [ConfigureOp]
|
# @param configure_op [ConfigureOp]
|
||||||
|
@ -9,7 +9,7 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [Boolean] Whether the given path is an absolute filesystem path.
|
# @return [Boolean] Whether the given path is an absolute filesystem path.
|
||||||
def absolute_path?(path)
|
def absolute_path?(path)
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
if RUBY_PLATFORM =~ /mingw|msys/
|
||||||
path =~ %r{^(?:\w:)?[\\/]}
|
path =~ %r{^(?:\w:)?[\\/]}
|
||||||
else
|
else
|
||||||
path.start_with?("/")
|
path.start_with?("/")
|
||||||
@ -68,8 +68,8 @@ module Rscons
|
|||||||
case RbConfig::CONFIG["host_os"]
|
case RbConfig::CONFIG["host_os"]
|
||||||
when /linux/
|
when /linux/
|
||||||
return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size
|
return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size
|
||||||
when /mswin|mingw/
|
when /mswin|mingw|msys/
|
||||||
if `wmic cpu get NumberOfLogicalProcessors /value` =~ /NumberOfLogicalProcessors=(\d+)/
|
if `wmic cpu get NumberOfLogicalProcessors -value` =~ /NumberOfLogicalProcessors=(\d+)/
|
||||||
return $1.to_i
|
return $1.to_i
|
||||||
end
|
end
|
||||||
when /darwin/
|
when /darwin/
|
||||||
@ -191,6 +191,40 @@ module Rscons
|
|||||||
deps
|
deps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Wait for any of a number of threads to complete.
|
||||||
|
#
|
||||||
|
# @param threads [Array<Thread>]
|
||||||
|
# Threads to wait for.
|
||||||
|
#
|
||||||
|
# @return [Thread]
|
||||||
|
# The Thread that completed.
|
||||||
|
def wait_for_thread(*threads)
|
||||||
|
if threads.empty?
|
||||||
|
raise "No threads to wait for"
|
||||||
|
end
|
||||||
|
queue = Queue.new
|
||||||
|
threads.each do |thread|
|
||||||
|
# Create a wait thread for each thread we're waiting for.
|
||||||
|
Thread.new do
|
||||||
|
begin
|
||||||
|
thread.join
|
||||||
|
ensure
|
||||||
|
queue.push(thread)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Wait for any thread to complete.
|
||||||
|
queue.pop
|
||||||
|
end
|
||||||
|
|
||||||
|
# Command that can be run to execute this instance of rscons from the
|
||||||
|
# current working directory.
|
||||||
|
def command_to_execute_me
|
||||||
|
command = Pathname.new(File.expand_path($0)).relative_path_from(Dir.pwd).to_s
|
||||||
|
command = "./#{command}" unless command["/"]
|
||||||
|
command
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Check if a directory contains a certain executable.
|
# Check if a directory contains a certain executable.
|
||||||
@ -199,11 +233,14 @@ module Rscons
|
|||||||
# Directory to look in.
|
# Directory to look in.
|
||||||
# @param executable [String]
|
# @param executable [String]
|
||||||
# Executable to look for.
|
# Executable to look for.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# Executable found.
|
||||||
def test_path_for_executable(path_entry, executable)
|
def test_path_for_executable(path_entry, executable)
|
||||||
is_executable = lambda do |path|
|
is_executable = lambda do |path|
|
||||||
File.file?(path) and File.executable?(path)
|
File.file?(path) and File.executable?(path)
|
||||||
end
|
end
|
||||||
if RbConfig::CONFIG["host_os"] =~ /mswin|windows|mingw/i
|
if RbConfig::CONFIG["host_os"] =~ /mswin|windows|mingw|msys/i
|
||||||
if File.directory?(path_entry)
|
if File.directory?(path_entry)
|
||||||
executable = executable.downcase
|
executable = executable.downcase
|
||||||
dir_entries = Dir.entries(path_entry)
|
dir_entries = Dir.entries(path_entry)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
# Project version.
|
# Project version.
|
||||||
VERSION = "2.0.0"
|
VERSION = "2.2.0"
|
||||||
end
|
end
|
||||||
|
@ -44,7 +44,7 @@ combine_files[START_FILE]
|
|||||||
# Strip Ruby comment lines and empty lines to save some space, but do not
|
# Strip Ruby comment lines and empty lines to save some space, but do not
|
||||||
# remove lines that are in heredoc sections. This isn't terribly robust to be
|
# remove lines that are in heredoc sections. This isn't terribly robust to be
|
||||||
# used in the wild, but works for the heredoc instances for this project.
|
# used in the wild, but works for the heredoc instances for this project.
|
||||||
stripped_comments = []
|
stripped = []
|
||||||
heredoc_end = nil
|
heredoc_end = nil
|
||||||
combined_file.each do |line|
|
combined_file.each do |line|
|
||||||
if line =~ /<<-?([A-Z]+)/
|
if line =~ /<<-?([A-Z]+)/
|
||||||
@ -53,14 +53,16 @@ combined_file.each do |line|
|
|||||||
if heredoc_end and line =~ /^\s*#{heredoc_end}/
|
if heredoc_end and line =~ /^\s*#{heredoc_end}/
|
||||||
heredoc_end = nil
|
heredoc_end = nil
|
||||||
end
|
end
|
||||||
if heredoc_end or not (line =~ /^\s*(#[^!].*)?$/)
|
if line !~ /#\sspecs/
|
||||||
stripped_comments << line
|
if heredoc_end or line !~ /^\s*(#[^!].*)?$/
|
||||||
|
stripped << line
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "zlib"
|
require "zlib"
|
||||||
require "base64"
|
require "base64"
|
||||||
compressed_script = Zlib::Deflate.deflate(stripped_comments.join)
|
compressed_script = Zlib::Deflate.deflate(stripped.join)
|
||||||
encoded_compressed_script = Base64.encode64(compressed_script).gsub("\n", "")
|
encoded_compressed_script = Base64.encode64(compressed_script).gsub("\n", "")
|
||||||
hash = Digest::MD5.hexdigest(encoded_compressed_script)
|
hash = Digest::MD5.hexdigest(encoded_compressed_script)
|
||||||
|
|
||||||
|
@ -55,6 +55,8 @@ describe Rscons do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let(:passenv) {{}}
|
||||||
|
|
||||||
def test_dir(build_test_directory)
|
def test_dir(build_test_directory)
|
||||||
Dir.chdir(@owd)
|
Dir.chdir(@owd)
|
||||||
rm_rf(@build_test_run_dir)
|
rm_rf(@build_test_run_dir)
|
||||||
@ -118,6 +120,7 @@ describe Rscons do
|
|||||||
command_name = "#{command_prefix}#{@statics[:build_test_id]}"
|
command_name = "#{command_prefix}#{@statics[:build_test_id]}"
|
||||||
File.open("_simplecov_setup.rb", "w") do |fh|
|
File.open("_simplecov_setup.rb", "w") do |fh|
|
||||||
fh.puts <<EOF
|
fh.puts <<EOF
|
||||||
|
unless ENV["dist_specs"]
|
||||||
require "bundler"
|
require "bundler"
|
||||||
Bundler.setup
|
Bundler.setup
|
||||||
require "simplecov"
|
require "simplecov"
|
||||||
@ -134,6 +137,7 @@ SimpleCov.start do
|
|||||||
end
|
end
|
||||||
formatter(MyFormatter)
|
formatter(MyFormatter)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
# force color off
|
# force color off
|
||||||
ENV["TERM"] = nil
|
ENV["TERM"] = nil
|
||||||
#{options[:ruby_setup_code]}
|
#{options[:ruby_setup_code]}
|
||||||
@ -143,8 +147,9 @@ EOF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
stdout, stderr, status = nil, nil, nil
|
stdout, stderr, status = nil, nil, nil
|
||||||
Bundler.with_clean_env do
|
Bundler.with_unbundled_env do
|
||||||
env = ENV.to_h
|
env = ENV.to_h
|
||||||
|
env.merge!(passenv)
|
||||||
path = ["#{@build_test_run_dir}/_bin", "#{env["PATH"]}"]
|
path = ["#{@build_test_run_dir}/_bin", "#{env["PATH"]}"]
|
||||||
if options[:path]
|
if options[:path]
|
||||||
path = Array(options[:path]) + path
|
path = Array(options[:path]) + path
|
||||||
@ -187,6 +192,10 @@ EOF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def nr(str)
|
||||||
|
str.gsub("\r", "")
|
||||||
|
end
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
# Tests
|
# Tests
|
||||||
###########################################################################
|
###########################################################################
|
||||||
@ -195,8 +204,8 @@ EOF
|
|||||||
test_dir('simple')
|
test_dir('simple')
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?('build/e.1/simple.o')).to be_truthy
|
expect(File.exists?('build/e.1/simple.c.o')).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows specifying a Builder object as the source to another build target" do
|
it "allows specifying a Builder object as the source to another build target" do
|
||||||
@ -204,7 +213,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "builder_as_source.rb")
|
result = run_rscons(rsconscript: "builder_as_source.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("simple.o")).to be_truthy
|
expect(File.exists?("simple.o")).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'prints commands as they are executed' do
|
it 'prints commands as they are executed' do
|
||||||
@ -212,8 +221,8 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "command.rb")
|
result = run_rscons(rsconscript: "command.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/simple.o -MMD -MF build/e.1/simple.mf simple.c},
|
%r{gcc -c -o build/e.1/simple.c.o -MMD -MF build/e.1/simple.c.o.mf simple.c},
|
||||||
%r{gcc -o simple.exe build/e.1/simple.o},
|
%r{gcc -o simple.exe build/e.1/simple.c.o},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -231,19 +240,19 @@ EOF
|
|||||||
test_dir('header')
|
test_dir('header')
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?('build/e.1/header.o')).to be_truthy
|
expect(File.exists?('build/e.1/header.c.o')).to be_truthy
|
||||||
expect(`./header.exe`).to eq "The value is 2\n"
|
expect(nr(`./header.exe`)).to eq "The value is 2\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'rebuilds a C module when a header it depends on changes' do
|
it 'rebuilds a C module when a header it depends on changes' do
|
||||||
test_dir('header')
|
test_dir('header')
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(`./header.exe`).to eq "The value is 2\n"
|
expect(nr(`./header.exe`)).to eq "The value is 2\n"
|
||||||
file_sub('header.h') {|line| line.sub(/2/, '5')}
|
file_sub('header.h') {|line| line.sub(/2/, '5')}
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(`./header.exe`).to eq "The value is 5\n"
|
expect(nr(`./header.exe`)).to eq "The value is 5\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not rebuild a C module when its dependencies have not changed' do
|
it 'does not rebuild a C module when its dependencies have not changed' do
|
||||||
@ -254,7 +263,7 @@ EOF
|
|||||||
%r{Compiling header.c},
|
%r{Compiling header.c},
|
||||||
%r{Linking header.exe},
|
%r{Linking header.exe},
|
||||||
])
|
])
|
||||||
expect(`./header.exe`).to eq "The value is 2\n"
|
expect(nr(`./header.exe`)).to eq "The value is 2\n"
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.stdout).to eq ""
|
expect(result.stdout).to eq ""
|
||||||
@ -268,7 +277,7 @@ EOF
|
|||||||
%r{Compiling header.c},
|
%r{Compiling header.c},
|
||||||
%r{Linking header.exe},
|
%r{Linking header.exe},
|
||||||
])
|
])
|
||||||
expect(`./header.exe`).to eq "The value is 2\n"
|
expect(nr(`./header.exe`)).to eq "The value is 2\n"
|
||||||
sleep 0.05
|
sleep 0.05
|
||||||
file_sub('header.c') {|line| line}
|
file_sub('header.c') {|line| line}
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
@ -281,13 +290,13 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "command.rb")
|
result = run_rscons(rsconscript: "command.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/simple.o -MMD -MF build/e.1/simple.mf simple.c},
|
%r{gcc -c -o build/e.1/simple.c.o -MMD -MF build/e.1/simple.c.o.mf simple.c},
|
||||||
%r{gcc -o simple.exe build/e.1/simple.o},
|
%r{gcc -o simple.exe build/e.1/simple.c.o},
|
||||||
])
|
])
|
||||||
result = run_rscons(rsconscript: "link_flag_change.rb")
|
result = run_rscons(rsconscript: "link_flag_change.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -o simple.exe build/e.1/simple.o -Llibdir},
|
%r{gcc -o simple.exe build/e.1/simple.c.o -Llibdir},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -317,9 +326,9 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "carat.rb")
|
result = run_rscons(rsconscript: "carat.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/one.o -MMD -MF build/e.1/one.mf -Isrc -Isrc/one -Isrc/two build/e.1/one.c},
|
%r{gcc -c -o build/e.1/one.o -MMD -MF build/e.1/one.o.mf -Isrc -Isrc/one -Isrc/two build/e.1/one.c},
|
||||||
%r{gcc -c -o build/e.1/src/two/two.o -MMD -MF build/e.1/src/two/two.mf -Isrc -Isrc/one -Isrc/two src/two/two.c},
|
%r{gcc -c -o build/e.1/src/two/two.c.o -MMD -MF build/e.1/src/two/two.c.o.mf -Isrc -Isrc/one -Isrc/two src/two/two.c},
|
||||||
%r{gcc -o program.exe build/e.1/src/two/two.o build/e.1/one.o},
|
%r{gcc -o program.exe build/e.1/src/two/two.c.o build/e.1/one.o},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -328,7 +337,7 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?('foo.yml')).to be_truthy
|
expect(File.exists?('foo.yml')).to be_truthy
|
||||||
expect(IO.read('foo.yml')).to eq("---\nkey: value\n")
|
expect(nr(IO.read('foo.yml'))).to eq("---\nkey: value\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when a side-effect file is registered for a build target that is not registered" do
|
it "raises an error when a side-effect file is registered for a build target that is not registered" do
|
||||||
@ -343,9 +352,9 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(`./simple.exe`).to match /This is a simple C program/
|
expect(`./simple.exe`).to match /This is a simple C program/
|
||||||
expect(File.exists?('build/e.1/simple.o')).to be_truthy
|
expect(File.exists?('build/e.1/simple.c.o')).to be_truthy
|
||||||
result = run_rscons(op: %w[clean])
|
result = run_rscons(op: %w[clean])
|
||||||
expect(File.exists?('build/e.1/simple.o')).to be_falsey
|
expect(File.exists?('build/e.1/simple.c.o')).to be_falsey
|
||||||
expect(File.exists?('build/e.1')).to be_falsey
|
expect(File.exists?('build/e.1')).to be_falsey
|
||||||
expect(File.exists?('simple.exe')).to be_falsey
|
expect(File.exists?('simple.exe')).to be_falsey
|
||||||
expect(File.exists?('simple.c')).to be_truthy
|
expect(File.exists?('simple.c')).to be_truthy
|
||||||
@ -356,7 +365,7 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(`./simple.exe`).to match /This is a simple C program/
|
expect(`./simple.exe`).to match /This is a simple C program/
|
||||||
expect(File.exists?('build/e.1/simple.o')).to be_truthy
|
expect(File.exists?('build/e.1/simple.c.o')).to be_truthy
|
||||||
File.open('build/e.1/dum', 'w') { |fh| fh.puts "dum" }
|
File.open('build/e.1/dum', 'w') { |fh| fh.puts "dum" }
|
||||||
result = run_rscons(op: %w[clean])
|
result = run_rscons(op: %w[clean])
|
||||||
expect(File.exists?('build/e.1')).to be_truthy
|
expect(File.exists?('build/e.1')).to be_truthy
|
||||||
@ -373,12 +382,12 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "install.rb", op: %W[install])
|
result = run_rscons(rsconscript: "install.rb", op: %W[install])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/src/one/one.o")).to be_truthy
|
expect(File.exists?("build/e.1/src/one/one.c.o")).to be_truthy
|
||||||
|
|
||||||
result = run_rscons(rsconscript: "install.rb", op: %W[clean])
|
result = run_rscons(rsconscript: "install.rb", op: %W[clean])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/src/one/one.o")).to be_falsey
|
expect(File.exists?("build/e.1/src/one/one.c.o")).to be_falsey
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -395,7 +404,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "install.rb", op: %W[clean])
|
result = run_rscons(rsconscript: "install.rb", op: %W[clean])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/src/one/one.o")).to be_falsey
|
expect(File.exists?("build/e.1/src/one/one.c.o")).to be_falsey
|
||||||
|
|
||||||
result = run_rscons(rsconscript: "install.rb", op: %W[uninstall -v])
|
result = run_rscons(rsconscript: "install.rb", op: %W[uninstall -v])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
@ -414,7 +423,7 @@ EOF
|
|||||||
%r{Linking program.exe},
|
%r{Linking program.exe},
|
||||||
])
|
])
|
||||||
expect(File.exists?('inc.h')).to be_truthy
|
expect(File.exists?('inc.h')).to be_truthy
|
||||||
expect(`./program.exe`).to eq "The value is 5678\n"
|
expect(nr(`./program.exe`)).to eq "The value is 5678\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'supports custom builders with multiple targets' do
|
it 'supports custom builders with multiple targets' do
|
||||||
@ -430,13 +439,13 @@ EOF
|
|||||||
])
|
])
|
||||||
expect(File.exists?("inc.c")).to be_truthy
|
expect(File.exists?("inc.c")).to be_truthy
|
||||||
expect(File.exists?("inc.h")).to be_truthy
|
expect(File.exists?("inc.h")).to be_truthy
|
||||||
expect(`./program.exe`).to eq "The value is 42\n"
|
expect(nr(`./program.exe`)).to eq "The value is 42\n"
|
||||||
|
|
||||||
File.open("inc.c", "w") {|fh| fh.puts "int THE_VALUE = 33;"}
|
File.open("inc.c", "w") {|fh| fh.puts "int THE_VALUE = 33;"}
|
||||||
result = run_rscons(rsconscript: "multiple_targets.rb")
|
result = run_rscons(rsconscript: "multiple_targets.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [%r{CHGen inc.c}])
|
verify_lines(lines(result.stdout), [%r{CHGen inc.c}])
|
||||||
expect(`./program.exe`).to eq "The value is 42\n"
|
expect(nr(`./program.exe`)).to eq "The value is 42\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an error when a custom builder returns an invalid value from #run' do
|
it 'raises an error when a custom builder returns an invalid value from #run' do
|
||||||
@ -477,10 +486,10 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/src/program.o -MMD -MF build/e.1/src/program.mf '-DSTRING="Debug Version"' -O2 src/program.c},
|
%r{gcc -c -o build/e.1/src/program.c.o -MMD -MF build/e.1/src/program.c.o.mf '-DSTRING="Debug Version"' -O2 src/program.c},
|
||||||
%r{gcc -o program-debug.exe build/e.1/src/program.o},
|
%r{gcc -o program-debug.exe build/e.1/src/program.c.o},
|
||||||
%r{gcc -c -o build/e.2/src/program.o -MMD -MF build/e.2/src/program.mf '-DSTRING="Release Version"' -O2 src/program.c},
|
%r{gcc -c -o build/e.2/src/program.c.o -MMD -MF build/e.2/src/program.c.o.mf '-DSTRING="Release Version"' -O2 src/program.c},
|
||||||
%r{gcc -o program-release.exe build/e.2/src/program.o},
|
%r{gcc -o program-release.exe build/e.2/src/program.c.o},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -489,12 +498,12 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "clone_all.rb")
|
result = run_rscons(rsconscript: "clone_all.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/src/program.o -MMD -MF build/e.1/src/program.mf -DSTRING="Hello" -O2 src/program.c},
|
%r{gcc -c -o build/e.1/src/program.c.o -MMD -MF build/e.1/src/program.c.o.mf -DSTRING="Hello" -O2 src/program.c},
|
||||||
%r{post build/e.1/src/program.o},
|
%r{post build/e.1/src/program.c.o},
|
||||||
%r{gcc -o program.exe build/e.1/src/program.o},
|
%r{gcc -o program.exe build/e.1/src/program.c.o},
|
||||||
%r{post program.exe},
|
%r{post program.exe},
|
||||||
%r{post build/e.2/src/program.o},
|
%r{post build/e.2/src/program.c.o},
|
||||||
%r{gcc -o program2.exe build/e.2/src/program.o},
|
%r{gcc -o program2.exe build/e.2/src/program.c.o},
|
||||||
%r{post program2.exe},
|
%r{post program2.exe},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
@ -503,8 +512,8 @@ EOF
|
|||||||
test_dir('simple_cc')
|
test_dir('simple_cc')
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?('build/e.1/simple.o')).to be_truthy
|
expect(File.exists?('build/e.1/simple.cc.o')).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C++ program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C++ program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "links with the C++ linker when object files were built from C++ sources" do
|
it "links with the C++ linker when object files were built from C++ sources" do
|
||||||
@ -512,7 +521,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "link_objects.rb")
|
result = run_rscons(rsconscript: "link_objects.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("simple.o")).to be_truthy
|
expect(File.exists?("simple.o")).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C++ program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C++ program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'allows overriding construction variables for individual builder calls' do
|
it 'allows overriding construction variables for individual builder calls' do
|
||||||
@ -520,12 +529,12 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o one.o -MMD -MF one.mf -DONE one.c},
|
%r{gcc -c -o one.o -MMD -MF build/e.1/one.o.mf -DONE one.c},
|
||||||
%r{gcc -c -o build/e.1/two.o -MMD -MF build/e.1/two.mf two.c},
|
%r{gcc -c -o build/e.1/two.c.o -MMD -MF build/e.1/two.c.o.mf two.c},
|
||||||
%r{gcc -o two_sources.exe one.o build/e.1/two.o},
|
%r{gcc -o two_sources.exe one.o build/e.1/two.c.o},
|
||||||
])
|
])
|
||||||
expect(File.exists?("two_sources.exe")).to be_truthy
|
expect(File.exists?("two_sources.exe")).to be_truthy
|
||||||
expect(`./two_sources.exe`).to eq "This is a C program with two sources.\n"
|
expect(nr(`./two_sources.exe`)).to eq "This is a C program with two sources.\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'builds a static library archive' do
|
it 'builds a static library archive' do
|
||||||
@ -533,14 +542,14 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/one.o -MMD -MF build/e.1/one.mf -Dmake_lib one.c},
|
%r{gcc -c -o build/e.1/one.c.o -MMD -MF build/e.1/one.c.o.mf -Dmake_lib one.c},
|
||||||
%r{gcc -c -o build/e.1/two.o -MMD -MF build/e.1/two.mf -Dmake_lib two.c},
|
%r{gcc -c -o build/e.1/two.c.o -MMD -MF build/e.1/two.c.o.mf -Dmake_lib two.c},
|
||||||
%r{ar rcs lib.a build/e.1/one.o build/e.1/two.o},
|
%r{ar rcs lib.a build/e.1/one.c.o build/e.1/two.c.o},
|
||||||
%r{gcc -c -o build/e.1/three.o -MMD -MF build/e.1/three.mf three.c},
|
%r{gcc -c -o build/e.1/three.c.o -MMD -MF build/e.1/three.c.o.mf three.c},
|
||||||
%r{gcc -o library.exe lib.a build/e.1/three.o},
|
%r{gcc -o library.exe lib.a build/e.1/three.c.o},
|
||||||
])
|
])
|
||||||
expect(File.exists?("library.exe")).to be_truthy
|
expect(File.exists?("library.exe")).to be_truthy
|
||||||
expect(`ar t lib.a`).to eq "one.o\ntwo.o\n"
|
expect(nr(`ar t lib.a`)).to eq "one.c.o\ntwo.c.o\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'supports build hooks to override construction variables' do
|
it 'supports build hooks to override construction variables' do
|
||||||
@ -548,11 +557,11 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "build_hooks.rb")
|
result = run_rscons(rsconscript: "build_hooks.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o build/e.1/src/one/one.o -MMD -MF build/e.1/src/one/one.mf -Isrc/one -Isrc/two -O1 src/one/one.c},
|
%r{gcc -c -o build/e.1/src/one/one.c.o -MMD -MF build/e.1/src/one/one.c.o.mf -Isrc/one -Isrc/two -O1 src/one/one.c},
|
||||||
%r{gcc -c -o build/e.1/src/two/two.o -MMD -MF build/e.1/src/two/two.mf -Isrc/one -Isrc/two -O2 src/two/two.c},
|
%r{gcc -c -o build/e.1/src/two/two.c.o -MMD -MF build/e.1/src/two/two.c.o.mf -Isrc/one -Isrc/two -O2 src/two/two.c},
|
||||||
%r{gcc -o build_hook.exe build/e.1/src/one/one.o build/e.1/src/two/two.o},
|
%r{gcc -o build_hook.exe build/e.1/src/one/one.c.o build/e.1/src/two/two.c.o},
|
||||||
])
|
])
|
||||||
expect(`./build_hook.exe`).to eq "Hello from two()\n"
|
expect(nr(`./build_hook.exe`)).to eq "Hello from two()\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'supports build hooks to override the entire vars hash' do
|
it 'supports build hooks to override the entire vars hash' do
|
||||||
@ -560,8 +569,8 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "build_hooks_override_vars.rb")
|
result = run_rscons(rsconscript: "build_hooks_override_vars.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o one.o -MMD -MF one.mf -Isrc -Isrc/one -Isrc/two -O1 src/two/two.c},
|
%r{gcc -c -o one.o -MMD -MF build/e.1/one.o.mf -Isrc -Isrc/one -Isrc/two -O1 src/two/two.c},
|
||||||
%r{gcc -c -o two.o -MMD -MF two.mf -Isrc -Isrc/one -Isrc/two -O2 src/two/two.c},
|
%r{gcc -c -o two.o -MMD -MF build/e.1/two.o.mf -Isrc -Isrc/one -Isrc/two -O2 src/two/two.c},
|
||||||
])
|
])
|
||||||
expect(File.exists?('one.o')).to be_truthy
|
expect(File.exists?('one.o')).to be_truthy
|
||||||
expect(File.exists?('two.o')).to be_truthy
|
expect(File.exists?('two.o')).to be_truthy
|
||||||
@ -577,8 +586,8 @@ EOF
|
|||||||
%r{Compiling simple.c},
|
%r{Compiling simple.c},
|
||||||
%r{Linking simple.exe},
|
%r{Linking simple.exe},
|
||||||
])
|
])
|
||||||
expect(File.exists?('build/e.1/simple.o')).to be_truthy
|
expect(File.exists?('build/e.1/simple.c.o')).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
|
|
||||||
File.open("program.ld", "w") {|fh| fh.puts("2")}
|
File.open("program.ld", "w") {|fh| fh.puts("2")}
|
||||||
result = run_rscons(rsconscript: "user_dependencies.rb")
|
result = run_rscons(rsconscript: "user_dependencies.rb")
|
||||||
@ -595,25 +604,48 @@ EOF
|
|||||||
expect(result.stdout).to eq ""
|
expect(result.stdout).to eq ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "rebuilds when user-specified dependencies using ^ change" do
|
||||||
|
test_dir("simple")
|
||||||
|
|
||||||
|
passenv["file_contents"] = "1"
|
||||||
|
result = run_rscons(rsconscript: "user_dependencies_carat.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{Compiling simple.c},
|
||||||
|
%r{Linking .*simple.exe},
|
||||||
|
])
|
||||||
|
|
||||||
|
passenv["file_contents"] = "2"
|
||||||
|
result = run_rscons(rsconscript: "user_dependencies_carat.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [%r{Linking .*simple.exe}])
|
||||||
|
|
||||||
|
result = run_rscons(rsconscript: "user_dependencies_carat.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to eq ""
|
||||||
|
end
|
||||||
|
|
||||||
|
unless RUBY_PLATFORM =~ /mingw|msys/
|
||||||
it "supports building D sources with gdc" do
|
it "supports building D sources with gdc" do
|
||||||
test_dir("d")
|
test_dir("d")
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{gdc -c -o build/e.1/main.o -MMD -MF build/e.1/main.mf main.d}])
|
verify_lines(slines, [%r{gdc -c -o build/e.1/main.d.o -MMD -MF build/e.1/main.d.o.mf main.d}])
|
||||||
verify_lines(slines, [%r{gdc -c -o build/e.1/mod.o -MMD -MF build/e.1/mod.mf mod.d}])
|
verify_lines(slines, [%r{gdc -c -o build/e.1/mod.d.o -MMD -MF build/e.1/mod.d.o.mf mod.d}])
|
||||||
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.o build/e.1/mod.o}])
|
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.d.o build/e.1/mod.d.o}])
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "supports building D sources with ldc2" do
|
it "supports building D sources with ldc2" do
|
||||||
test_dir("d")
|
test_dir("d")
|
||||||
result = run_rscons(rsconscript: "build-ldc2.rb")
|
result = run_rscons(rsconscript: "build-ldc2.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.o(bj)? -deps=build/e.1/main.mf main.d}])
|
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.d.o(bj)? -deps=build/e.1/main.d.o(bj)?.mf main.d}])
|
||||||
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.o(bj)? -deps=build/e.1/mod.mf mod.d}])
|
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.d.o(bj)? -deps=build/e.1/mod.d.o(bj)?.mf mod.d}])
|
||||||
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.o(bj)? build/e.1/mod.o(bj)?}])
|
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.d.o(bj)? build/e.1/mod.d.o(bj)?}])
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -622,9 +654,9 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "build-ldc2.rb")
|
result = run_rscons(rsconscript: "build-ldc2.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.o(bj)? -deps=build/e.1/main.mf main.d}])
|
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.d.o(bj)? -deps=build/e.1/main.d.o(bj)?.mf main.d}])
|
||||||
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.o(bj)? -deps=build/e.1/mod.mf mod.d}])
|
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.d.o(bj)? -deps=build/e.1/mod.d.o(bj)?.mf mod.d}])
|
||||||
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.o(bj)? build/e.1/mod.o(bj)?}])
|
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.d.o(bj)? build/e.1/mod.d.o(bj)?}])
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
||||||
contents = File.read("mod.d", mode: "rb").sub("42", "33")
|
contents = File.read("mod.d", mode: "rb").sub("42", "33")
|
||||||
File.open("mod.d", "wb") do |fh|
|
File.open("mod.d", "wb") do |fh|
|
||||||
@ -633,13 +665,13 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "build-ldc2.rb")
|
result = run_rscons(rsconscript: "build-ldc2.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.o(bj)? -deps=build/e.1/main.mf main.d}])
|
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.d.o(bj)? -deps=build/e.1/main.d.o(bj)?.mf main.d}])
|
||||||
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.o(bj)? -deps=build/e.1/mod.mf mod.d}])
|
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.d.o(bj)? -deps=build/e.1/mod.d.o(bj)?.mf mod.d}])
|
||||||
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.o(bj)? build/e.1/mod.o(bj)?}])
|
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.d.o(bj)? build/e.1/mod.d.o(bj)?}])
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 33!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 33!"
|
||||||
end
|
end
|
||||||
|
|
||||||
unless ENV["omit_gdc_tests"]
|
unless RUBY_PLATFORM =~ /mingw|msys/
|
||||||
it "links with the D linker when object files were built from D sources" do
|
it "links with the D linker when object files were built from D sources" do
|
||||||
test_dir("d")
|
test_dir("d")
|
||||||
result = run_rscons(rsconscript: "link_objects.rb")
|
result = run_rscons(rsconscript: "link_objects.rb")
|
||||||
@ -654,18 +686,18 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{gdc -c -o build/e.1/main.o -MMD -MF build/e.1/main.mf main.d}])
|
verify_lines(slines, [%r{gdc -c -o build/e.1/main.d.o -MMD -MF build/e.1/main.d.o.mf main.d}])
|
||||||
verify_lines(slines, [%r{gdc -c -o build/e.1/mod.o -MMD -MF build/e.1/mod.mf mod.d}])
|
verify_lines(slines, [%r{gdc -c -o build/e.1/mod.d.o -MMD -MF build/e.1/mod.d.o.mf mod.d}])
|
||||||
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.o build/e.1/mod.o}])
|
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.d.o build/e.1/mod.d.o}])
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
||||||
fcontents = File.read("mod.d", mode: "rb").sub("42", "33")
|
fcontents = File.read("mod.d", mode: "rb").sub("42", "33")
|
||||||
File.open("mod.d", "wb") {|fh| fh.write(fcontents)}
|
File.open("mod.d", "wb") {|fh| fh.write(fcontents)}
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{gdc -c -o build/e.1/main.o -MMD -MF build/e.1/main.mf main.d}])
|
verify_lines(slines, [%r{gdc -c -o build/e.1/main.d.o -MMD -MF build/e.1/main.d.o.mf main.d}])
|
||||||
verify_lines(slines, [%r{gdc -c -o build/e.1/mod.o -MMD -MF build/e.1/mod.mf mod.d}])
|
verify_lines(slines, [%r{gdc -c -o build/e.1/mod.d.o -MMD -MF build/e.1/mod.d.o.mf mod.d}])
|
||||||
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.o build/e.1/mod.o}])
|
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.d.o build/e.1/mod.d.o}])
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 33!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 33!"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -675,7 +707,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "shared_library_d.rb")
|
result = run_rscons(rsconscript: "shared_library_d.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
if RUBY_PLATFORM =~ /mingw|msys/
|
||||||
verify_lines(slines, [%r{Linking mine.dll}])
|
verify_lines(slines, [%r{Linking mine.dll}])
|
||||||
else
|
else
|
||||||
verify_lines(slines, [%r{Linking libmine.so}])
|
verify_lines(slines, [%r{Linking libmine.so}])
|
||||||
@ -701,7 +733,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "preprocess.rb")
|
result = run_rscons(rsconscript: "preprocess.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.read("simplepp.c")).to match /# \d+ "simple.c"/
|
expect(File.read("simplepp.c")).to match /# \d+ "simple.c"/
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports preprocessing C++ sources" do
|
it "supports preprocessing C++ sources" do
|
||||||
@ -709,7 +741,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "preprocess.rb")
|
result = run_rscons(rsconscript: "preprocess.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.read("simplepp.cc")).to match /# \d+ "simple.cc"/
|
expect(File.read("simplepp.cc")).to match /# \d+ "simple.cc"/
|
||||||
expect(`./simple.exe`).to eq "This is a simple C++ program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C++ program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports invoking builders with no sources" do
|
it "supports invoking builders with no sources" do
|
||||||
@ -727,23 +759,23 @@ EOF
|
|||||||
%r{Linking program.exe},
|
%r{Linking program.exe},
|
||||||
])
|
])
|
||||||
expect(File.exists?('inc.h')).to be_truthy
|
expect(File.exists?('inc.h')).to be_truthy
|
||||||
expect(`./program.exe`).to eq "The value is 678\n"
|
expect(nr(`./program.exe`)).to eq "The value is 678\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports lambdas as construction variable values" do
|
it "supports lambdas as construction variable values" do
|
||||||
test_dir "custom_builder"
|
test_dir "custom_builder"
|
||||||
result = run_rscons(rsconscript: "cvar_lambda.rb")
|
result = run_rscons(rsconscript: "cvar_lambda.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(`./program.exe`).to eq "The value is 5678\n"
|
expect(nr(`./program.exe`)).to eq "The value is 5678\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports registering build targets from within a build hook" do
|
it "supports registering build targets from within a build hook" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
result = run_rscons(rsconscript: "register_target_in_build_hook.rb")
|
result = run_rscons(rsconscript: "register_target_in_build_hook.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("build/e.1/simple.o")).to be_truthy
|
expect(File.exists?("build/e.1/simple.c.o")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/simple.o.txt")).to be_truthy
|
expect(File.exists?("build/e.1/simple.c.o.txt")).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports multiple values for CXXSUFFIX" do
|
it "supports multiple values for CXXSUFFIX" do
|
||||||
@ -751,9 +783,9 @@ EOF
|
|||||||
File.open("other.cccc", "w") {|fh| fh.puts}
|
File.open("other.cccc", "w") {|fh| fh.puts}
|
||||||
result = run_rscons(rsconscript: "cxxsuffix.rb")
|
result = run_rscons(rsconscript: "cxxsuffix.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("build/e.1/simple.o")).to be_truthy
|
expect(File.exists?("build/e.1/simple.cc.o")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/other.o")).to be_truthy
|
expect(File.exists?("build/e.1/other.cccc.o")).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C++ program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C++ program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports multiple values for CSUFFIX" do
|
it "supports multiple values for CSUFFIX" do
|
||||||
@ -761,9 +793,9 @@ EOF
|
|||||||
FileUtils.mv("src/one/one.c", "src/one/one.yargh")
|
FileUtils.mv("src/one/one.c", "src/one/one.yargh")
|
||||||
result = run_rscons(rsconscript: "csuffix.rb")
|
result = run_rscons(rsconscript: "csuffix.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("build/e.1/src/one/one.o")).to be_truthy
|
expect(File.exists?("build/e.1/src/one/one.yargh.o")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/src/two/two.o")).to be_truthy
|
expect(File.exists?("build/e.1/src/two/two.c.o")).to be_truthy
|
||||||
expect(`./program.exe`).to eq "Hello from two()\n"
|
expect(nr(`./program.exe`)).to eq "Hello from two()\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports multiple values for OBJSUFFIX" do
|
it "supports multiple values for OBJSUFFIX" do
|
||||||
@ -773,7 +805,7 @@ EOF
|
|||||||
expect(File.exists?("two_sources.exe")).to be_truthy
|
expect(File.exists?("two_sources.exe")).to be_truthy
|
||||||
expect(File.exists?("one.oooo")).to be_truthy
|
expect(File.exists?("one.oooo")).to be_truthy
|
||||||
expect(File.exists?("two.ooo")).to be_truthy
|
expect(File.exists?("two.ooo")).to be_truthy
|
||||||
expect(`./two_sources.exe`).to eq "This is a C program with two sources.\n"
|
expect(nr(`./two_sources.exe`)).to eq "This is a C program with two sources.\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports multiple values for LIBSUFFIX" do
|
it "supports multiple values for LIBSUFFIX" do
|
||||||
@ -781,7 +813,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "libsuffix.rb")
|
result = run_rscons(rsconscript: "libsuffix.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("two_sources.exe")).to be_truthy
|
expect(File.exists?("two_sources.exe")).to be_truthy
|
||||||
expect(`./two_sources.exe`).to eq "This is a C program with two sources.\n"
|
expect(nr(`./two_sources.exe`)).to eq "This is a C program with two sources.\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports multiple values for ASSUFFIX" do
|
it "supports multiple values for ASSUFFIX" do
|
||||||
@ -796,7 +828,7 @@ EOF
|
|||||||
%r{Linking two_sources.exe},
|
%r{Linking two_sources.exe},
|
||||||
])
|
])
|
||||||
expect(File.exists?("two_sources.exe")).to be_truthy
|
expect(File.exists?("two_sources.exe")).to be_truthy
|
||||||
expect(`./two_sources.exe`).to eq "This is a C program with two sources.\n"
|
expect(nr(`./two_sources.exe`)).to eq "This is a C program with two sources.\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports dumping an Environment's construction variables" do
|
it "supports dumping an Environment's construction variables" do
|
||||||
@ -834,8 +866,8 @@ EOF
|
|||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
result = run_rscons(rsconscript: "cvar_array.rb")
|
result = run_rscons(rsconscript: "cvar_array.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("build/e.1/simple.o")).to be_truthy
|
expect(File.exists?("build/e.1/simple.c.o")).to be_truthy
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "supports registering multiple build targets with the same target path" do
|
it "supports registering multiple build targets with the same target path" do
|
||||||
@ -916,7 +948,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "absolute_source_path.rb")
|
result = run_rscons(rsconscript: "absolute_source_path.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
verify_lines(slines, [%r{build/e.1/.*/abs\.o$}])
|
verify_lines(slines, [%r{build/e.1/.*/abs\.c.o$}])
|
||||||
verify_lines(slines, [%r{\babs.exe\b}])
|
verify_lines(slines, [%r{\babs.exe\b}])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -926,7 +958,7 @@ EOF
|
|||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
if RUBY_PLATFORM =~ /mingw|msys/
|
||||||
verify_lines(slines, [%r{Linking mine.dll}])
|
verify_lines(slines, [%r{Linking mine.dll}])
|
||||||
expect(File.exists?("mine.dll")).to be_truthy
|
expect(File.exists?("mine.dll")).to be_truthy
|
||||||
else
|
else
|
||||||
@ -938,7 +970,7 @@ EOF
|
|||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.stdout).to eq ""
|
expect(result.stdout).to eq ""
|
||||||
|
|
||||||
ld_library_path_prefix = (RUBY_PLATFORM =~ /mingw/ ? "" : "LD_LIBRARY_PATH=. ")
|
ld_library_path_prefix = (RUBY_PLATFORM =~ /mingw|msys/ ? "" : "LD_LIBRARY_PATH=. ")
|
||||||
expect(`#{ld_library_path_prefix}./test-shared.exe`).to match /Hi from one/
|
expect(`#{ld_library_path_prefix}./test-shared.exe`).to match /Hi from one/
|
||||||
expect(`./test-static.exe`).to match /Hi from one/
|
expect(`./test-static.exe`).to match /Hi from one/
|
||||||
end
|
end
|
||||||
@ -957,7 +989,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "shared_library_cxx.rb")
|
result = run_rscons(rsconscript: "shared_library_cxx.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
if RUBY_PLATFORM =~ /mingw|msys/
|
||||||
verify_lines(slines, [%r{Linking mine.dll}])
|
verify_lines(slines, [%r{Linking mine.dll}])
|
||||||
else
|
else
|
||||||
verify_lines(slines, [%r{Linking libmine.so}])
|
verify_lines(slines, [%r{Linking libmine.so}])
|
||||||
@ -967,7 +999,7 @@ EOF
|
|||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.stdout).to eq ""
|
expect(result.stdout).to eq ""
|
||||||
|
|
||||||
ld_library_path_prefix = (RUBY_PLATFORM =~ /mingw/ ? "" : "LD_LIBRARY_PATH=. ")
|
ld_library_path_prefix = (RUBY_PLATFORM =~ /mingw|msys/ ? "" : "LD_LIBRARY_PATH=. ")
|
||||||
expect(`#{ld_library_path_prefix}./test-shared.exe`).to match /Hi from one/
|
expect(`#{ld_library_path_prefix}./test-shared.exe`).to match /Hi from one/
|
||||||
expect(`./test-static.exe`).to match /Hi from one/
|
expect(`./test-static.exe`).to match /Hi from one/
|
||||||
end
|
end
|
||||||
@ -1034,7 +1066,7 @@ EOF
|
|||||||
|
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to match /Failed to build/
|
expect(result.stderr).to match /Failed to build/
|
||||||
expect(result.stderr).to match /^Use.*-F.*to view the failed command log/
|
expect(result.stderr).to match %r{^Use .*/rscons(\.rb)? -F.*to view the failed command log}
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
|
|
||||||
result = run_rscons(rscons_args: %w[-F])
|
result = run_rscons(rscons_args: %w[-F])
|
||||||
@ -1098,7 +1130,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "command_builder.rb")
|
result = run_rscons(rsconscript: "command_builder.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [%r{BuildIt simple.exe}])
|
verify_lines(lines(result.stdout), [%r{BuildIt simple.exe}])
|
||||||
expect(`./simple.exe`).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
|
|
||||||
result = run_rscons(rsconscript: "command_builder.rb")
|
result = run_rscons(rsconscript: "command_builder.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
@ -1431,6 +1463,37 @@ EOF
|
|||||||
expect(result.stdout).to eq ""
|
expect(result.stdout).to eq ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "supports building multiple object files from sources with the same pathname and basename" do
|
||||||
|
test_dir "multiple_basename"
|
||||||
|
result = run_rscons
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.status).to eq 0
|
||||||
|
expect(File.exist?("foo.exe")).to be_truthy
|
||||||
|
result = run_rscons
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to eq ""
|
||||||
|
expect(result.status).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows prepending and appending to PATH" do
|
||||||
|
test_dir "simple"
|
||||||
|
result = run_rscons(rsconscript: "pathing.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to match /flex!/
|
||||||
|
expect(result.stdout).to match /foobar!/
|
||||||
|
expect(File.exist?("simple.o")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "writes the dependency file to the build root" do
|
||||||
|
test_dir "simple"
|
||||||
|
result = run_rscons(rsconscript: "distclean.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to match /Compiling simple\.c/
|
||||||
|
expect(File.exist?("simple.o")).to be_truthy
|
||||||
|
expect(File.exist?("simple.o.mf")).to be_falsey
|
||||||
|
expect(File.exist?("build/e.1/simple.o.mf")).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
context "debugging" do
|
context "debugging" do
|
||||||
it "prints a message when the target does not exist" do
|
it "prints a message when the target does not exist" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
@ -1524,7 +1587,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "override_depfilesuffix.rb")
|
result = run_rscons(rsconscript: "override_depfilesuffix.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{gcc -c -o simple.o -MMD -MF simple.deppy simple.c},
|
%r{gcc -c -o simple.o -MMD -MF build/e.1/simple.o.deppy simple.c},
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1548,7 +1611,7 @@ EOF
|
|||||||
test_dir("library")
|
test_dir("library")
|
||||||
result = run_rscons(rsconscript: "override_arcmd.rb")
|
result = run_rscons(rsconscript: "override_arcmd.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [%r{ar rcf lib.a build/e.1/one.o build/e.1/three.o build/e.1/two.o}])
|
verify_lines(lines(result.stdout), [%r{ar rcf lib.a build/e.1/one.c.o build/e.1/three.c.o build/e.1/two.c.o}])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows passing object files as sources" do
|
it "allows passing object files as sources" do
|
||||||
@ -1567,7 +1630,7 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "shared_library_set_shld.rb")
|
result = run_rscons(rsconscript: "shared_library_set_shld.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
slines = lines(result.stdout)
|
slines = lines(result.stdout)
|
||||||
if RUBY_PLATFORM =~ /mingw/
|
if RUBY_PLATFORM =~ /mingw|msys/
|
||||||
verify_lines(slines, [%r{Linking mine.dll}])
|
verify_lines(slines, [%r{Linking mine.dll}])
|
||||||
else
|
else
|
||||||
verify_lines(slines, [%r{Linking libmine.so}])
|
verify_lines(slines, [%r{Linking libmine.so}])
|
||||||
@ -1578,7 +1641,7 @@ EOF
|
|||||||
test_dir "shared_library"
|
test_dir "shared_library"
|
||||||
result = run_rscons(rsconscript: "shared_library_from_object.rb")
|
result = run_rscons(rsconscript: "shared_library_from_object.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("one.o"))
|
expect(File.exists?("one.c.o"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1711,7 +1774,7 @@ EOF
|
|||||||
create_exe "gcc", "exit 1"
|
create_exe "gcc", "exit 1"
|
||||||
create_exe "clang", "exit 1"
|
create_exe "clang", "exit 1"
|
||||||
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for C compiler\.\.\. not found/
|
expect(result.stdout).to match /Checking for C compiler\.\.\. not found/
|
||||||
end
|
end
|
||||||
@ -1754,7 +1817,7 @@ EOF
|
|||||||
create_exe "g++", "exit 1"
|
create_exe "g++", "exit 1"
|
||||||
create_exe "clang++", "exit 1"
|
create_exe "clang++", "exit 1"
|
||||||
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. not found/
|
expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. not found/
|
||||||
end
|
end
|
||||||
@ -1775,6 +1838,7 @@ EOF
|
|||||||
{"check_d_compiler.rb" => "when no arguments are given",
|
{"check_d_compiler.rb" => "when no arguments are given",
|
||||||
"check_d_compiler_find_first.rb" => "when arguments are given"}.each_pair do |rsconscript, desc|
|
"check_d_compiler_find_first.rb" => "when arguments are given"}.each_pair do |rsconscript, desc|
|
||||||
context desc do
|
context desc do
|
||||||
|
unless RUBY_PLATFORM =~ /mingw|msys/
|
||||||
it "finds the first listed D compiler" do
|
it "finds the first listed D compiler" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
||||||
@ -1782,6 +1846,7 @@ EOF
|
|||||||
expect(result.status).to eq 0
|
expect(result.status).to eq 0
|
||||||
expect(result.stdout).to match /Checking for D compiler\.\.\. gdc/
|
expect(result.stdout).to match /Checking for D compiler\.\.\. gdc/
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "finds the second listed D compiler" do
|
it "finds the second listed D compiler" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
@ -1797,13 +1862,14 @@ EOF
|
|||||||
create_exe "gdc", "exit 1"
|
create_exe "gdc", "exit 1"
|
||||||
create_exe "ldc2", "exit 1"
|
create_exe "ldc2", "exit 1"
|
||||||
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
result = run_rscons(rsconscript: rsconscript, op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for D compiler\.\.\. not found/
|
expect(result.stdout).to match /Checking for D compiler\.\.\. not found/
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless RUBY_PLATFORM =~ /mingw|msys/
|
||||||
it "successfully tests a compiler with an unknown name that uses gdc-compatible options" do
|
it "successfully tests a compiler with an unknown name that uses gdc-compatible options" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
create_exe "mycompiler", %[exec gdc "$@"]
|
create_exe "mycompiler", %[exec gdc "$@"]
|
||||||
@ -1812,6 +1878,7 @@ EOF
|
|||||||
expect(result.status).to eq 0
|
expect(result.status).to eq 0
|
||||||
expect(result.stdout).to match /Checking for D compiler\.\.\. mycompiler/
|
expect(result.stdout).to match /Checking for D compiler\.\.\. mycompiler/
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "successfully tests a compiler with an unknown name that uses ldc2-compatible options" do
|
it "successfully tests a compiler with an unknown name that uses ldc2-compatible options" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
@ -1835,7 +1902,7 @@ EOF
|
|||||||
it "fails when the requested header is not found" do
|
it "fails when the requested header is not found" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "check_c_header_failure.rb", op: "configure")
|
result = run_rscons(rsconscript: "check_c_header_failure.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for C header 'not___found\.h'... not found/
|
expect(result.stdout).to match /Checking for C header 'not___found\.h'... not found/
|
||||||
end
|
end
|
||||||
@ -1900,7 +1967,7 @@ EOF
|
|||||||
it "fails when the requested header is not found" do
|
it "fails when the requested header is not found" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "check_cxx_header_failure.rb", op: "configure")
|
result = run_rscons(rsconscript: "check_cxx_header_failure.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for C\+\+ header 'not___found\.h'... not found/
|
expect(result.stdout).to match /Checking for C\+\+ header 'not___found\.h'... not found/
|
||||||
end
|
end
|
||||||
@ -1941,7 +2008,7 @@ EOF
|
|||||||
it "fails when the requested import is not found" do
|
it "fails when the requested import is not found" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "check_d_import_failure.rb", op: "configure")
|
result = run_rscons(rsconscript: "check_d_import_failure.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for D import 'not\.found'... not found/
|
expect(result.stdout).to match /Checking for D import 'not\.found'... not found/
|
||||||
end
|
end
|
||||||
@ -1982,7 +2049,7 @@ EOF
|
|||||||
it "fails when the requested library is not found" do
|
it "fails when the requested library is not found" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "check_lib_failure.rb", op: "configure")
|
result = run_rscons(rsconscript: "check_lib_failure.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for library 'mfoofoo'... not found/
|
expect(result.stdout).to match /Checking for library 'mfoofoo'... not found/
|
||||||
end
|
end
|
||||||
@ -2063,7 +2130,7 @@ EOF
|
|||||||
it "fails when the requested program is not found" do
|
it "fails when the requested program is not found" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "check_program_failure.rb", op: "configure")
|
result = run_rscons(rsconscript: "check_program_failure.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking for program 'program-that-is-not-found'... not found/
|
expect(result.stdout).to match /Checking for program 'program-that-is-not-found'... not found/
|
||||||
end
|
end
|
||||||
@ -2095,7 +2162,7 @@ EOF
|
|||||||
it "fails when the configure program given does not exist" do
|
it "fails when the configure program given does not exist" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "check_cfg.rb", op: "configure")
|
result = run_rscons(rsconscript: "check_cfg.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
expect(result.stdout).to match /Checking 'my-config'\.\.\. not found/
|
expect(result.stdout).to match /Checking 'my-config'\.\.\. not found/
|
||||||
end
|
end
|
||||||
@ -2140,7 +2207,7 @@ EOF
|
|||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
create_exe "grep", "exit 4"
|
create_exe "grep", "exit 4"
|
||||||
result = run_rscons(rsconscript: "custom_config_check.rb", op: "configure")
|
result = run_rscons(rsconscript: "custom_config_check.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.stdout).to match /Checking 'grep' version\.\.\. error executing grep/
|
expect(result.stdout).to match /Checking 'grep' version\.\.\. error executing grep/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
end
|
end
|
||||||
@ -2151,7 +2218,7 @@ EOF
|
|||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
create_exe "grep", "echo 'grep (GNU grep) 1.1'"
|
create_exe "grep", "echo 'grep (GNU grep) 1.1'"
|
||||||
result = run_rscons(rsconscript: "custom_config_check.rb", op: "configure")
|
result = run_rscons(rsconscript: "custom_config_check.rb", op: "configure")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to match /Configuration failed/
|
||||||
expect(result.stdout).to match /Checking 'grep' version\.\.\. too old!/
|
expect(result.stdout).to match /Checking 'grep' version\.\.\. too old!/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
end
|
end
|
||||||
@ -2200,6 +2267,16 @@ EOF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "on_fail option" do
|
||||||
|
it "prints on_fail messages and calls on_fail procs on failure" do
|
||||||
|
test_dir "configure"
|
||||||
|
result = run_rscons(rsconscript: "on_fail.rb", op: %w[configure])
|
||||||
|
expect(result.status).to_not eq 0
|
||||||
|
expect(result.stdout).to match /Install the foo123 package/
|
||||||
|
expect(result.stdout).to match /Install the foo123cxx package/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "does everything" do
|
it "does everything" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
create_exe "pkg-config", "echo '-DMYPACKAGE'"
|
create_exe "pkg-config", "echo '-DMYPACKAGE'"
|
||||||
@ -2238,11 +2315,13 @@ EOF
|
|||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
it "exits with an error if configuration fails during autoconf" do
|
it "exits with an error code and message if configuration fails during autoconf" do
|
||||||
test_dir "configure"
|
test_dir "configure"
|
||||||
result = run_rscons(rsconscript: "autoconf_fail.rb")
|
result = run_rscons(rsconscript: "autoconf_fail.rb")
|
||||||
expect(result.stdout).to match /Checking for C compiler\.\.\. not found/
|
expect(result.stdout).to match /Checking for C compiler\.\.\. not found/
|
||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
|
expect(result.stderr).to_not match /from\s/
|
||||||
|
expect(lines(result.stderr).last).to eq "Configuration failed"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "exits with an error if configuration has not been performed before attempting to create an environment" do
|
it "exits with an error if configuration has not been performed before attempting to create an environment" do
|
||||||
@ -2351,7 +2430,7 @@ EOF
|
|||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.stdout).to match %r{Compiling/Linking}
|
expect(result.stdout).to match %r{Compiling/Linking}
|
||||||
expect(File.exists?("test.exe")).to be_truthy
|
expect(File.exists?("test.exe")).to be_truthy
|
||||||
ld_library_path_prefix = (RUBY_PLATFORM =~ /mingw/ ? "" : "LD_LIBRARY_PATH=. ")
|
ld_library_path_prefix = (RUBY_PLATFORM =~ /mingw|msys/ ? "" : "LD_LIBRARY_PATH=. ")
|
||||||
expect(`#{ld_library_path_prefix}./test.exe`).to match /three/
|
expect(`#{ld_library_path_prefix}./test.exe`).to match /three/
|
||||||
|
|
||||||
result = run_rscons(rsconscript: "c_shared_library.rb")
|
result = run_rscons(rsconscript: "c_shared_library.rb")
|
||||||
@ -2446,13 +2525,13 @@ EOF
|
|||||||
result = run_rscons(rsconscript: "install.rb", op: %W[install])
|
result = run_rscons(rsconscript: "install.rb", op: %W[install])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
expect(File.exists?("#{prefix}/bin/program.exe")).to be_truthy
|
||||||
expect(File.exists?("build/e.1/src/one/one.o")).to be_truthy
|
expect(File.exists?("build/e.1/src/one/one.c.o")).to be_truthy
|
||||||
|
|
||||||
result = run_rscons(rsconscript: "install.rb", op: %W[uninstall])
|
result = run_rscons(rsconscript: "install.rb", op: %W[uninstall])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.stdout).to_not match /Removing/
|
expect(result.stdout).to_not match /Removing/
|
||||||
expect(File.exists?("#{prefix}/bin/program.exe")).to be_falsey
|
expect(File.exists?("#{prefix}/bin/program.exe")).to be_falsey
|
||||||
expect(File.exists?("build/e.1/src/one/one.o")).to be_truthy
|
expect(File.exists?("build/e.1/src/one/one.c.o")).to be_truthy
|
||||||
expect(Dir.entries(prefix)).to match_array %w[. ..]
|
expect(Dir.entries(prefix)).to match_array %w[. ..]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2546,4 +2625,123 @@ EOF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with subsidiary scripts" do
|
||||||
|
context "with a script specified" do
|
||||||
|
it "executes the subsidiary script from configure block" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
result = run_rscons(op: %W[configure])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub Rsconscript configure},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub Rsconscript build},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub Rsconscript2 configure},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{top configure},
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "executes the subsidiary script from build block" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
result = run_rscons(op: %W[configure])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
result = run_rscons(op: %W[build])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{sub Rsconscript2 build},
|
||||||
|
%r{top build},
|
||||||
|
])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with a directory specified" do
|
||||||
|
it "executes the subsidiary script from configure block" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
result = run_rscons(rsconscript: "Rsconscript_dir", op: %W[configure])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub Rsconscript configure},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub Rsconscript build},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub Rsconscript2 configure},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{top configure},
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "executes the subsidiary script from build block" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
result = run_rscons(rsconscript: "Rsconscript_dir", op: %W[configure])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
result = run_rscons(rsconscript: "Rsconscript_dir", op: %W[build])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{sub Rsconscript2 build},
|
||||||
|
%r{top build},
|
||||||
|
])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with a rscons binary in the subsidiary script directory" do
|
||||||
|
it "executes rscons from the subsidiary script directory" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
File.binwrite("sub/rscons", <<EOF)
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
puts "sub rscons"
|
||||||
|
EOF
|
||||||
|
FileUtils.chmod(0755, "sub/rscons")
|
||||||
|
result = run_rscons(op: %W[configure])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub rscons},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub rscons},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{Entering directory '.*/sub'},
|
||||||
|
%r{sub rscons},
|
||||||
|
%r{Leaving directory '.*/sub'},
|
||||||
|
%r{top configure},
|
||||||
|
])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not print entering/leaving directory messages when the subsidiary script is in the same directory" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
result = run_rscons(rsconscript: "Rsconscript_samedir", op: %W[configure])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
result = run_rscons(rsconscript: "Rsconscript_samedir", op: %W[build])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to_not match(%{(Entering|Leaving) directory})
|
||||||
|
verify_lines(lines(result.stdout), [
|
||||||
|
%r{second build},
|
||||||
|
%r{top build},
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
it "terminates execution when a subsidiary script fails" do
|
||||||
|
test_dir "subsidiary"
|
||||||
|
|
||||||
|
result = run_rscons(rsconscript: "Rsconscript_fail", op: %W[configure])
|
||||||
|
expect(result.stderr).to_not eq ""
|
||||||
|
expect(result.status).to_not eq 0
|
||||||
|
expect(result.stdout).to_not match /top configure/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -68,7 +68,7 @@ EOF
|
|||||||
expect(RbConfig::CONFIG).to receive(:[]).with("host_os").and_return("mingw")
|
expect(RbConfig::CONFIG).to receive(:[]).with("host_os").and_return("mingw")
|
||||||
end
|
end
|
||||||
it "returns the number of logical processors that wmic reports" do
|
it "returns the number of logical processors that wmic reports" do
|
||||||
expect(Util).to receive(:`).with("wmic cpu get NumberOfLogicalProcessors /value").and_return("NumberOfLogicalProcessors=7")
|
expect(Util).to receive(:`).with("wmic cpu get NumberOfLogicalProcessors -value").and_return("NumberOfLogicalProcessors=7")
|
||||||
expect(Util.determine_n_threads).to eq(7)
|
expect(Util.determine_n_threads).to eq(7)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
describe Rscons do
|
describe Rscons do
|
||||||
|
|
||||||
describe ".set_suffix" do
|
|
||||||
it "changes the suffix to the new one" do
|
|
||||||
expect(Rscons.set_suffix("foo.c", ".h")).to eq("foo.h")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "appends a suffix if the given file name does not have one" do
|
|
||||||
expect(Rscons.set_suffix("bazz", ".d")).to eq("bazz.d")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe ".get_system_shell" do
|
describe ".get_system_shell" do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
Rscons.instance_variable_set(:@shell, nil)
|
Rscons.instance_variable_set(:@shell, nil)
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
if ENV["dist_specs"]
|
||||||
|
require_relative "../test/rscons"
|
||||||
|
else
|
||||||
require "simplecov"
|
require "simplecov"
|
||||||
|
|
||||||
SimpleCov.start do
|
SimpleCov.start do
|
||||||
@ -18,8 +21,5 @@ SimpleCov.start do
|
|||||||
merge_timeout 3600
|
merge_timeout 3600
|
||||||
end
|
end
|
||||||
|
|
||||||
if ENV["dist_specs"]
|
|
||||||
require_relative "../test/rscons"
|
|
||||||
else
|
|
||||||
require "rscons"
|
require "rscons"
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user