Compare commits

...
35 Commits
Author SHA1 Message Date
josh 8e06efe61e v2.1.0 2020-04-16 16:52:58 -04:00
josh 0756874ddb update CHANGELOG for v2.1.0 2020-04-16 16:51:16 -04:00
josh dded5e2648 ruby 2.7 compatibility - #117 2020-04-16 15:48:45 -04:00
josh fbe60f6ba2 stick with simplecov 0.15.x for now 2020-04-16 15:02:01 -04:00
josh 8dd9799666 Revert "update simplecov"
This reverts commit 01ca86de8b.
2020-04-16 15:02:01 -04:00
josh f2c755c8bb update bundle 2020-04-16 13:07:20 -04:00
josh 01ca86de8b update simplecov 2020-02-29 14:27:21 -05:00
josh 943fabd0d1 update some gems 2020-02-29 10:47:46 -05:00
josh d08e2f6b5c v2.0.2 2019-12-16 21:36:38 -05:00
josh 90365dd197 update CHANGELOG for v2.0.2 2019-12-16 21:36:22 -05:00
josh 8d05516c40 distinguish object files built from multiple sources with the same base name but different extensions - close #113 2019-12-14 00:10:42 -05:00
josh db49d86866 show a configuration failed message on stderr on configuration failure 2019-10-14 22:57:49 -04:00
josh e667455c32 user guide: fix configure script example 2019-10-14 22:49:34 -04:00
josh e62332aba6 avoid backtrace when configuring fails during autoconf 2019-10-14 22:23:18 -04:00
josh 397639849d call print_run_message() in json_to_yaml build test 2019-10-12 17:59:08 -04:00
josh 96d5caf2e5 user guide: fix print_run_message() examples 2019-10-12 17:57:58 -04:00
josh f4b10a30af update CHANGELOG for v2.0.1 2019-10-02 21:10:29 -04:00
josh cf52c3fc6f v2.0.1 2019-10-02 20:59:58 -04:00
josh 5378afb6f8 Install builder cannot replace a currently executing binary on Linux - close #112 2019-09-28 23:18:31 -04:00
josh 48d9273cc6 v2.0.0 2019-09-11 23:32:27 -04:00
josh efea4f1181 user guide: Installation: mention marking rscons executable 2019-09-11 23:29:25 -04:00
josh b4fa6d965c CHANGELOG - add logo 2019-09-11 23:25:19 -04:00
josh ac56ad34f6 add rscons logo to README 2019-09-11 23:24:20 -04:00
josh 2fd533a32a clobber large_project directory 2019-09-11 23:20:22 -04:00
josh c938ed71d1 add "all" rake task 2019-09-11 23:19:46 -04:00
josh ec60201a62 user guide: add rscons logo 2019-09-11 23:18:38 -04:00
josh 0cafb8c5b3 user guide: stylize as "Rscons" 2019-09-11 23:15:16 -04:00
josh 004810386b clobber should remove "gen" directory 2019-09-11 23:15:02 -04:00
josh a15ee9daaf add logo images 2019-09-11 23:02:17 -04:00
josh cd33405697 user guide: add FreeBSD compatibility 2019-09-01 21:52:32 -04:00
josh efa77066bf allow ConfigureOp#log_and_test_command to be passed standard input data - close #111 2019-09-01 21:50:57 -04:00
josh a1bb9d81fd check_program: do not fail on Windows for non-existent PATH entries 2019-08-27 19:47:21 -04:00
josh 0344f02cb1 build tests: use -m instead of -lc for mingw 2019-08-27 19:32:36 -04:00
josh d52bdaf046 build tests: do ldc2 tests even if omit_gdc_tests set 2019-08-27 18:51:56 -04:00
josh ad7ccb771d update build test for gdc fix 2019-08-27 18:50:01 -04:00
35 changed files with 350 additions and 205 deletions

No files matched your search

+19
View File
@@ -1,3 +1,21 @@
## 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
@@ -32,6 +50,7 @@
- various performance improvements - various performance improvements
- wrote a new user guide - wrote a new user guide
- added new website ([https://holtrop.github.io/rscons/](https://holtrop.github.io/rscons/)) - added new website ([https://holtrop.github.io/rscons/](https://holtrop.github.io/rscons/))
- added new logo
## v1.17.0 ## v1.17.0
+1 -1
View File
@@ -3,7 +3,7 @@ source 'https://rubygems.org'
gem "json" gem "json"
gem "rspec" gem "rspec"
gem "rake" gem "rake"
gem "simplecov" gem "simplecov", "~> 0.15.0"
gem "yard" gem "yard"
gem "rdoc" gem "rdoc"
gem "redcarpet" gem "redcarpet"
+20 -20
View File
@@ -2,31 +2,31 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
diff-lcs (1.3) diff-lcs (1.3)
docile (1.3.2) docile (1.1.5)
json (2.2.0) json (2.3.0)
rake (12.3.2) rake (13.0.1)
rdoc (6.1.1) rdoc (6.2.1)
redcarpet (3.4.0) redcarpet (3.5.0)
rspec (3.8.0) rspec (3.9.0)
rspec-core (~> 3.8.0) rspec-core (~> 3.9.0)
rspec-expectations (~> 3.8.0) rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.8.0) rspec-mocks (~> 3.9.0)
rspec-core (3.8.2) rspec-core (3.9.1)
rspec-support (~> 3.8.0) rspec-support (~> 3.9.1)
rspec-expectations (3.8.4) rspec-expectations (3.9.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0) rspec-support (~> 3.9.0)
rspec-mocks (3.8.1) rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0) rspec-support (~> 3.9.0)
rspec-support (3.8.2) rspec-support (3.9.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.24)
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
+2
View File
@@ -1,5 +1,7 @@
# Rscons # Rscons
![rscons logo](img/rscons_logo_1000.png)
Rscons (https://github.com/holtrop/rscons) is an open-source build system Rscons (https://github.com/holtrop/rscons) is an open-source build system
for developers. for developers.
+8 -1
View File
@@ -11,7 +11,7 @@ require "rake/clean"
require "fileutils" require "fileutils"
CLEAN.include %w[build_test_run .yardoc yard coverage test] CLEAN.include %w[build_test_run .yardoc yard coverage test]
CLOBBER.include %w[dist pkg] CLOBBER.include %w[dist gen large_project pkg]
task :build_dist do task :build_dist do
sh "ruby rb/build_dist.rb" sh "ruby rb/build_dist.rb"
@@ -93,3 +93,10 @@ task :user_guide do
end end
task :default => :spec task :default => :spec
task :all => [
:build_dist,
:spec,
:yard,
:user_guide,
]
@@ -17,6 +17,10 @@ configure do
end end
op.complete(status, success_message: "good!", fail_message: fail_message, fail: should_fail) op.complete(status, success_message: "good!", fail_message: fail_message, fail: should_fail)
end end
custom_check("Checking sed -E flag") do |op|
stdout, stderr, status = op.log_and_test_command(%w[sed -E -e s/ab+/rep/], stdin: "abbbc")
op.complete(stdout =~ /repc/ ? 0 : 1, success_message: "good", fail_message: "fail")
end
end end
build do build do
+3 -2
View File
@@ -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
+3 -2
View File
@@ -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",
[], [],
+3 -2
View File
@@ -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",
[], [],
@@ -0,0 +1,6 @@
build do
Environment.new do |env|
env.Program("program.exe", "program.c")
env.Install("install/program.exe", "program.exe")
end
end
@@ -0,0 +1,8 @@
#include <stdio.h>
#include <unistd.h>
int main(int argc, char * argv[])
{
sleep(2);
return 0;
}
+1
View File
@@ -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))))
@@ -0,0 +1,5 @@
build do
Environment.new do |env|
env.Program("foo.exe", glob("*.cc", "*.c"))
end
end
+6
View File
@@ -0,0 +1,6 @@
#include <stdio.h>
void foo(void)
{
printf("foo\n");
}
+12
View 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;
}
+1 -1
View File
@@ -1,6 +1,6 @@
build do build do
Environment.new do |env| Environment.new do |env|
env["LIBS"] += ["c"] env["LIBS"] += ["m"]
env.Program('simple.exe', Dir['*.c']) env.Program('simple.exe', Dir['*.c'])
end end
end end
+2 -2
View File
@@ -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
+6 -5
View File
@@ -8,7 +8,7 @@ It supports the following features:
* built-in builders for several common operations * built-in builders for several common operations
* out-of-the-box support for C, C++, and D languages * out-of-the-box support for C, C++, and D languages
* extensibility for other languages or custom builders * extensibility for other languages or custom builders
* compatible with Windows, Linux, and OS X * compatible with Windows, Linux, OS X, and FreeBSD
* colorized output with build progress * colorized output with build progress
* build hooks * build hooks
@@ -98,7 +98,8 @@ The only dependency required to run Rscons is to have a Ruby interpreter
installed. installed.
The latest release can be downloaded from [https://github.com/holtrop/rscons/releases](https://github.com/holtrop/rscons/releases). The latest release can be downloaded from [https://github.com/holtrop/rscons/releases](https://github.com/holtrop/rscons/releases).
Simply copy the `rscons` executable script into the desired location within Simply copy the `rscons` executable script into the desired location within
the project to be built (typically the root of the repository). the project to be built (typically the root of the repository) and mark it
executable.
## Version Control Setup ## Version Control Setup
@@ -1024,7 +1025,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
@@ -1049,7 +1050,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"))
@@ -1276,7 +1277,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`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

-10
View File
@@ -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.
+3
View File
@@ -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
@@ -192,6 +194,7 @@ module Rscons
begin begin
@script.configure(co) @script.configure(co)
rescue ConfigureOp::ConfigureFailure rescue ConfigureOp::ConfigureFailure
Ansi.write($stderr, :red, "Configuration failed", :reset, "\n")
rv = 1 rv = 1
end end
co.close(rv == 0) co.close(rv == 0)
+1
View File
@@ -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)
+1 -1
View File
@@ -78,7 +78,7 @@ module Rscons
if @vars[:direct] if @vars[:direct]
@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)
+1 -1
View File
@@ -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)
+9 -2
View File
@@ -280,12 +280,19 @@ module Rscons
# Execute a test command and log the result. # Execute a test command and log the result.
# #
# @param command [Array<String>]
# Command to execute.
# @param options [Hash]
# Optional arguments.
# @option options [String] :stdin
# Data to send to standard input stream of the executed command.
#
# @return [String, String, Process::Status] # @return [String, String, Process::Status]
# stdout, stderr, status # stdout, stderr, status
def log_and_test_command(command) def log_and_test_command(command, options = {})
begin begin
@log_fh.puts("Command: #{command.join(" ")}") @log_fh.puts("Command: #{command.join(" ")}")
stdout, stderr, status = Open3.capture3(*command) stdout, stderr, status = Open3.capture3(*command, stdin_data: options[:stdin])
@log_fh.puts("Exit status: #{status.to_i}") @log_fh.puts("Exit status: #{status.to_i}")
@log_fh.write(stdout) @log_fh.write(stdout)
@log_fh.write(stderr) @log_fh.write(stderr)
+2 -6
View File
@@ -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.
@@ -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
+38 -10
View File
@@ -191,6 +191,32 @@ 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
private private
# Check if a directory contains a certain executable. # Check if a directory contains a certain executable.
@@ -204,16 +230,18 @@ module Rscons
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/i
executable = executable.downcase if File.directory?(path_entry)
dir_entries = Dir.entries(path_entry) executable = executable.downcase
dir_entries.find do |entry| dir_entries = Dir.entries(path_entry)
path = "#{path_entry}/#{entry}" dir_entries.find do |entry|
entry = entry.downcase path = "#{path_entry}/#{entry}"
if ((entry == executable) or entry = entry.downcase
(entry == "#{executable}.exe") or if ((entry == executable) or
(entry == "#{executable}.com") or (entry == "#{executable}.exe") or
(entry == "#{executable}.bat")) and is_executable[path] (entry == "#{executable}.com") or
return path (entry == "#{executable}.bat")) and is_executable[path]
return path
end
end end
end end
else else
+1 -1
View File
@@ -1,4 +1,4 @@
module Rscons module Rscons
# Project version. # Project version.
VERSION = "2.0.0beta2" VERSION = "2.1.0"
end end
+6 -1
View File
@@ -1,6 +1,6 @@
<html> <html>
<head> <head>
<title>RScons User Guide<%= subpage_title %> - Version <%= Rscons::VERSION %></title> <title>Rscons User Guide<%= subpage_title %> - Version <%= Rscons::VERSION %></title>
<style> <style>
body { body {
background-color: #CCC; background-color: #CCC;
@@ -31,6 +31,11 @@
.separator { .separator {
height: 2em; height: 2em;
} }
.img_block_center {
display: block;
margin-left: auto;
margin-right: auto;
}
.page_nav { .page_nav {
width: 100%; width: 100%;
table-layout: fixed; table-layout: fixed;
+3 -1
View File
@@ -154,7 +154,8 @@ class Generator
end end
def render_toc def render_toc
toc_content = %[<h1>Table of Contents</h1>\n] toc_content = %[<img class="img_block_center" src="rscons_logo_1000.png" />]
toc_content += %[<h1>Table of Contents</h1>\n]
@sections.each do |section| @sections.each do |section|
indent = section.number.split(".").size - 1 indent = section.number.split(".").size - 1
toc_content += %[<span style="padding-left: #{4 * indent}ex;">] toc_content += %[<span style="padding-left: #{4 * indent}ex;">]
@@ -223,5 +224,6 @@ end
input = load_file("doc/user_guide.md") input = load_file("doc/user_guide.md")
FileUtils.rm_rf("gen/user_guide") FileUtils.rm_rf("gen/user_guide")
FileUtils.mkdir_p("gen/user_guide") FileUtils.mkdir_p("gen/user_guide")
FileUtils.cp("img/rscons_logo_1000.png", "gen/user_guide")
Generator.new(input, "gen/user_guide/user_guide.html", false) Generator.new(input, "gen/user_guide/user_guide.html", false)
Generator.new(input, "gen/user_guide", true) Generator.new(input, "gen/user_guide", true)
+171 -125
View File
@@ -143,9 +143,13 @@ 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["PATH"] = "#{@build_test_run_dir}/_bin#{File::PATH_SEPARATOR}#{env["PATH"]}" path = ["#{@build_test_run_dir}/_bin", "#{env["PATH"]}"]
if options[:path]
path = Array(options[:path]) + path
end
env["PATH"] = path.join(File::PATH_SEPARATOR)
stdout, stderr, status = Open3.capture3(env, *command) stdout, stderr, status = Open3.capture3(env, *command)
File.open("#{@build_test_run_dir}/.stdout", "wb") do |fh| File.open("#{@build_test_run_dir}/.stdout", "wb") do |fh|
fh.write(stdout) fh.write(stdout)
@@ -191,7 +195,7 @@ 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(`./simple.exe`).to eq "This is a simple C program\n"
end end
@@ -208,8 +212,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
@@ -227,7 +231,7 @@ 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(`./header.exe`).to eq "The value is 2\n"
end end
@@ -277,13 +281,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
@@ -313,9 +317,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
@@ -333,15 +337,29 @@ EOF
expect(result.stderr).to match /Could not find a registered build target "foo"/ expect(result.stderr).to match /Could not find a registered build target "foo"/
end end
it "allows replacing a running executable when performing an 'install' operation" do
test_dir("install_running_exe")
result = run_rscons(op: "install")
expect(result.stderr).to eq ""
fcontents = File.read("program.c", mode: "rb")
File.open("program.c", "wb") do |fh|
fh.write(fcontents.sub(/2/, '3'))
end
pid = Process.spawn("install/program.exe")
result = run_rscons(op: "install")
expect(result.stderr).to eq ""
Process.wait(pid)
end
context "clean operation" do context "clean operation" do
it 'cleans built files' do it 'cleans built files' do
test_dir("simple") test_dir("simple")
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
@@ -352,7 +370,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
@@ -369,12 +387,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
@@ -391,7 +409,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 ""
@@ -473,10 +491,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
@@ -485,12 +503,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
@@ -499,7 +517,7 @@ 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(`./simple.exe`).to eq "This is a simple C++ program\n"
end end
@@ -516,9 +534,9 @@ 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 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(`./two_sources.exe`).to eq "This is a C program with two sources.\n"
@@ -529,14 +547,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(`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
@@ -544,9 +562,9 @@ 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(`./build_hook.exe`).to eq "Hello from two()\n"
end end
@@ -556,8 +574,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 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 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
@@ -573,7 +591,7 @@ 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(`./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")}
@@ -591,51 +609,51 @@ EOF
expect(result.stdout).to eq "" expect(result.stdout).to eq ""
end end
it "supports building D sources with gdc" do
test_dir("d")
result = run_rscons
expect(result.stderr).to eq ""
slines = lines(result.stdout)
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.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.d.o build/e.1/mod.d.o}])
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
end
it "supports building D sources with ldc2" do
test_dir("d")
result = run_rscons(rsconscript: "build-ldc2.rb")
expect(result.stderr).to eq ""
slines = lines(result.stdout)
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.d.o(bj)? -deps=build/e.1/main.d.o.mf main.d}])
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.d.o(bj)? -deps=build/e.1/mod.d.o.mf mod.d}])
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!"
end
it "rebuilds D modules with ldc2 when deep dependencies change" do
test_dir("d")
result = run_rscons(rsconscript: "build-ldc2.rb")
expect(result.stderr).to eq ""
slines = lines(result.stdout)
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.d.o(bj)? -deps=build/e.1/main.d.o.mf main.d}])
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.d.o(bj)? -deps=build/e.1/mod.d.o.mf mod.d}])
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!"
contents = File.read("mod.d", mode: "rb").sub("42", "33")
File.open("mod.d", "wb") do |fh|
fh.write(contents)
end
result = run_rscons(rsconscript: "build-ldc2.rb")
expect(result.stderr).to eq ""
slines = lines(result.stdout)
verify_lines(slines, [%r{ldc2 -c -of build/e.1/main.d.o(bj)? -deps=build/e.1/main.d.o.mf main.d}])
verify_lines(slines, [%r{ldc2 -c -of build/e.1/mod.d.o(bj)? -deps=build/e.1/mod.d.o.mf mod.d}])
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!"
end
unless ENV["omit_gdc_tests"] unless ENV["omit_gdc_tests"]
it "supports building D sources with gdc" do
test_dir("d")
result = run_rscons
expect(result.stderr).to eq ""
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/mod.o -MMD -MF build/e.1/mod.mf mod.d}])
verify_lines(slines, [%r{gdc -o hello-d.exe build/e.1/main.o build/e.1/mod.o}])
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
end
it "supports building D sources with ldc2" do
test_dir("d")
result = run_rscons(rsconscript: "build-ldc2.rb")
expect(result.stderr).to eq ""
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/mod.o(bj)? -deps=build/e.1/mod.mf mod.d}])
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.o(bj)? build/e.1/mod.o(bj)?}])
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
end
it "rebuilds D modules with ldc2 when deep dependencies change" do
test_dir("d")
result = run_rscons(rsconscript: "build-ldc2.rb")
expect(result.stderr).to eq ""
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/mod.o(bj)? -deps=build/e.1/mod.mf mod.d}])
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.o(bj)? build/e.1/mod.o(bj)?}])
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
contents = File.read("mod.d", mode: "rb").sub("42", "33")
File.open("mod.d", "wb") do |fh|
fh.write(contents)
end
result = run_rscons(rsconscript: "build-ldc2.rb")
expect(result.stderr).to eq ""
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/mod.o(bj)? -deps=build/e.1/mod.mf mod.d}])
verify_lines(slines, [%r{ldc2 -of hello-d.exe build/e.1/main.o(bj)? build/e.1/mod.o(bj)?}])
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 33!"
end
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")
@@ -650,18 +668,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
@@ -669,11 +687,7 @@ EOF
test_dir("shared_library") test_dir("shared_library")
result = run_rscons(rsconscript: "shared_library_d.rb") result = run_rscons(rsconscript: "shared_library_d.rb")
# Currently gdc produces an error while trying to build the shared expect(result.stderr).to eq ""
# library. Since this isn't really an rscons problem, I'm commenting out
# this check. I'm not sure what I want to do about D support at this
# point anyway...
#expect(result.stderr).to eq ""
slines = lines(result.stdout) slines = lines(result.stdout)
if RUBY_PLATFORM =~ /mingw/ if RUBY_PLATFORM =~ /mingw/
verify_lines(slines, [%r{Linking mine.dll}]) verify_lines(slines, [%r{Linking mine.dll}])
@@ -741,8 +755,8 @@ EOF
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(`./simple.exe`).to eq "This is a simple C program\n"
end end
@@ -751,8 +765,8 @@ 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(`./simple.exe`).to eq "This is a simple C++ program\n"
end end
@@ -761,8 +775,8 @@ 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(`./program.exe`).to eq "Hello from two()\n"
end end
@@ -834,7 +848,7 @@ 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(`./simple.exe`).to eq "This is a simple C program\n"
end end
@@ -916,7 +930,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
@@ -1431,6 +1445,18 @@ 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
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 +1550,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 simple.o.deppy simple.c},
]) ])
end end
@@ -1548,7 +1574,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
@@ -1578,7 +1604,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 +1737,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 +1780,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
@@ -1797,7 +1823,7 @@ 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
@@ -1835,7 +1861,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 +1926,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 +1967,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 +2008,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
@@ -2050,10 +2076,20 @@ EOF
expect(result.stdout).to match /Checking for program 'find'... .*find/ expect(result.stdout).to match /Checking for program 'find'... .*find/
end end
context "with non-existent PATH entries" do
it "succeeds when the requested program is found" do
test_dir "configure"
result = run_rscons(rsconscript: "check_program_success.rb", op: "configure", path: "/foo/bar")
expect(result.stderr).to eq ""
expect(result.status).to eq 0
expect(result.stdout).to match /Checking for program 'find'... .*find/
end
end
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
@@ -2085,7 +2121,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
@@ -2130,7 +2166,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
@@ -2141,7 +2177,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
@@ -2179,6 +2215,14 @@ EOF
expect(result.status).to eq 0 expect(result.status).to eq 0
end end
end end
it "allows passing standard input data to the executed command" do
test_dir "configure"
result = run_rscons(rsconscript: "custom_config_check.rb", op: "configure")
expect(result.stderr).to eq ""
expect(result.stdout).to match /Checking sed -E flag\.\.\. good/
expect(result.status).to eq 0
end
end end
end end
@@ -2192,8 +2236,8 @@ EOF
expect(result.stdout).to match /Setting build directory\.\.\. bb/ expect(result.stdout).to match /Setting build directory\.\.\. bb/
expect(result.stdout).to match %r{Setting prefix\.\.\. /my/prefix} expect(result.stdout).to match %r{Setting prefix\.\.\. /my/prefix}
expect(result.stdout).to match /Checking for C compiler\.\.\. gcc/ expect(result.stdout).to match /Checking for C compiler\.\.\. gcc/
expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. g++/ expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. g\+\+/
expect(result.stdout).to match /Checking for D compiler\.\.\. gdc/ expect(result.stdout).to match /Checking for D compiler\.\.\. (gdc|ldc2)/
expect(result.stdout).to match /Checking for package 'mypackage'\.\.\. found/ expect(result.stdout).to match /Checking for package 'mypackage'\.\.\. found/
expect(result.stdout).to match /Checking for C header 'stdio.h'\.\.\. found/ expect(result.stdout).to match /Checking for C header 'stdio.h'\.\.\. found/
expect(result.stdout).to match /Checking for C\+\+ header 'iostream'\.\.\. found/ expect(result.stdout).to match /Checking for C\+\+ header 'iostream'\.\.\. found/
@@ -2220,11 +2264,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
@@ -2428,13 +2474,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
+4 -1
View File
@@ -121,7 +121,10 @@ EOF
before(:each) do before(:each) do
stub_const("File::PATH_SEPARATOR", ";") stub_const("File::PATH_SEPARATOR", ";")
stub_const("RbConfig::CONFIG", "host_os" => "mingw") stub_const("RbConfig::CONFIG", "host_os" => "mingw")
expect(ENV).to receive(:[]).with("PATH").and_return("C:\\bin;C:\\Windows") expect(ENV).to receive(:[]).with("PATH").and_return("C:\\none;C:\\bin;C:\\Windows")
allow(File).to receive(:directory?).with("C:\\none").and_return(false)
allow(File).to receive(:directory?).with("C:\\bin").and_return(true)
allow(File).to receive(:directory?).with("C:\\Windows").and_return(true)
allow(Dir).to receive(:entries).with("C:\\bin").and_return(%w[one.com]) allow(Dir).to receive(:entries).with("C:\\bin").and_return(%w[one.com])
allow(Dir).to receive(:entries).with("C:\\Windows").and_return(%w[two.exe Three.bat]) allow(Dir).to receive(:entries).with("C:\\Windows").and_return(%w[two.exe Three.bat])
end end
-10
View File
@@ -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)