Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cf77f1f58 | ||
|
|
b4cc45c381 | ||
|
|
750506201f | ||
|
|
284312a21c | ||
|
|
d081a4695f | ||
|
|
c7f66694ab | ||
|
|
57de94a3fb | ||
|
|
53ba7dad41 | ||
|
|
8cb02a7e34 | ||
|
|
dbbce9e476 | ||
|
|
0dc3a90660 | ||
|
|
d48c7587d6 | ||
|
|
70d4740a69 | ||
|
|
aaae845d60 | ||
|
|
e900e74342 | ||
|
|
62ae3f162d | ||
|
|
099d26f33c | ||
|
|
89562c584a | ||
|
|
a9aeaf2356 | ||
|
|
5409b3cb34 | ||
|
|
6d04500c13 | ||
|
|
45e30662d2 | ||
|
|
8f7e044bfd | ||
|
|
dbea6f0a26 | ||
|
|
c923eb5c7c | ||
|
|
529d9aacaa | ||
|
|
65c1bac4f9 | ||
|
|
775363ddbd | ||
|
|
2a96495e83 | ||
|
|
15e52e488c | ||
|
|
c0b12132f0 |
No files matched your search
+203
@@ -0,0 +1,203 @@
|
|||||||
|
## ChangeLog
|
||||||
|
|
||||||
|
### v1.16.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- Add `Rscons.glob`
|
||||||
|
- Support command-line variables
|
||||||
|
- improve debuggability of cache.up_to_date?
|
||||||
|
- allow passing a VarSet into cache methods
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- generate dependencies for D builds
|
||||||
|
|
||||||
|
### v1.15.0
|
||||||
|
|
||||||
|
- allow json 1.x or 2.x
|
||||||
|
|
||||||
|
### v1.14.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- #45 - Add Rscons::VarSet#values_at
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- #44 - Environment#print_builder_run_message should support string commands
|
||||||
|
|
||||||
|
### v1.13.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- #43 - Add ability to record side-effect file production
|
||||||
|
|
||||||
|
### v1.12.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- #40 - env.depends should imply env.build_after
|
||||||
|
- #41 - be more colorful
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- #39 - wait for in-progress subcommands to complete on build failure
|
||||||
|
- #42 - cloned Environments should inherit n_threads
|
||||||
|
|
||||||
|
### v1.11.1
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- fix the circular build dependency detection logic
|
||||||
|
|
||||||
|
### v1.11.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- Change default Environment :clone option to :all to clone all attributes
|
||||||
|
- #38 - raise error when circular dependencies are found
|
||||||
|
- #34 - Allow overriding n_threads on a per-Environment level
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- #35 - env.build_after should expand paths
|
||||||
|
- #36 - SHCFLAGS and SHCXXFLAGS should inherit non-SH flags by default
|
||||||
|
- #37 - Fix non-blocking thread-wait if Rscons.n_threads is set to 0
|
||||||
|
|
||||||
|
### v1.10.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- #23 - add parallelization - builds are now parallelized by default
|
||||||
|
- #31 - add LEXSUFFIX, YACCSUFFIX construction variables
|
||||||
|
- #30 - place object files for absolute source paths under build_root
|
||||||
|
- #28 - support redirecting standard output using the Command builder
|
||||||
|
- Always use a build root and default it to "build"
|
||||||
|
- Add builder features
|
||||||
|
- #8 - add SharedObject and SharedLibrary builders
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- expand target and source paths before calling Builder#create_build_target
|
||||||
|
- #29 - fix PROGSUFFIX handling
|
||||||
|
- #32 - Pre-build hooks do not respect modified key values
|
||||||
|
|
||||||
|
### v1.9.3
|
||||||
|
|
||||||
|
- Environment#parse_flags should put -std=XXX flags in CCFLAGS, not CFLAGS
|
||||||
|
|
||||||
|
### v1.9.2
|
||||||
|
|
||||||
|
- allow phony targets in conjunction with build roots
|
||||||
|
|
||||||
|
### v1.9.1
|
||||||
|
|
||||||
|
- change *SUFFIX defaults to arrays
|
||||||
|
- add various C++ file suffixes
|
||||||
|
- use ${INCPREFIX} instead of hard-coded "-I" in Preprocess builder
|
||||||
|
|
||||||
|
### v1.9.0
|
||||||
|
|
||||||
|
#### New Features
|
||||||
|
|
||||||
|
- #6 - add Install and Copy builders
|
||||||
|
- #22 - allow overriding Command builder short description with CMD_DESC variable
|
||||||
|
- #24 - add "rscons" executable
|
||||||
|
- #25 - add support for phony targets given as Symbols instead of Strings
|
||||||
|
- #26 - support registering multiple build targets with the same target name
|
||||||
|
- #27 - add Directory builder
|
||||||
|
|
||||||
|
#### Fixes
|
||||||
|
|
||||||
|
- #20 - fix variable references that expand to arrays in build target sources
|
||||||
|
- #21 - rework Preprocess builder to consider deep dependencies
|
||||||
|
- fix Rscons.set_suffix to append the given suffix if the filename has none
|
||||||
|
- remove ${CFLAGS} from default CPP_CMD
|
||||||
|
|
||||||
|
### v1.8.1
|
||||||
|
|
||||||
|
- fix Environment#dump when construction variables are symbols
|
||||||
|
|
||||||
|
### v1.8.0
|
||||||
|
|
||||||
|
- new Command builder to execute arbitrary user commands
|
||||||
|
- new SimpleBuilder class
|
||||||
|
- create new builders quickly by passing a block to Environment#add_builder
|
||||||
|
- improved YARD documentation
|
||||||
|
- add Environment#dump to debug Environment construction variables
|
||||||
|
|
||||||
|
### v1.7.0
|
||||||
|
|
||||||
|
- allow build hooks to register new build targets
|
||||||
|
- add post-build hooks (register with Environment#add_post_build_hook)
|
||||||
|
- clear all build targets after processing an Environment
|
||||||
|
- allow trailing slashes in arguments to Environment#build_dir
|
||||||
|
|
||||||
|
### v1.6.1
|
||||||
|
|
||||||
|
- add DEPFILESUFFIX construction variable to override dependency file suffix
|
||||||
|
- fix Environment#depends to expand its arguments for construction variables
|
||||||
|
|
||||||
|
### v1.6.0
|
||||||
|
|
||||||
|
- support lambdas as construction variable values
|
||||||
|
|
||||||
|
### v1.5.0
|
||||||
|
|
||||||
|
- add "json" as a runtime dependency
|
||||||
|
- update construction variables to match SCons more closely
|
||||||
|
- add CPPDEFPREFIX, INCPREFIX, CPPDEFINES, CCFLAGS, LIBDIRPREFIX, and LIBLINKPREFIX
|
||||||
|
- add Environment#shell
|
||||||
|
- add Environment#parse_flags, #parse_flags!, #merge_flags
|
||||||
|
- unbuffer $stdout by default
|
||||||
|
- add PROGSUFFIX construction variable (defaults to .exe on MinGW/Cygwin)
|
||||||
|
- add Rscons::BuildTarget and Builder#create_build_target
|
||||||
|
- update specs to RSpec 3.x and fix to run on MinGW/Cygwin/Linux
|
||||||
|
- add YARD documentation to get to 100% coverage
|
||||||
|
|
||||||
|
### v1.4.3
|
||||||
|
|
||||||
|
- fix builders properly using construction variable overrides
|
||||||
|
- expand nil construction variables to empty strings
|
||||||
|
|
||||||
|
### v1.4.2
|
||||||
|
|
||||||
|
- add Environment#expand_path
|
||||||
|
- expand construction variable references in builder targets and sources before invoking builder
|
||||||
|
|
||||||
|
### v1.4.1
|
||||||
|
|
||||||
|
- fix invoking a builder with no sources while a build root defined
|
||||||
|
|
||||||
|
### v1.4.0
|
||||||
|
|
||||||
|
- add CFile builder
|
||||||
|
- add Disassemble builder
|
||||||
|
- add Preprocess builder
|
||||||
|
- pass the Environment object to build hooks in the :env key of the build_op parameter
|
||||||
|
- expand target/source paths beginning with "^/" to be relative to the Environment's build root
|
||||||
|
- many performance improvements, including:
|
||||||
|
- use JSON instead of YAML for the cache to improve loading speed (Issue #7)
|
||||||
|
- store a hash of the build command instead of the full command contents in the cache
|
||||||
|
- implement copy-on-write semantics for construction variables when cloning Environments
|
||||||
|
- only load the cache once instead of on each Environment#process
|
||||||
|
- only write the cache when something has changed
|
||||||
|
- fix Cache#mkdir_p to handle relative paths (Issue #5)
|
||||||
|
- flush the cache to disk if a builder raises an exception (Issue #4)
|
||||||
|
|
||||||
|
### v1.3.0
|
||||||
|
|
||||||
|
- change Environment#execute() options parameter to accept the following options keys:
|
||||||
|
- :env to pass an environment Hash to Kernel#system
|
||||||
|
- :options to pass an options Hash to Kernel#system
|
||||||
|
|
||||||
|
### v1.2.0
|
||||||
|
|
||||||
|
- add :clone option to Environment#clone to control exactly which Environment attributes are cloned
|
||||||
|
- allow nil to be passed in to Environment#build_root=
|
||||||
|
|
||||||
|
### v1.1.0
|
||||||
|
|
||||||
|
- Change Cache#up_to_date?() and #register_build() to accept a single target
|
||||||
|
file or an array of target file names
|
||||||
+22
-25
@@ -1,38 +1,36 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
rscons (1.11.1)
|
rscons (1.16.0)
|
||||||
json (~> 1.0)
|
json (>= 1.8, < 3.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.3)
|
||||||
docile (1.1.5)
|
docile (1.1.5)
|
||||||
json (1.8.3)
|
json (2.1.0)
|
||||||
rake (10.4.2)
|
rake (12.3.1)
|
||||||
rdoc (4.2.0)
|
rdoc (5.1.0)
|
||||||
json (~> 1.4)
|
rspec (3.6.0)
|
||||||
redcarpet (3.3.3)
|
rspec-core (~> 3.6.0)
|
||||||
rspec (3.4.0)
|
rspec-expectations (~> 3.6.0)
|
||||||
rspec-core (~> 3.4.0)
|
rspec-mocks (~> 3.6.0)
|
||||||
rspec-expectations (~> 3.4.0)
|
rspec-core (3.6.0)
|
||||||
rspec-mocks (~> 3.4.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-core (3.4.1)
|
rspec-expectations (3.6.0)
|
||||||
rspec-support (~> 3.4.0)
|
|
||||||
rspec-expectations (3.4.0)
|
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.4.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-mocks (3.4.0)
|
rspec-mocks (3.6.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.4.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-support (3.4.1)
|
rspec-support (3.6.0)
|
||||||
simplecov (0.11.1)
|
simplecov (0.15.0)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
json (~> 1.8)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.0)
|
simplecov-html (0.10.2)
|
||||||
yard (0.8.7.6)
|
yard (0.9.12)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
@@ -41,11 +39,10 @@ PLATFORMS
|
|||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
rake
|
rake
|
||||||
rdoc
|
rdoc
|
||||||
redcarpet
|
|
||||||
rscons!
|
rscons!
|
||||||
rspec
|
rspec
|
||||||
simplecov
|
simplecov
|
||||||
yard
|
yard
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.10.6
|
1.16.2
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# Rscons
|
# Rscons
|
||||||
|
|
||||||
Rscons is a software construction framework inspired by SCons and implemented
|
Rscons (https://github.com/holtrop/rscons) is a software construction framework
|
||||||
in Ruby.
|
inspired by SCons and implemented in Ruby.
|
||||||
|
|
||||||
[](http://badge.fury.io/rb/rscons)
|
[](http://badge.fury.io/rb/rscons)
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ task block or split among multiple tasks.
|
|||||||
```ruby
|
```ruby
|
||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CFLAGS"] << "-Wall"
|
env["CFLAGS"] << "-Wall"
|
||||||
env.Program("program", Dir["src/**/*.c"])
|
env.Program("program", Rscons.glob("src/**/*.c"))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ end
|
|||||||
```ruby
|
```ruby
|
||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["DFLAGS"] << "-Wall"
|
env["DFLAGS"] << "-Wall"
|
||||||
env.Program("program", Dir["src/**/*.d"])
|
env.Program("program", Rscons.glob("src/**/*.d"))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ main_env = Rscons::Environment.new do |env|
|
|||||||
env.build_dir("src", "build/main")
|
env.build_dir("src", "build/main")
|
||||||
env["CFLAGS"] = ["-DSOME_DEFINE", "-O3"]
|
env["CFLAGS"] = ["-DSOME_DEFINE", "-O3"]
|
||||||
env["LIBS"] = ["SDL"]
|
env["LIBS"] = ["SDL"]
|
||||||
env.Program("program", Dir["src/**/*.cc"])
|
env.Program("program", Rscons.glob("src/**/*.cc"))
|
||||||
end
|
end
|
||||||
|
|
||||||
debug_env = main_env.clone do |env|
|
debug_env = main_env.clone do |env|
|
||||||
@@ -59,7 +59,7 @@ debug_env = main_env.clone do |env|
|
|||||||
env.build_dir("src", "build/debug")
|
env.build_dir("src", "build/debug")
|
||||||
env["CFLAGS"] -= ["-O3"]
|
env["CFLAGS"] -= ["-O3"]
|
||||||
env["CFLAGS"] += ["-g", "-O0"]
|
env["CFLAGS"] += ["-g", "-O0"]
|
||||||
env.Program("program-debug", Dir["src/**/*.cc"])
|
env.Program("program-debug", Rscons.glob("src/**/*.cc"))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ end
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env.add_builder(GenerateFoo.new)
|
env.add_builder(GenerateFoo.new)
|
||||||
env.GenerateFoo("foo.h", [])
|
env.GenerateFoo("foo.h", [])
|
||||||
env.Program("a.out", Dir["*.c"])
|
env.Program("a.out", Rscons.glob("*.c"))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -111,6 +111,15 @@ Rscons::Environment.new do |env|
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `Cache#up_to_date?` method accepts an optional 5th parameter which is an
|
||||||
|
options Hash. The `:debug` option can be specified in this Hash with a value
|
||||||
|
of `true` to aid in debugging builders while developing them. For example:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
unless cache.up_to_date?(target, cmd, sources, env, debug: true)
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
### Example: Custom Builder That Generates Multiple Output Files
|
### Example: Custom Builder That Generates Multiple Output Files
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
@@ -191,7 +200,7 @@ Rscons::Environment.new do |env|
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
env.build_dir("src", "build")
|
env.build_dir("src", "build")
|
||||||
env.Program("program", Dir["**/*.cc"])
|
env.Program("program", Rscons.glob("**/*.cc"))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -199,7 +208,7 @@ end
|
|||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env.Library("mylib.a", Dir["src/**/*.c"])
|
env.Library("mylib.a", Rscons.glob("src/**/*.c"))
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -327,7 +336,7 @@ env.Install("dist/share", "share")
|
|||||||
```ruby
|
```ruby
|
||||||
env.Library(target, sources)
|
env.Library(target, sources)
|
||||||
# Example
|
# Example
|
||||||
env.Library("lib.a", Dir["src/**/*.c"])
|
env.Library("lib.a", Rscons.glob("src/**/*.c"))
|
||||||
```
|
```
|
||||||
|
|
||||||
The Library builder creates a static library archive from the given source
|
The Library builder creates a static library archive from the given source
|
||||||
@@ -362,7 +371,7 @@ preprocessed output to the target file.
|
|||||||
```ruby
|
```ruby
|
||||||
env.Program(target, sources)
|
env.Program(target, sources)
|
||||||
# Example
|
# Example
|
||||||
env.Program("myprog", Dir["src/**/*.cc"])
|
env.Program("myprog", Rscons.glob("src/**/*.cc"))
|
||||||
```
|
```
|
||||||
|
|
||||||
The Program builder compiles and links the given sources to an executable file.
|
The Program builder compiles and links the given sources to an executable file.
|
||||||
@@ -375,7 +384,7 @@ This can be controlled with the `PROGSUFFIX` construction variable.
|
|||||||
```ruby
|
```ruby
|
||||||
env.SharedLibrary(target, sources)
|
env.SharedLibrary(target, sources)
|
||||||
# Example
|
# Example
|
||||||
env.SharedLibrary("mydll", Dir["src/**/*.cc"])
|
env.SharedLibrary("mydll", Rscons.glob("src/**/*.cc"))
|
||||||
```
|
```
|
||||||
|
|
||||||
The SharedLibrary builder compiles and links the given sources to a dynamically
|
The SharedLibrary builder compiles and links the given sources to a dynamically
|
||||||
@@ -411,14 +420,14 @@ construction variables can be overridden by the user.
|
|||||||
| ARFLAGS | Array | Static library archiver flags | ["rcs"] |
|
| ARFLAGS | Array | Static library archiver flags | ["rcs"] |
|
||||||
| AS | String | Assembler executable | "${CC}" |
|
| AS | String | Assembler executable | "${CC}" |
|
||||||
| ASCMD | Array | Assembler command line | ["${AS}", "-c", "-o", "${_TARGET}", "${ASDEPGEN}", "${INCPREFIX}${ASPPPATH}", "${ASPPFLAGS}", "${ASFLAGS}", "${_SOURCES}"] |
|
| ASCMD | Array | Assembler command line | ["${AS}", "-c", "-o", "${_TARGET}", "${ASDEPGEN}", "${INCPREFIX}${ASPPPATH}", "${ASPPFLAGS}", "${ASFLAGS}", "${_SOURCES}"] |
|
||||||
| ASDEPGEN | Array | Assembly dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}"] |
|
| ASDEPGEN | Array | Assembly dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}", "-MT", "TARGET"] |
|
||||||
| ASFLAGS | Array | Assembler flags | [] |
|
| ASFLAGS | Array | Assembler flags | [] |
|
||||||
| ASPPFLAGS | Array | Assembler preprocessor flags | ["${CPPFLAGS}"] |
|
| ASPPFLAGS | Array | Assembler preprocessor flags | ["${CPPFLAGS}"] |
|
||||||
| ASPPPATH | Array | Assembler preprocessor path | ["${CPPPATH}"] |
|
| ASPPPATH | Array | Assembler preprocessor path | ["${CPPPATH}"] |
|
||||||
| ASSUFFIX | Array | Assembly file suffixes | [".S"] |
|
| ASSUFFIX | Array | Assembly file suffixes | [".S"] |
|
||||||
| CC | String | C compiler executable | "gcc" |
|
| CC | String | C compiler executable | "gcc" |
|
||||||
| CCCMD | Array | C compiler command line | ["${CC}", "-c", "-o", "${_TARGET}", "${CCDEPGEN}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${CFLAGS}", "${CCFLAGS}", "${_SOURCES}"] |
|
| CCCMD | Array | C compiler command line | ["${CC}", "-c", "-o", "${_TARGET}", "${CCDEPGEN}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${CFLAGS}", "${CCFLAGS}", "${_SOURCES}"] |
|
||||||
| CCDEPGEN | Array | C compiler dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}"] |
|
| CCDEPGEN | Array | C compiler dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}", "-MT", "TARGET"] |
|
||||||
| CCFLAGS | Array | Common flags for both C and C++ compiler | [] |
|
| CCFLAGS | Array | Common flags for both C and C++ compiler | [] |
|
||||||
| CFLAGS | Array | C compiler flags | [] |
|
| CFLAGS | Array | C compiler flags | [] |
|
||||||
| CPP_CMD | Array | Preprocess command line | ["${_PREPROCESS_CC}", "-E", "${_PREPROCESS_DEPGEN}", "-o", "${_TARGET}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${_SOURCES}"] |
|
| CPP_CMD | Array | Preprocess command line | ["${_PREPROCESS_CC}", "-E", "${_PREPROCESS_DEPGEN}", "-o", "${_TARGET}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${_SOURCES}"] |
|
||||||
@@ -430,12 +439,13 @@ construction variables can be overridden by the user.
|
|||||||
| CSUFFIX | Array | C source file suffixes | [".c"] |
|
| CSUFFIX | Array | C source file suffixes | [".c"] |
|
||||||
| CXX | String | C++ compiler executable | "g++" |
|
| CXX | String | C++ compiler executable | "g++" |
|
||||||
| CXXCMD | Array | C++ compiler command line | ["${CXX}", "-c", "-o", "${_TARGET}", "${CXXDEPGEN}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${CXXFLAGS}", "${CCFLAGS}", "${_SOURCES}"] |
|
| CXXCMD | Array | C++ compiler command line | ["${CXX}", "-c", "-o", "${_TARGET}", "${CXXDEPGEN}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${CXXFLAGS}", "${CCFLAGS}", "${_SOURCES}"] |
|
||||||
| CXXDEPGEN | Array | C++ compiler dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}"] |
|
| CXXDEPGEN | Array | C++ compiler dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}", "-MT", "TARGET"] |
|
||||||
| CXXFLAGS | Array | C++ compiler flags | [] |
|
| CXXFLAGS | Array | C++ compiler flags | [] |
|
||||||
| CXXSUFFIX | Array | C++ source file suffixes | [".cc", ".cpp", ".cxx", ".C"] |
|
| CXXSUFFIX | Array | C++ source file suffixes | [".cc", ".cpp", ".cxx", ".C"] |
|
||||||
| D_IMPORT_PATH | Array | D compiler import path | [] |
|
| D_IMPORT_PATH | Array | D compiler import path | [] |
|
||||||
| DC | String | D compiler executable | "gdc" |
|
| DC | String | D compiler executable | "gdc" |
|
||||||
| DCCMD | Array | D compiler command line | ["${DC}", "-c", "-o", "${_TARGET}", "${INCPREFIX}${D_IMPORT_PATH}", "${DFLAGS}", "${_SOURCES}"] |
|
| DCCMD | Array | D compiler command line | ["${DC}", "-c", "-o", "${_TARGET}", "${DDEPGEN}", "${INCPREFIX}${D_IMPORT_PATH}", "${DFLAGS}", "${_SOURCES}"] |
|
||||||
|
| DDEPGEN | Array | D compiler dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}", "-MT", "TARGET"] |
|
||||||
| DEPFILESUFFIX | String | Dependency file suffix for Makefile-style dependency rules emitted by the compiler (used internally for temporary dependency files used to determine a source file's dependencies) | ".mf" |
|
| DEPFILESUFFIX | String | Dependency file suffix for Makefile-style dependency rules emitted by the compiler (used internally for temporary dependency files used to determine a source file's dependencies) | ".mf" |
|
||||||
| DFLAGS | Array | D compiler flags | [] |
|
| DFLAGS | Array | D compiler flags | [] |
|
||||||
| DISASM_CMD | Array | Disassemble command line | ["${OBJDUMP}", "${DISASM_FLAGS}", "${_SOURCES}"] |
|
| DISASM_CMD | Array | Disassemble command line | ["${OBJDUMP}", "${DISASM_FLAGS}", "${_SOURCES}"] |
|
||||||
@@ -548,9 +558,19 @@ end
|
|||||||
You can pass multiple dependency files to `Environment#depends`:
|
You can pass multiple dependency files to `Environment#depends`:
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
env.depends("my_app", "config/link.ld", "README.txt", *Dir.glob("assets/**/*"))
|
env.depends("my_app", "config/link.ld", "README.txt", *Rscons.glob("assets/**/*"))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Command-Line Variables
|
||||||
|
|
||||||
|
Variables can be specified on the rscons command line. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
rscons VAR=val
|
||||||
|
```
|
||||||
|
|
||||||
|
These variables are accessible in a global VarSet called `Rscons.vars`.
|
||||||
|
|
||||||
### Construction Variable Naming
|
### Construction Variable Naming
|
||||||
|
|
||||||
* uppercase strings - the default construction variables that Rscons uses
|
* uppercase strings - the default construction variables that Rscons uses
|
||||||
@@ -562,159 +582,6 @@ env.depends("my_app", "config/link.ld", "README.txt", *Dir.glob("assets/**/*"))
|
|||||||
Documentation for the complete Rscons API can be found at
|
Documentation for the complete Rscons API can be found at
|
||||||
http://www.rubydoc.info/github/holtrop/rscons/master.
|
http://www.rubydoc.info/github/holtrop/rscons/master.
|
||||||
|
|
||||||
## Release Notes
|
|
||||||
|
|
||||||
### v1.11.0
|
|
||||||
|
|
||||||
#### New Features
|
|
||||||
|
|
||||||
- Change default Environment :clone option to :all to clone all attributes
|
|
||||||
- #38 - raise error when circular dependencies are found
|
|
||||||
- #34 - Allow overriding n_threads on a per-Environment level
|
|
||||||
|
|
||||||
#### Fixes
|
|
||||||
|
|
||||||
- #35 - env.build_after should expand paths
|
|
||||||
- #36 - SHCFLAGS and SHCXXFLAGS should inherit non-SH flags by default
|
|
||||||
- #37 - Fix non-blocking thread-wait if Rscons.n_threads is set to 0
|
|
||||||
|
|
||||||
### v1.10.0
|
|
||||||
|
|
||||||
#### New Features
|
|
||||||
|
|
||||||
- #23 - add parallelization - builds are now parallelized by default
|
|
||||||
- #31 - add LEXSUFFIX, YACCSUFFIX construction variables
|
|
||||||
- #30 - place object files for absolute source paths under build_root
|
|
||||||
- #28 - support redirecting standard output using the Command builder
|
|
||||||
- Always use a build root and default it to "build"
|
|
||||||
- Add builder features
|
|
||||||
- #8 - add SharedObject and SharedLibrary builders
|
|
||||||
|
|
||||||
#### Fixes
|
|
||||||
|
|
||||||
- expand target and source paths before calling Builder#create_build_target
|
|
||||||
- #29 - fix PROGSUFFIX handling
|
|
||||||
- #32 - Pre-build hooks do not respect modified key values
|
|
||||||
|
|
||||||
### v1.9.3
|
|
||||||
|
|
||||||
- Environment#parse_flags should put -std=XXX flags in CCFLAGS, not CFLAGS
|
|
||||||
|
|
||||||
### v1.9.2
|
|
||||||
|
|
||||||
- allow phony targets in conjunction with build roots
|
|
||||||
|
|
||||||
### v1.9.1
|
|
||||||
|
|
||||||
- change *SUFFIX defaults to arrays
|
|
||||||
- add various C++ file suffixes
|
|
||||||
- use ${INCPREFIX} instead of hard-coded "-I" in Preprocess builder
|
|
||||||
|
|
||||||
### v1.9.0
|
|
||||||
|
|
||||||
#### New Features
|
|
||||||
|
|
||||||
- #6 - add Install and Copy builders
|
|
||||||
- #22 - allow overriding Command builder short description with CMD_DESC variable
|
|
||||||
- #24 - add "rscons" executable
|
|
||||||
- #25 - add support for phony targets given as Symbols instead of Strings
|
|
||||||
- #26 - support registering multiple build targets with the same target name
|
|
||||||
- #27 - add Directory builder
|
|
||||||
|
|
||||||
#### Fixes
|
|
||||||
|
|
||||||
- #20 - fix variable references that expand to arrays in build target sources
|
|
||||||
- #21 - rework Preprocess builder to consider deep dependencies
|
|
||||||
- fix Rscons.set_suffix to append the given suffix if the filename has none
|
|
||||||
- remove ${CFLAGS} from default CPP_CMD
|
|
||||||
|
|
||||||
### v1.8.1
|
|
||||||
|
|
||||||
- fix Environment#dump when construction variables are symbols
|
|
||||||
|
|
||||||
### v1.8.0
|
|
||||||
|
|
||||||
- new Command builder to execute arbitrary user commands
|
|
||||||
- new SimpleBuilder class
|
|
||||||
- create new builders quickly by passing a block to Environment#add_builder
|
|
||||||
- improved YARD documentation
|
|
||||||
- add Environment#dump to debug Environment construction variables
|
|
||||||
|
|
||||||
### v1.7.0
|
|
||||||
|
|
||||||
- allow build hooks to register new build targets
|
|
||||||
- add post-build hooks (register with Environment#add_post_build_hook)
|
|
||||||
- clear all build targets after processing an Environment
|
|
||||||
- allow trailing slashes in arguments to Environment#build_dir
|
|
||||||
|
|
||||||
### v1.6.1
|
|
||||||
|
|
||||||
- add DEPFILESUFFIX construction variable to override dependency file suffix
|
|
||||||
- fix Environment#depends to expand its arguments for construction variables
|
|
||||||
|
|
||||||
### v1.6.0
|
|
||||||
|
|
||||||
- support lambdas as construction variable values
|
|
||||||
|
|
||||||
### v1.5.0
|
|
||||||
|
|
||||||
- add "json" as a runtime dependency
|
|
||||||
- update construction variables to match SCons more closely
|
|
||||||
- add CPPDEFPREFIX, INCPREFIX, CPPDEFINES, CCFLAGS, LIBDIRPREFIX, and LIBLINKPREFIX
|
|
||||||
- add Environment#shell
|
|
||||||
- add Environment#parse_flags, #parse_flags!, #merge_flags
|
|
||||||
- unbuffer $stdout by default
|
|
||||||
- add PROGSUFFIX construction variable (defaults to .exe on MinGW/Cygwin)
|
|
||||||
- add Rscons::BuildTarget and Builder#create_build_target
|
|
||||||
- update specs to RSpec 3.x and fix to run on MinGW/Cygwin/Linux
|
|
||||||
- add YARD documentation to get to 100% coverage
|
|
||||||
|
|
||||||
### v1.4.3
|
|
||||||
|
|
||||||
- fix builders properly using construction variable overrides
|
|
||||||
- expand nil construction variables to empty strings
|
|
||||||
|
|
||||||
### v1.4.2
|
|
||||||
|
|
||||||
- add Environment#expand_path
|
|
||||||
- expand construction variable references in builder targets and sources before invoking builder
|
|
||||||
|
|
||||||
### v1.4.1
|
|
||||||
|
|
||||||
- fix invoking a builder with no sources while a build root defined
|
|
||||||
|
|
||||||
### v1.4.0
|
|
||||||
|
|
||||||
- add CFile builder
|
|
||||||
- add Disassemble builder
|
|
||||||
- add Preprocess builder
|
|
||||||
- pass the Environment object to build hooks in the :env key of the build_op parameter
|
|
||||||
- expand target/source paths beginning with "^/" to be relative to the Environment's build root
|
|
||||||
- many performance improvements, including:
|
|
||||||
- use JSON instead of YAML for the cache to improve loading speed (Issue #7)
|
|
||||||
- store a hash of the build command instead of the full command contents in the cache
|
|
||||||
- implement copy-on-write semantics for construction variables when cloning Environments
|
|
||||||
- only load the cache once instead of on each Environment#process
|
|
||||||
- only write the cache when something has changed
|
|
||||||
- fix Cache#mkdir_p to handle relative paths (Issue #5)
|
|
||||||
- flush the cache to disk if a builder raises an exception (Issue #4)
|
|
||||||
|
|
||||||
### v1.3.0
|
|
||||||
|
|
||||||
- change Environment#execute() options parameter to accept the following options keys:
|
|
||||||
- :env to pass an environment Hash to Kernel#system
|
|
||||||
- :options to pass an options Hash to Kernel#system
|
|
||||||
|
|
||||||
### v1.2.0
|
|
||||||
|
|
||||||
- add :clone option to Environment#clone to control exactly which Environment attributes are cloned
|
|
||||||
- allow nil to be passed in to Environment#build_root=
|
|
||||||
|
|
||||||
### v1.1.0
|
|
||||||
|
|
||||||
- Change Cache#up_to_date?() and #register_build() to accept a single target
|
|
||||||
file or an array of target file names
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
1. Fork it
|
1. Fork it
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require "rscons/cli"
|
require "rscons/cli"
|
||||||
|
|
||||||
Rscons::Cli.run(ARGV)
|
Rscons::Cli.run(ARGV)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
env.append('CPPPATH' => Rscons.glob('src/**'))
|
||||||
env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
|
env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
|
||||||
env.Program('build_dir.exe', Dir['src/**/*.c'])
|
env.Program('build_dir.exe', Rscons.glob('src/**/*.c'))
|
||||||
end
|
end
|
||||||
@@ -6,7 +6,7 @@ end
|
|||||||
|
|
||||||
Rscons::Environment.new(echo: :command) do |env|
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
env.add_builder(MyObject.new)
|
env.add_builder(MyObject.new)
|
||||||
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
env.append('CPPPATH' => Rscons.glob('src/**'))
|
||||||
env.add_build_hook do |build_op|
|
env.add_build_hook do |build_op|
|
||||||
if build_op[:builder].name == "MyObject" && build_op[:sources].first =~ %r{one\.c}
|
if build_op[:builder].name == "MyObject" && build_op[:sources].first =~ %r{one\.c}
|
||||||
build_op[:vars]["CFLAGS"] << "-O1"
|
build_op[:vars]["CFLAGS"] << "-O1"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
env = Rscons::Environment.new do |env|
|
env = Rscons::Environment.new do |env|
|
||||||
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
env.append('CPPPATH' => Rscons.glob('src/**/*/'))
|
||||||
env.build_dir("src", "build")
|
env.build_dir("src", "build")
|
||||||
env.build_root = "build_root"
|
env.build_root = "build_root"
|
||||||
env.Program('build_dir.exe', Dir['src/**/*.c'])
|
env.Program('build_dir.exe', Rscons.glob('src/**/*.c'))
|
||||||
end
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Rscons::Environment.new(echo: :command) do |env|
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
env.append('CPPPATH' => Rscons.glob('src/**/*/'))
|
||||||
env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
|
env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
|
||||||
env.add_build_hook do |build_op|
|
env.add_build_hook do |build_op|
|
||||||
if build_op[:target] =~ %r{build_one/.*\.o}
|
if build_op[:target] =~ %r{build_one/.*\.o}
|
||||||
@@ -8,5 +8,5 @@ Rscons::Environment.new(echo: :command) do |env|
|
|||||||
build_op[:vars]["CFLAGS"] << "-O2"
|
build_op[:vars]["CFLAGS"] << "-O2"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
env.Program('build_hook.exe', Dir['src/**/*.c'].sort)
|
env.Program('build_hook.exe', Rscons.glob('src/**/*.c'))
|
||||||
end
|
end
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
Rscons::Environment.new(echo: :command) do |env|
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
env.append('CPPPATH' => Rscons.glob('src/**').sort)
|
||||||
env.build_root = "build_root"
|
env.build_root = "build_root"
|
||||||
FileUtils.mkdir_p(env.build_root)
|
FileUtils.mkdir_p(env.build_root)
|
||||||
FileUtils.mv("src/one/one.c", "build_root")
|
FileUtils.mv("src/one/one.c", "build_root")
|
||||||
env.Object("^/one.o", "^/one.c")
|
env.Object("^/one.o", "^/one.c")
|
||||||
env.Program("build_dir.exe", Dir['src/**/*.c'] + ["^/one.o"])
|
env.Program("build_dir.exe", Rscons.glob('src/**/*.c') + ["^/one.o"])
|
||||||
end
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CSUFFIX"] = %w[.yargh .c]
|
env["CSUFFIX"] = %w[.yargh .c]
|
||||||
env["CFLAGS"] += %w[-x c]
|
env["CFLAGS"] += %w[-x c]
|
||||||
env["CPPPATH"] += Dir["src/**/"]
|
env["CPPPATH"] += Rscons.glob("src/**")
|
||||||
env.Program("build_dir.exe", Dir["src/**/*.{c,yargh}"])
|
env.Program("build_dir.exe", Rscons.glob("src/**/*.{c,yargh}"))
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.echo = :command
|
||||||
|
env.Install("inst.exe", "install.rb")
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class MyBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
env, target = options.values_at(:env, :target)
|
||||||
|
env.print_builder_run_message("MyBuilder #{target}", "MyBuilder #{target} command")
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.echo = :command
|
||||||
|
env.add_builder(MyBuilder.new)
|
||||||
|
env.MyBuilder("foo")
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
env.append('CPPPATH' => Rscons.glob('src/**'))
|
||||||
env.build_dir("src2", "build")
|
env.build_dir("src2", "build")
|
||||||
env.build_root = "build_root"
|
env.build_root = "build_root"
|
||||||
env.Program('build_dir.exe', Dir['src/**/*.c'])
|
env.Program('build_dir.exe', Rscons.glob('src/**/*.c'))
|
||||||
end
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env.append("CPPPATH" => Dir["src/**/*/"].sort)
|
env.append("CPPPATH" => Rscons.glob("src/**"))
|
||||||
env.build_dir("src/one/", "build_one/")
|
env.build_dir("src/one/", "build_one/")
|
||||||
env.build_dir("src/two", "build_two")
|
env.build_dir("src/two", "build_two")
|
||||||
env.Program("build_dir.exe", Dir["src/**/*.c"])
|
env.Program("build_dir.exe", Rscons.glob("src/**/*.c"))
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["build_root"] = env.build_root
|
||||||
|
env["inc_h"] = "inc.h"
|
||||||
|
|
||||||
|
env.Copy("copy_inc.h", "${inc_h}")
|
||||||
|
env.depends("${build_root}/program.o", "${inc_h}")
|
||||||
|
env.Program("program.exe", ["program.c", "inc.c"])
|
||||||
|
|
||||||
|
env.Command("inc.c",
|
||||||
|
[],
|
||||||
|
"CMD" => %w[ruby gen.rb ${_TARGET}],
|
||||||
|
"CMD_DESC" => "Generating")
|
||||||
|
env.produces("inc.c", "inc.h")
|
||||||
|
end
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
Rscons::Environment.new(echo: :command) do |env|
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
env.Program("hello-d.exe", Dir["*.d"])
|
env.Program("hello-d.exe", Rscons.glob("*.d"))
|
||||||
end
|
end
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
import mod;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
writeln("Hello from D!");
|
writeln("Hello from D, value is ", Klass.VAL, "!");
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
class Klass
|
||||||
|
{
|
||||||
|
enum VAL = 42;
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Rscons::Environment.new(echo: :command) do |env|
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
env["ARCMD"] = %w[ar rcf ${_TARGET} ${_SOURCES}]
|
env["ARCMD"] = %w[ar rcf ${_TARGET} ${_SOURCES}]
|
||||||
env.Library("lib.a", Dir["*.c"].sort)
|
env.Library("lib.a", Rscons.glob("*.c"))
|
||||||
end
|
end
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CPPPATH"] << "src/lib"
|
env["CPPPATH"] << "src/lib"
|
||||||
libmine = env.SharedLibrary("mine", Dir["src/lib/*.c"])
|
libmine = env.SharedLibrary("mine", Rscons.glob("src/lib/*.c"))
|
||||||
env.Program("test-shared.exe",
|
env.Program("test-shared.exe",
|
||||||
Dir["src/*.c"],
|
Rscons.glob("src/*.c"),
|
||||||
"LIBPATH" => %w[.],
|
"LIBPATH" => %w[.],
|
||||||
"LIBS" => %w[mine])
|
"LIBS" => %w[mine])
|
||||||
env.build_after("test-shared.exe", libmine.to_s)
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
env.Program("test-static.exe",
|
env.Program("test-static.exe",
|
||||||
Dir["src/**/*.c"])
|
Rscons.glob("src/**/*.c"))
|
||||||
end
|
end
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CPPPATH"] << "src/lib"
|
env["CPPPATH"] << "src/lib"
|
||||||
libmine = env.SharedLibrary("mine", Dir["src/lib/*.cc"])
|
libmine = env.SharedLibrary("mine", Rscons.glob("src/lib/*.cc"))
|
||||||
env.Program("test-shared.exe",
|
env.Program("test-shared.exe",
|
||||||
Dir["src/*.cc"],
|
Rscons.glob("src/*.cc"),
|
||||||
"LIBPATH" => %w[.],
|
"LIBPATH" => %w[.],
|
||||||
"LIBS" => %w[mine])
|
"LIBS" => %w[mine])
|
||||||
env.build_after("test-shared.exe", libmine.to_s)
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
env.Program("test-static.exe",
|
env.Program("test-static.exe",
|
||||||
Dir["src/**/*.cc"])
|
Rscons.glob("src/**/*.cc"))
|
||||||
end
|
end
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CPPPATH"] << "src/lib"
|
env["CPPPATH"] << "src/lib"
|
||||||
libmine = env.SharedLibrary("mine", Dir["src/lib/*.d"])
|
libmine = env.SharedLibrary("mine", Rscons.glob("src/lib/*.d"))
|
||||||
env.Program("test-shared.exe",
|
env.Program("test-shared.exe",
|
||||||
Dir["src/*.c"],
|
Rscons.glob("src/*.c"),
|
||||||
"LIBPATH" => %w[.],
|
"LIBPATH" => %w[.],
|
||||||
"LIBS" => %w[mine])
|
"LIBS" => %w[mine])
|
||||||
env.build_after("test-shared.exe", libmine.to_s)
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CPPPATH"] << "src/lib"
|
env["CPPPATH"] << "src/lib"
|
||||||
env["SHLD"] = "gcc"
|
env["SHLD"] = "gcc"
|
||||||
libmine = env.SharedLibrary("mine", Dir["src/lib/*.c"])
|
libmine = env.SharedLibrary("mine", Rscons.glob("src/lib/*.c"))
|
||||||
env.Program("test-shared.exe",
|
env.Program("test-shared.exe",
|
||||||
Dir["src/*.c"],
|
Rscons.glob("src/*.c"),
|
||||||
"LIBPATH" => %w[.],
|
"LIBPATH" => %w[.],
|
||||||
"LIBS" => %w[mine])
|
"LIBS" => %w[mine])
|
||||||
env.build_after("test-shared.exe", libmine.to_s)
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
env.Program("test-static.exe",
|
env.Program("test-static.exe",
|
||||||
Dir["src/**/*.c"])
|
Rscons.glob("src/**/*.c"))
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
class DebugBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
|
command = %W[gcc -c -o #{target} #{sources.first}]
|
||||||
|
if Rscons.vars["command_change"]
|
||||||
|
command += %w[-Wall]
|
||||||
|
end
|
||||||
|
if Rscons.vars["new_dep"]
|
||||||
|
sources += ["extra"]
|
||||||
|
end
|
||||||
|
if Rscons.vars["strict_deps1"]
|
||||||
|
sources += ["extra"]
|
||||||
|
strict_deps = true
|
||||||
|
end
|
||||||
|
if Rscons.vars["strict_deps2"]
|
||||||
|
sources = ["extra"] + sources
|
||||||
|
strict_deps = true
|
||||||
|
end
|
||||||
|
unless cache.up_to_date?(target, command, sources, env, debug: true, strict_deps: strict_deps)
|
||||||
|
desc = "#{self.class.name} #{target}"
|
||||||
|
return false unless env.execute(desc, command)
|
||||||
|
cache.register_build(target, command, sources, env)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(DebugBuilder.new)
|
||||||
|
if Rscons.vars["new_user_dep"]
|
||||||
|
env.depends("foo.o", "new_dep")
|
||||||
|
end
|
||||||
|
env.DebugBuilder("foo.o", "simple.c")
|
||||||
|
end
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
class TestBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env = options.values_at(:target, :sources, :cache, :env)
|
||||||
|
command = Rscons::VarSet.new("A" => "a", "B" => "b")
|
||||||
|
unless cache.up_to_date?(target, command, sources, env)
|
||||||
|
File.open(target, "w") do |fh|
|
||||||
|
fh.puts("hi")
|
||||||
|
end
|
||||||
|
msg = "#{self.class.name} #{target}"
|
||||||
|
env.print_builder_run_message(msg, msg)
|
||||||
|
cache.register_build(target, command, sources, env)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(TestBuilder.new)
|
||||||
|
env.TestBuilder("foo")
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
base_env = Rscons::Environment.new do |env|
|
||||||
|
env.n_threads = 165
|
||||||
|
end
|
||||||
|
|
||||||
|
my_env = base_env.clone
|
||||||
|
|
||||||
|
puts my_env.n_threads
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["sources"] = Dir["*.c"].sort
|
env["sources"] = Rscons.glob("*.c")
|
||||||
env.Program("simple.exe", "${sources}")
|
env.Program("simple.exe", "${sources}")
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
class TestBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, env, vars, cache = options.values_at(:target, :env, :vars, :cache)
|
||||||
|
if target == "two"
|
||||||
|
return false unless File.exists?("one")
|
||||||
|
end
|
||||||
|
wait_time = env.expand_varref("${wait_time}", vars)
|
||||||
|
command = ["ruby", "-e", "require 'fileutils'; sleep #{wait_time}; FileUtils.touch('#{target}');"]
|
||||||
|
standard_threaded_build("TestBuilder", target, command, [], env, cache)
|
||||||
|
end
|
||||||
|
|
||||||
|
def finalize(options)
|
||||||
|
standard_finalize(options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(TestBuilder.new)
|
||||||
|
env.TestBuilder("one", [], "wait_time" => "3")
|
||||||
|
env.TestBuilder("two", [], "wait_time" => "0")
|
||||||
|
env.depends("two", "one")
|
||||||
|
end
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
class Fail < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, cache, env, vars = options.values_at(:target, :cache, :env, :vars)
|
||||||
|
wait_time = env.expand_varref("${wait_time}", vars)
|
||||||
|
ruby_command = %[sleep #{wait_time}; exit 2]
|
||||||
|
command = %W[ruby -e #{ruby_command}]
|
||||||
|
standard_threaded_build("Fail #{target}", target, command, [], env, cache)
|
||||||
|
end
|
||||||
|
def finalize(options)
|
||||||
|
standard_finalize(options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(Fail.new)
|
||||||
|
4.times do |i|
|
||||||
|
wait_time = i + 1
|
||||||
|
env.Fail("foo_#{wait_time}", [], "wait_time" => wait_time.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
require_relative "rscons/ansi"
|
||||||
require_relative "rscons/build_target"
|
require_relative "rscons/build_target"
|
||||||
require_relative "rscons/builder"
|
require_relative "rscons/builder"
|
||||||
require_relative "rscons/cache"
|
require_relative "rscons/cache"
|
||||||
@@ -50,6 +51,15 @@ module Rscons
|
|||||||
# The number of threads to use when scheduling subprocesses.
|
# The number of threads to use when scheduling subprocesses.
|
||||||
attr_accessor :n_threads
|
attr_accessor :n_threads
|
||||||
|
|
||||||
|
# @return [Boolean]
|
||||||
|
# Whether to output ANSI color escape sequences.
|
||||||
|
attr_accessor :do_ansi_color
|
||||||
|
|
||||||
|
# @since 1.16.0
|
||||||
|
# @return [VarSet]
|
||||||
|
# Access any variables set on the rscons command-line.
|
||||||
|
attr_reader :vars
|
||||||
|
|
||||||
# Remove all generated files.
|
# Remove all generated files.
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
@@ -160,6 +170,35 @@ module Rscons
|
|||||||
@command_executer = val
|
@command_executer = val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a list of paths matching the specified pattern(s).
|
||||||
|
#
|
||||||
|
# @since 1.16.0
|
||||||
|
#
|
||||||
|
# A pattern can contain a "/**" component to recurse through directories.
|
||||||
|
# If the pattern ends with "/**" then only the recursive list of
|
||||||
|
# directories will be returned.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
# - "src/**": return all directories under "src", recursively (including
|
||||||
|
# "src" itself).
|
||||||
|
# - "src/**/*": return all files and directories recursively under the src
|
||||||
|
# directory.
|
||||||
|
# - "src/**/*.c": return all .c files recursively under the src directory.
|
||||||
|
# - "dir/*/": return all directories in dir, but no files.
|
||||||
|
#
|
||||||
|
# @return [Array<String>] Paths matching the specified pattern(s).
|
||||||
|
def glob(*patterns)
|
||||||
|
require "pathname"
|
||||||
|
patterns.reduce([]) do |result, pattern|
|
||||||
|
if pattern.end_with?("/**")
|
||||||
|
pattern += "/"
|
||||||
|
end
|
||||||
|
result += Dir.glob(pattern).map do |path|
|
||||||
|
Pathname.new(path.gsub("\\", "/")).cleanpath.to_s
|
||||||
|
end
|
||||||
|
end.sort
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Determine the number of threads to use by default.
|
# Determine the number of threads to use by default.
|
||||||
@@ -198,6 +237,7 @@ module Rscons
|
|||||||
end
|
end
|
||||||
|
|
||||||
@n_threads = determine_n_threads
|
@n_threads = determine_n_threads
|
||||||
|
@vars = VarSet.new
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
module Rscons
|
||||||
|
# Module to contain logic to write ANSI color escape codes.
|
||||||
|
module Ansi
|
||||||
|
class << self
|
||||||
|
|
||||||
|
# Write a message to an IO with ANSI escape codes.
|
||||||
|
#
|
||||||
|
# @param io [IO]
|
||||||
|
# The IO to write to.
|
||||||
|
# @param message [Array<String, Symbol>]
|
||||||
|
# Strings to be printed, with Symbols representing ANSI escape codes.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def write(io, *message)
|
||||||
|
do_color = Rscons.do_ansi_color
|
||||||
|
if do_color.nil?
|
||||||
|
do_color = do_ansi?(io)
|
||||||
|
end
|
||||||
|
out = ""
|
||||||
|
message.each do |m|
|
||||||
|
if m.is_a?(String)
|
||||||
|
out += m
|
||||||
|
elsif do_color
|
||||||
|
case m
|
||||||
|
when :red
|
||||||
|
out += "\e[0;31m"
|
||||||
|
when :cyan
|
||||||
|
out += "\e[0;36m"
|
||||||
|
when :reset
|
||||||
|
out += "\e[0m"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
io.write(out)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Determine whether to output ANSI color escape codes.
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
# Whether to output ANSI color escape codes.
|
||||||
|
def do_ansi?(io)
|
||||||
|
if RUBY_PLATFORM =~ /mingw/
|
||||||
|
(ENV["TERM"] == "xterm") && %w[fifo characterSpecial].include?(io.stat.ftype)
|
||||||
|
else
|
||||||
|
io.tty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -231,7 +231,7 @@ module Rscons
|
|||||||
# @param env [Environment] The Environment executing the builder.
|
# @param env [Environment] The Environment executing the builder.
|
||||||
# @param cache [Cache] The Cache object.
|
# @param cache [Cache] The Cache object.
|
||||||
# @param options [Hash] Options.
|
# @param options [Hash] Options.
|
||||||
# @options options [String] :stdout
|
# @option options [String] :stdout
|
||||||
# File name to redirect standard output to.
|
# File name to redirect standard output to.
|
||||||
#
|
#
|
||||||
# @return [String,ThreadedCommand]
|
# @return [String,ThreadedCommand]
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ module Rscons
|
|||||||
if File.directory?(target)
|
if File.directory?(target)
|
||||||
target
|
target
|
||||||
elsif File.exists?(target)
|
elsif File.exists?(target)
|
||||||
$stderr.puts "Error: `#{target}' already exists and is not a directory"
|
Ansi.write($stderr, :red, "Error: `#{target}' already exists and is not a directory", :reset, "\n")
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
puts "Directory #{target}"
|
env.print_builder_run_message("Directory #{target}", nil)
|
||||||
cache.mkdir_p(target)
|
cache.mkdir_p(target)
|
||||||
target
|
target
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ module Rscons
|
|||||||
# Check the cache and copy if necessary
|
# Check the cache and copy if necessary
|
||||||
unless cache.up_to_date?(dest, :Copy, [src], env)
|
unless cache.up_to_date?(dest, :Copy, [src], env)
|
||||||
unless printed_message
|
unless printed_message
|
||||||
puts "#{name} #{target}"
|
env.print_builder_run_message("#{name} #{target}", nil)
|
||||||
printed_message = true
|
printed_message = true
|
||||||
end
|
end
|
||||||
cache.mkdir_p(File.dirname(dest))
|
cache.mkdir_p(File.dirname(dest))
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ module Rscons
|
|||||||
'ASSUFFIX' => ['.S'],
|
'ASSUFFIX' => ['.S'],
|
||||||
'ASPPPATH' => '${CPPPATH}',
|
'ASPPPATH' => '${CPPPATH}',
|
||||||
'ASPPFLAGS' => '${CPPFLAGS}',
|
'ASPPFLAGS' => '${CPPFLAGS}',
|
||||||
'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
|
'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}', '-MT', 'TARGET'],
|
||||||
'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '${INCPREFIX}${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
|
'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '${INCPREFIX}${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'],
|
||||||
|
|
||||||
'CPPFLAGS' => ['${CPPDEFPREFIX}${CPPDEFINES}'],
|
'CPPFLAGS' => ['${CPPDEFPREFIX}${CPPDEFINES}'],
|
||||||
@@ -42,20 +42,21 @@ module Rscons
|
|||||||
'CC' => 'gcc',
|
'CC' => 'gcc',
|
||||||
'CFLAGS' => [],
|
'CFLAGS' => [],
|
||||||
'CSUFFIX' => ['.c'],
|
'CSUFFIX' => ['.c'],
|
||||||
'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
|
'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}', '-MT', 'TARGET'],
|
||||||
'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '${INCPREFIX}${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${CCFLAGS}', '${_SOURCES}'],
|
'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '${INCPREFIX}${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${CCFLAGS}', '${_SOURCES}'],
|
||||||
|
|
||||||
'CXX' => 'g++',
|
'CXX' => 'g++',
|
||||||
'CXXFLAGS' => [],
|
'CXXFLAGS' => [],
|
||||||
'CXXSUFFIX' => ['.cc', '.cpp', '.cxx', '.C'],
|
'CXXSUFFIX' => ['.cc', '.cpp', '.cxx', '.C'],
|
||||||
'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'],
|
'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}', '-MT', 'TARGET'],
|
||||||
'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '${INCPREFIX}${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${CCFLAGS}', '${_SOURCES}'],
|
'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '${INCPREFIX}${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${CCFLAGS}', '${_SOURCES}'],
|
||||||
|
|
||||||
'DC' => 'gdc',
|
'DC' => 'gdc',
|
||||||
'DFLAGS' => [],
|
'DFLAGS' => [],
|
||||||
'DSUFFIX' => ['.d'],
|
'DSUFFIX' => ['.d'],
|
||||||
|
'DDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}', '-MT', 'TARGET'],
|
||||||
'D_IMPORT_PATH' => [],
|
'D_IMPORT_PATH' => [],
|
||||||
'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '${INCPREFIX}${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
|
'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '${DDEPGEN}', '${INCPREFIX}${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -114,7 +115,7 @@ module Rscons
|
|||||||
if options[:command_status]
|
if options[:command_status]
|
||||||
target, deps, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
target, deps, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
if File.exists?(vars['_DEPFILE'])
|
if File.exists?(vars['_DEPFILE'])
|
||||||
deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target)
|
deps += Environment.parse_makefile_deps(vars['_DEPFILE'], 'TARGET')
|
||||||
FileUtils.rm_f(vars['_DEPFILE'])
|
FileUtils.rm_f(vars['_DEPFILE'])
|
||||||
end
|
end
|
||||||
cache.register_build(target, options[:tc].command, deps.uniq, env)
|
cache.register_build(target, options[:tc].command, deps.uniq, env)
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ module Rscons
|
|||||||
if options[:command_status]
|
if options[:command_status]
|
||||||
target, deps, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
target, deps, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
if File.exists?(vars['_DEPFILE'])
|
if File.exists?(vars['_DEPFILE'])
|
||||||
deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target)
|
deps += Environment.parse_makefile_deps(vars['_DEPFILE'], 'TARGET')
|
||||||
FileUtils.rm_f(vars['_DEPFILE'])
|
FileUtils.rm_f(vars['_DEPFILE'])
|
||||||
end
|
end
|
||||||
cache.register_build(target, options[:tc].command, deps.uniq, env)
|
cache.register_build(target, options[:tc].command, deps.uniq, env)
|
||||||
|
|||||||
+52
-8
@@ -111,6 +111,10 @@ module Rscons
|
|||||||
# @param deps [Array<String>] List of the target's dependency files.
|
# @param deps [Array<String>] List of the target's dependency files.
|
||||||
# @param env [Environment] The Rscons::Environment.
|
# @param env [Environment] The Rscons::Environment.
|
||||||
# @param options [Hash] Optional options.
|
# @param options [Hash] Optional options.
|
||||||
|
# @option options [Boolean] :debug
|
||||||
|
# If turned on, this causes the Cache to print messages explaining why
|
||||||
|
# a build target is out of date. This could aid a builder author in
|
||||||
|
# debugging the operation of their builder.
|
||||||
# @option options [Boolean] :strict_deps
|
# @option options [Boolean] :strict_deps
|
||||||
# Only consider a target up to date if its list of dependencies is
|
# Only consider a target up to date if its list of dependencies is
|
||||||
# exactly equal (including order) to the cached list of dependencies
|
# exactly equal (including order) to the cached list of dependencies
|
||||||
@@ -133,39 +137,79 @@ module Rscons
|
|||||||
|
|
||||||
unless Rscons.phony_target?(target)
|
unless Rscons.phony_target?(target)
|
||||||
# target file must exist on disk
|
# target file must exist on disk
|
||||||
return false unless File.exists?(target)
|
unless File.exists?(target)
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because it does not exist on disk"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# target must be registered in the cache
|
# target must be registered in the cache
|
||||||
return false unless @cache["targets"].has_key?(cache_key)
|
unless @cache["targets"].has_key?(cache_key)
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because there is no cached build information for it"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
unless Rscons.phony_target?(target)
|
unless Rscons.phony_target?(target)
|
||||||
# target must have the same checksum as when it was built last
|
# target must have the same checksum as when it was built last
|
||||||
return false unless @cache["targets"][cache_key]["checksum"] == lookup_checksum(target)
|
unless @cache["targets"][cache_key]["checksum"] == lookup_checksum(target)
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because it has been changed on disk since being built last"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# command used to build target must be identical
|
# command used to build target must be identical
|
||||||
return false unless @cache["targets"][cache_key]["command"] == Digest::MD5.hexdigest(command.inspect)
|
unless @cache["targets"][cache_key]["command"] == Digest::MD5.hexdigest(command.inspect)
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because the command used to build it has changed"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
cached_deps = @cache["targets"][cache_key]["deps"] || []
|
cached_deps = @cache["targets"][cache_key]["deps"] || []
|
||||||
cached_deps_fnames = cached_deps.map { |dc| dc["fname"] }
|
cached_deps_fnames = cached_deps.map { |dc| dc["fname"] }
|
||||||
if options[:strict_deps]
|
if options[:strict_deps]
|
||||||
# depedencies passed in must exactly equal those in the cache
|
# depedencies passed in must exactly equal those in the cache
|
||||||
return false unless deps == cached_deps_fnames
|
unless deps == cached_deps_fnames
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because the :strict_deps option is given and the set of dependencies does not match the previous set of dependencies"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
else
|
else
|
||||||
# all dependencies passed in must exist in cache (but cache may have more)
|
# all dependencies passed in must exist in cache (but cache may have more)
|
||||||
return false unless (Set.new(deps) - Set.new(cached_deps_fnames)).empty?
|
unless (Set.new(deps) - Set.new(cached_deps_fnames)).empty?
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because there are new dependencies"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# set of user dependencies must match
|
# set of user dependencies must match
|
||||||
user_deps = env.get_user_deps(target) || []
|
user_deps = env.get_user_deps(target) || []
|
||||||
cached_user_deps = @cache["targets"][cache_key]["user_deps"] || []
|
cached_user_deps = @cache["targets"][cache_key]["user_deps"] || []
|
||||||
cached_user_deps_fnames = cached_user_deps.map { |dc| dc["fname"] }
|
cached_user_deps_fnames = cached_user_deps.map { |dc| dc["fname"] }
|
||||||
return false unless user_deps == cached_user_deps_fnames
|
unless user_deps == cached_user_deps_fnames
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because the set of user-specified dependency files has changed"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
# all cached dependencies must have their checksums match
|
# all cached dependencies must have their checksums match
|
||||||
(cached_deps + cached_user_deps).each do |dep_cache|
|
(cached_deps + cached_user_deps).each do |dep_cache|
|
||||||
return false unless dep_cache["checksum"] == lookup_checksum(dep_cache["fname"])
|
unless dep_cache["checksum"] == lookup_checksum(dep_cache["fname"])
|
||||||
|
if options[:debug]
|
||||||
|
puts "Target #{target} needs rebuilding because dependency file #{dep_cache["fname"]} has changed"
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+15
-1
@@ -39,6 +39,15 @@ module Rscons
|
|||||||
Rscons.n_threads = n_threads.to_i
|
Rscons.n_threads = n_threads.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
opts.on("-r", "--color MODE", "Set color mode (off, auto, force)") do |color_mode|
|
||||||
|
case color_mode
|
||||||
|
when "off"
|
||||||
|
Rscons.do_ansi_color = false
|
||||||
|
when "force"
|
||||||
|
Rscons.do_ansi_color = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
opts.on_tail("--version", "Show version") do
|
opts.on_tail("--version", "Show version") do
|
||||||
puts "Rscons version #{Rscons::VERSION}"
|
puts "Rscons version #{Rscons::VERSION}"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -51,6 +60,12 @@ module Rscons
|
|||||||
|
|
||||||
end.parse!(argv)
|
end.parse!(argv)
|
||||||
|
|
||||||
|
argv.each do |arg|
|
||||||
|
if arg =~ /^([^=]+)=(.*)$/
|
||||||
|
Rscons.vars[$1] = $2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if rsconsfile
|
if rsconsfile
|
||||||
unless File.exists?(rsconsfile)
|
unless File.exists?(rsconsfile)
|
||||||
$stderr.puts "Cannot read #{rsconsfile}"
|
$stderr.puts "Cannot read #{rsconsfile}"
|
||||||
@@ -70,7 +85,6 @@ module Rscons
|
|||||||
begin
|
begin
|
||||||
load rsconsfile
|
load rsconsfile
|
||||||
rescue Rscons::BuildError => e
|
rescue Rscons::BuildError => e
|
||||||
$stderr.puts e.message
|
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+79
-19
@@ -45,8 +45,9 @@ module Rscons
|
|||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
@threaded_commands = Set.new
|
@threaded_commands = Set.new
|
||||||
@registered_build_dependencies = {}
|
@registered_build_dependencies = {}
|
||||||
|
@side_effects = {}
|
||||||
@varset = VarSet.new
|
@varset = VarSet.new
|
||||||
@job_set = JobSet.new(@registered_build_dependencies)
|
@job_set = JobSet.new(@registered_build_dependencies, @side_effects)
|
||||||
@user_deps = {}
|
@user_deps = {}
|
||||||
@builders = {}
|
@builders = {}
|
||||||
@build_dirs = []
|
@build_dirs = []
|
||||||
@@ -118,6 +119,7 @@ module Rscons
|
|||||||
env.add_post_build_hook(&build_hook_block)
|
env.add_post_build_hook(&build_hook_block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
env.instance_variable_set(:@n_threads, @n_threads)
|
||||||
|
|
||||||
if block_given?
|
if block_given?
|
||||||
yield env
|
yield env
|
||||||
@@ -302,13 +304,19 @@ module Rscons
|
|||||||
# @return [void]
|
# @return [void]
|
||||||
def process
|
def process
|
||||||
cache = Cache.instance
|
cache = Cache.instance
|
||||||
|
failure = nil
|
||||||
begin
|
begin
|
||||||
while @job_set.size > 0 or @threaded_commands.size > 0
|
while @job_set.size > 0 or @threaded_commands.size > 0
|
||||||
|
|
||||||
|
if failure
|
||||||
|
@job_set.clear!
|
||||||
|
job = nil
|
||||||
|
else
|
||||||
targets_still_building = @threaded_commands.map do |tc|
|
targets_still_building = @threaded_commands.map do |tc|
|
||||||
tc.build_operation[:target]
|
tc.build_operation[:target]
|
||||||
end
|
end
|
||||||
job = @job_set.get_next_job_to_run(targets_still_building)
|
job = @job_set.get_next_job_to_run(targets_still_building)
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: have Cache determine when checksums may be invalid based on
|
# TODO: have Cache determine when checksums may be invalid based on
|
||||||
# file size and/or timestamp.
|
# file size and/or timestamp.
|
||||||
@@ -323,7 +331,9 @@ module Rscons
|
|||||||
allow_delayed_execution: true,
|
allow_delayed_execution: true,
|
||||||
setup_info: job[:setup_info])
|
setup_info: job[:setup_info])
|
||||||
unless result
|
unless result
|
||||||
raise BuildError.new("Failed to build #{job[:target]}")
|
failure = "Failed to build #{job[:target]}"
|
||||||
|
Ansi.write($stderr, :red, failure, :reset, "\n")
|
||||||
|
next
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -349,9 +359,11 @@ module Rscons
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
unless @echo == :command
|
unless @echo == :command
|
||||||
$stdout.puts "Failed command was: #{command_to_s(tc.command)}"
|
print_failed_command(tc.command)
|
||||||
end
|
end
|
||||||
raise BuildError.new("Failed to build #{tc.build_operation[:target]}")
|
failure = "Failed to build #{tc.build_operation[:target]}"
|
||||||
|
Ansi.write($stderr, :red, failure, :reset, "\n")
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -359,6 +371,9 @@ module Rscons
|
|||||||
ensure
|
ensure
|
||||||
cache.write
|
cache.write
|
||||||
end
|
end
|
||||||
|
if failure
|
||||||
|
raise BuildError.new(failure)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Clear all targets registered for the Environment.
|
# Clear all targets registered for the Environment.
|
||||||
@@ -398,16 +413,12 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [true,false,nil] Return value from Kernel.system().
|
# @return [true,false,nil] Return value from Kernel.system().
|
||||||
def execute(short_desc, command, options = {})
|
def execute(short_desc, command, options = {})
|
||||||
if @echo == :command
|
print_builder_run_message(short_desc, command)
|
||||||
puts command_to_s(command)
|
|
||||||
elsif @echo == :short
|
|
||||||
puts short_desc
|
|
||||||
end
|
|
||||||
env_args = options[:env] ? [options[:env]] : []
|
env_args = options[:env] ? [options[:env]] : []
|
||||||
options_args = options[:options] ? [options[:options]] : []
|
options_args = options[:options] ? [options[:options]] : []
|
||||||
system(*env_args, *Rscons.command_executer, *command, *options_args).tap do |result|
|
system(*env_args, *Rscons.command_executer, *command, *options_args).tap do |result|
|
||||||
unless result or @echo == :command
|
unless result or @echo == :command
|
||||||
$stdout.puts "Failed command was: #{command_to_s(command)}"
|
print_failed_command(command)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -451,6 +462,7 @@ module Rscons
|
|||||||
user_deps = user_deps.map {|ud| expand_varref(ud)}
|
user_deps = user_deps.map {|ud| expand_varref(ud)}
|
||||||
@user_deps[target] ||= []
|
@user_deps[target] ||= []
|
||||||
@user_deps[target] = (@user_deps[target] + user_deps).uniq
|
@user_deps[target] = (@user_deps[target] + user_deps).uniq
|
||||||
|
build_after(target, user_deps)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Manually record the given target(s) as needing to be built after the
|
# Manually record the given target(s) as needing to be built after the
|
||||||
@@ -491,6 +503,26 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Manually record the given side effect file(s) as being produced when the
|
||||||
|
# named target is produced.
|
||||||
|
#
|
||||||
|
# @since 1.13.0
|
||||||
|
#
|
||||||
|
# @param target [String]
|
||||||
|
# Target of a build operation.
|
||||||
|
# @param side_effects [Array<String>]
|
||||||
|
# File(s) produced when the target file is produced.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def produces(target, *side_effects)
|
||||||
|
target = expand_path(expand_varref(target))
|
||||||
|
side_effects = Array(side_effects).map do |side_effect|
|
||||||
|
expand_path(expand_varref(side_effect))
|
||||||
|
end.flatten
|
||||||
|
@side_effects[target] ||= []
|
||||||
|
@side_effects[target] += side_effects
|
||||||
|
end
|
||||||
|
|
||||||
# Return the list of user dependencies for a given target.
|
# Return the list of user dependencies for a given target.
|
||||||
#
|
#
|
||||||
# @param target [String] Target file name.
|
# @param target [String] Target file name.
|
||||||
@@ -642,7 +674,7 @@ module Rscons
|
|||||||
call_build_hooks[:post]
|
call_build_hooks[:post]
|
||||||
else
|
else
|
||||||
unless @echo == :command
|
unless @echo == :command
|
||||||
$stdout.puts "Failed command was: #{command_to_s(tc.command)}"
|
print_failed_command(tc.command)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -829,7 +861,7 @@ module Rscons
|
|||||||
varset_hash = @varset.to_h
|
varset_hash = @varset.to_h
|
||||||
varset_hash.keys.sort_by(&:to_s).each do |var|
|
varset_hash.keys.sort_by(&:to_s).each do |var|
|
||||||
var_str = var.is_a?(Symbol) ? var.inspect : var
|
var_str = var.is_a?(Symbol) ? var.inspect : var
|
||||||
puts "#{var_str} => #{varset_hash[var].inspect}"
|
Ansi.write($stdout, :cyan, var_str, :reset, " => #{varset_hash[var].inspect}\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -842,6 +874,40 @@ module Rscons
|
|||||||
@n_threads || Rscons.n_threads
|
@n_threads || Rscons.n_threads
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Print the builder run message, depending on the Environment's echo mode.
|
||||||
|
#
|
||||||
|
# @param short_description [String]
|
||||||
|
# Builder short description, printed if the echo mode is :short.
|
||||||
|
# @param command [Array<String>]
|
||||||
|
# Builder command, printed if the echo mode is :command.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def print_builder_run_message(short_description, command)
|
||||||
|
case @echo
|
||||||
|
when :command
|
||||||
|
if command.is_a?(Array)
|
||||||
|
message = command_to_s(command)
|
||||||
|
elsif command.is_a?(String)
|
||||||
|
message = command
|
||||||
|
elsif short_description.is_a?(String)
|
||||||
|
message = short_description
|
||||||
|
end
|
||||||
|
when :short
|
||||||
|
message = short_description if short_description
|
||||||
|
end
|
||||||
|
Ansi.write($stdout, :cyan, message, :reset, "\n") if message
|
||||||
|
end
|
||||||
|
|
||||||
|
# Print a failed command.
|
||||||
|
#
|
||||||
|
# @param command [Array<String>]
|
||||||
|
# Builder command.
|
||||||
|
#
|
||||||
|
# @return [void]
|
||||||
|
def print_failed_command(command)
|
||||||
|
Ansi.write($stdout, :red, "Failed command was: #{command_to_s(command)}", :reset, "\n")
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Add a build target.
|
# Add a build target.
|
||||||
@@ -874,13 +940,7 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def start_threaded_command(tc)
|
def start_threaded_command(tc)
|
||||||
if @echo == :command
|
print_builder_run_message(tc.short_description, tc.command)
|
||||||
puts command_to_s(tc.command)
|
|
||||||
elsif @echo == :short
|
|
||||||
if tc.short_description
|
|
||||||
puts tc.short_description
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
env_args = tc.system_env ? [tc.system_env] : []
|
env_args = tc.system_env ? [tc.system_env] : []
|
||||||
options_args = tc.system_options ? [tc.system_options] : []
|
options_args = tc.system_options ? [tc.system_options] : []
|
||||||
|
|||||||
+13
-10
@@ -9,9 +9,14 @@ module Rscons
|
|||||||
# @param build_dependencies [Hash]
|
# @param build_dependencies [Hash]
|
||||||
# Hash mapping targets to a set of build dependencies. A job will not be
|
# Hash mapping targets to a set of build dependencies. A job will not be
|
||||||
# returned as ready to run if any of its dependencies are still building.
|
# returned as ready to run if any of its dependencies are still building.
|
||||||
def initialize(build_dependencies)
|
# @param side_effects [Hash]
|
||||||
|
# Hash mapping targets to a set of side-effect files. A job will not be
|
||||||
|
# returned as ready to run if any of its dependencies is a side-effect
|
||||||
|
# of another target that has not yet been built.
|
||||||
|
def initialize(build_dependencies, side_effects)
|
||||||
@jobs = {}
|
@jobs = {}
|
||||||
@build_dependencies = build_dependencies
|
@build_dependencies = build_dependencies
|
||||||
|
@side_effects = side_effects
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add a job to the JobSet.
|
# Add a job to the JobSet.
|
||||||
@@ -47,18 +52,16 @@ module Rscons
|
|||||||
# @return [nil, Hash]
|
# @return [nil, Hash]
|
||||||
# The next job to run.
|
# The next job to run.
|
||||||
def get_next_job_to_run(targets_still_building)
|
def get_next_job_to_run(targets_still_building)
|
||||||
|
targets_not_built_yet = targets_still_building + @jobs.keys
|
||||||
|
side_effects = targets_not_built_yet.map do |target|
|
||||||
|
@side_effects[target] || []
|
||||||
|
end.flatten
|
||||||
|
targets_not_built_yet += side_effects
|
||||||
|
|
||||||
@jobs.keys.each do |target|
|
@jobs.keys.each do |target|
|
||||||
skip = false
|
skip = false
|
||||||
(@jobs[target][0][:sources] + (@build_dependencies[target] || []).to_a).each do |src|
|
(@jobs[target][0][:sources] + (@build_dependencies[target] || []).to_a).each do |src|
|
||||||
if @jobs.include?(src)
|
if targets_not_built_yet.include?(src)
|
||||||
# Skip this target because it depends on another target not yet
|
|
||||||
# built.
|
|
||||||
skip = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if targets_still_building.include?(src)
|
|
||||||
# Skip this target because it depends on another target that is
|
|
||||||
# currently being built.
|
|
||||||
skip = true
|
skip = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -143,6 +143,26 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a String representing the VarSet.
|
||||||
|
#
|
||||||
|
# @return [String] Representation of the VarSet.
|
||||||
|
def inspect
|
||||||
|
to_h.inspect
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return an array containing the values associated with the given keys.
|
||||||
|
#
|
||||||
|
# @param keys [Array<String, Symbol>]
|
||||||
|
# Keys to look up in the VarSet.
|
||||||
|
#
|
||||||
|
# @return [Array]
|
||||||
|
# An array containing the values associated with the given keys.
|
||||||
|
def values_at(*keys)
|
||||||
|
keys.map do |key|
|
||||||
|
self[key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Move all VarSet variables into the copy-on-access list.
|
# Move all VarSet variables into the copy-on-access list.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
# gem version
|
# gem version
|
||||||
VERSION = "1.11.1"
|
VERSION = "1.16.0"
|
||||||
end
|
end
|
||||||
+1
-2
@@ -18,12 +18,11 @@ Gem::Specification.new do |gem|
|
|||||||
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
||||||
gem.require_paths = ["lib"]
|
gem.require_paths = ["lib"]
|
||||||
|
|
||||||
gem.add_dependency "json", "~> 1.0"
|
gem.add_dependency "json", ">= 1.8", "< 3.0"
|
||||||
|
|
||||||
gem.add_development_dependency "rspec"
|
gem.add_development_dependency "rspec"
|
||||||
gem.add_development_dependency "rake"
|
gem.add_development_dependency "rake"
|
||||||
gem.add_development_dependency "simplecov"
|
gem.add_development_dependency "simplecov"
|
||||||
gem.add_development_dependency "yard"
|
gem.add_development_dependency "yard"
|
||||||
gem.add_development_dependency "rdoc"
|
gem.add_development_dependency "rdoc"
|
||||||
gem.add_development_dependency "redcarpet"
|
|
||||||
end
|
end
|
||||||
+202
-22
@@ -91,6 +91,7 @@ end
|
|||||||
$LOAD_PATH.unshift(#{@owd.inspect} + "/lib")
|
$LOAD_PATH.unshift(#{@owd.inspect} + "/lib")
|
||||||
# force color off
|
# force color off
|
||||||
ENV["TERM"] = nil
|
ENV["TERM"] = nil
|
||||||
|
#{options[:ruby_setup_code]}
|
||||||
EOF
|
EOF
|
||||||
end
|
end
|
||||||
stdout, stderr, status = nil, nil, nil
|
stdout, stderr, status = nil, nil, nil
|
||||||
@@ -125,7 +126,7 @@ EOF
|
|||||||
result = run_test(rsconsfile: "command.rb")
|
result = run_test(rsconsfile: "command.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(lines(result.stdout)).to eq [
|
expect(lines(result.stdout)).to eq [
|
||||||
'gcc -c -o build/simple.o -MMD -MF build/simple.mf simple.c',
|
'gcc -c -o build/simple.o -MMD -MF build/simple.mf -MT TARGET simple.c',
|
||||||
"gcc -o simple.exe build/simple.o",
|
"gcc -o simple.exe build/simple.o",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@@ -194,7 +195,7 @@ EOF
|
|||||||
result = run_test(rsconsfile: "command.rb")
|
result = run_test(rsconsfile: "command.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(lines(result.stdout)).to eq [
|
expect(lines(result.stdout)).to eq [
|
||||||
'gcc -c -o build/simple.o -MMD -MF build/simple.mf simple.c',
|
'gcc -c -o build/simple.o -MMD -MF build/simple.mf -MT TARGET simple.c',
|
||||||
"gcc -o simple.exe build/simple.o",
|
"gcc -o simple.exe build/simple.o",
|
||||||
]
|
]
|
||||||
result = run_test(rsconsfile: "link_flag_change.rb")
|
result = run_test(rsconsfile: "link_flag_change.rb")
|
||||||
@@ -249,8 +250,8 @@ EOF
|
|||||||
result = run_test(rsconsfile: "carat.rb")
|
result = run_test(rsconsfile: "carat.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(Set[*lines(result.stdout)]).to eq Set[
|
expect(Set[*lines(result.stdout)]).to eq Set[
|
||||||
%q{gcc -c -o build_root/one.o -MMD -MF build_root/one.mf -Isrc/one/ -Isrc/two/ build_root/one.c},
|
%q{gcc -c -o build_root/one.o -MMD -MF build_root/one.mf -MT TARGET -Isrc -Isrc/one -Isrc/two build_root/one.c},
|
||||||
%q{gcc -c -o build_root/src/two/two.o -MMD -MF build_root/src/two/two.mf -Isrc/one/ -Isrc/two/ src/two/two.c},
|
%q{gcc -c -o build_root/src/two/two.o -MMD -MF build_root/src/two/two.mf -MT TARGET -Isrc -Isrc/one -Isrc/two src/two/two.c},
|
||||||
%Q{gcc -o build_dir.exe build_root/src/two/two.o build_root/one.o},
|
%Q{gcc -o build_dir.exe build_root/src/two/two.o build_root/one.o},
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@@ -329,9 +330,9 @@ EOF
|
|||||||
result = run_test
|
result = run_test
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(Set[*lines(result.stdout)]).to eq Set[
|
expect(Set[*lines(result.stdout)]).to eq Set[
|
||||||
%q{gcc -c -o debug/program.o -MMD -MF debug/program.mf '-DSTRING="Debug Version"' -O2 src/program.c},
|
%q{gcc -c -o debug/program.o -MMD -MF debug/program.mf -MT TARGET '-DSTRING="Debug Version"' -O2 src/program.c},
|
||||||
%Q{gcc -o program-debug.exe debug/program.o},
|
%Q{gcc -o program-debug.exe debug/program.o},
|
||||||
%q{gcc -c -o release/program.o -MMD -MF release/program.mf '-DSTRING="Release Version"' -O2 src/program.c},
|
%q{gcc -c -o release/program.o -MMD -MF release/program.mf -MT TARGET '-DSTRING="Release Version"' -O2 src/program.c},
|
||||||
%Q{gcc -o program-release.exe release/program.o},
|
%Q{gcc -o program-release.exe release/program.o},
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@@ -341,7 +342,7 @@ EOF
|
|||||||
result = run_test(rsconsfile: "clone_all.rb")
|
result = run_test(rsconsfile: "clone_all.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(lines(result.stdout)).to eq [
|
expect(lines(result.stdout)).to eq [
|
||||||
%q{gcc -c -o build/program.o -MMD -MF build/program.mf -DSTRING="Hello" -O2 src/program.c},
|
%q{gcc -c -o build/program.o -MMD -MF build/program.mf -MT TARGET -DSTRING="Hello" -O2 src/program.c},
|
||||||
%q{post build/program.o},
|
%q{post build/program.o},
|
||||||
%Q{gcc -o program.exe build/program.o},
|
%Q{gcc -o program.exe build/program.o},
|
||||||
%q{post program.exe},
|
%q{post program.exe},
|
||||||
@@ -364,8 +365,8 @@ EOF
|
|||||||
result = run_test
|
result = run_test
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(Set[*lines(result.stdout)]).to eq Set[
|
expect(Set[*lines(result.stdout)]).to eq Set[
|
||||||
'gcc -c -o one.o -MMD -MF one.mf -DONE one.c',
|
'gcc -c -o one.o -MMD -MF one.mf -MT TARGET -DONE one.c',
|
||||||
'gcc -c -o build/two.o -MMD -MF build/two.mf two.c',
|
'gcc -c -o build/two.o -MMD -MF build/two.mf -MT TARGET two.c',
|
||||||
"gcc -o two_sources.exe one.o build/two.o",
|
"gcc -o two_sources.exe one.o build/two.o",
|
||||||
]
|
]
|
||||||
expect(File.exists?("two_sources.exe")).to be_truthy
|
expect(File.exists?("two_sources.exe")).to be_truthy
|
||||||
@@ -377,10 +378,10 @@ EOF
|
|||||||
result = run_test
|
result = run_test
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(Set[*lines(result.stdout)]).to eq Set[
|
expect(Set[*lines(result.stdout)]).to eq Set[
|
||||||
'gcc -c -o build/one.o -MMD -MF build/one.mf -Dmake_lib one.c',
|
'gcc -c -o build/one.o -MMD -MF build/one.mf -MT TARGET -Dmake_lib one.c',
|
||||||
'gcc -c -o build/two.o -MMD -MF build/two.mf -Dmake_lib two.c',
|
'gcc -c -o build/two.o -MMD -MF build/two.mf -MT TARGET -Dmake_lib two.c',
|
||||||
'ar rcs lib.a build/one.o build/two.o',
|
'ar rcs lib.a build/one.o build/two.o',
|
||||||
'gcc -c -o build/three.o -MMD -MF build/three.mf three.c',
|
'gcc -c -o build/three.o -MMD -MF build/three.mf -MT TARGET three.c',
|
||||||
"gcc -o library.exe lib.a build/three.o",
|
"gcc -o library.exe lib.a build/three.o",
|
||||||
]
|
]
|
||||||
expect(File.exists?("library.exe")).to be_truthy
|
expect(File.exists?("library.exe")).to be_truthy
|
||||||
@@ -392,8 +393,8 @@ EOF
|
|||||||
result = run_test(rsconsfile: "build_hooks.rb")
|
result = run_test(rsconsfile: "build_hooks.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(Set[*lines(result.stdout)]).to eq Set[
|
expect(Set[*lines(result.stdout)]).to eq Set[
|
||||||
'gcc -c -o build_one/one.o -MMD -MF build_one/one.mf -Isrc/one/ -Isrc/two/ -O1 src/one/one.c',
|
'gcc -c -o build_one/one.o -MMD -MF build_one/one.mf -MT TARGET -Isrc/one -Isrc/two -O1 src/one/one.c',
|
||||||
'gcc -c -o build_two/two.o -MMD -MF build_two/two.mf -Isrc/one/ -Isrc/two/ -O2 src/two/two.c',
|
'gcc -c -o build_two/two.o -MMD -MF build_two/two.mf -MT TARGET -Isrc/one -Isrc/two -O2 src/two/two.c',
|
||||||
'gcc -o build_hook.exe build_one/one.o build_two/two.o',
|
'gcc -o build_hook.exe build_one/one.o build_two/two.o',
|
||||||
]
|
]
|
||||||
expect(`./build_hook.exe`).to eq "Hello from two()\n"
|
expect(`./build_hook.exe`).to eq "Hello from two()\n"
|
||||||
@@ -429,11 +430,31 @@ EOF
|
|||||||
test_dir("d")
|
test_dir("d")
|
||||||
result = run_test
|
result = run_test
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(lines(result.stdout)).to eq [
|
slines = lines(result.stdout)
|
||||||
"gdc -c -o build/main.o main.d",
|
expect(slines).to include("gdc -c -o build/main.o -MMD -MF build/main.mf -MT TARGET main.d")
|
||||||
"gdc -o hello-d.exe build/main.o",
|
expect(slines).to include("gdc -c -o build/mod.o -MMD -MF build/mod.mf -MT TARGET mod.d")
|
||||||
]
|
expect(slines.last).to eq("gdc -o hello-d.exe build/main.o build/mod.o")
|
||||||
expect(`./hello-d.exe`.rstrip).to eq "Hello from D!"
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does dependency generation for D sources" do
|
||||||
|
test_dir("d")
|
||||||
|
result = run_test
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
slines = lines(result.stdout)
|
||||||
|
expect(slines).to include("gdc -c -o build/main.o -MMD -MF build/main.mf -MT TARGET main.d")
|
||||||
|
expect(slines).to include("gdc -c -o build/mod.o -MMD -MF build/mod.mf -MT TARGET mod.d")
|
||||||
|
expect(slines.last).to eq("gdc -o hello-d.exe build/main.o build/mod.o")
|
||||||
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 42!"
|
||||||
|
fcontents = File.read("mod.d", mode: "rb").sub("42", "33")
|
||||||
|
File.open("mod.d", "wb") {|fh| fh.write(fcontents)}
|
||||||
|
result = run_test
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
slines = lines(result.stdout)
|
||||||
|
expect(slines).to include("gdc -c -o build/main.o -MMD -MF build/main.mf -MT TARGET main.d")
|
||||||
|
expect(slines).to include("gdc -c -o build/mod.o -MMD -MF build/mod.mf -MT TARGET mod.d")
|
||||||
|
expect(slines.last).to eq("gdc -o hello-d.exe build/main.o build/mod.o")
|
||||||
|
expect(`./hello-d.exe`.rstrip).to eq "Hello from D, value is 33!"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates shared libraries using D" do
|
it "creates shared libraries using D" do
|
||||||
@@ -746,6 +767,68 @@ EOF
|
|||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "orders builds to respect user dependencies" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "user_dep_build_order.rb", rscons_args: %w[-j4])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
end
|
||||||
|
|
||||||
|
it "waits for all parallelized builds to complete if one fails" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "wait_for_builds_on_failure.rb", rscons_args: %w[-j4])
|
||||||
|
expect(result.status).to_not eq 0
|
||||||
|
expect(result.stderr).to match /Failed to build foo_1/
|
||||||
|
expect(result.stderr).to match /Failed to build foo_2/
|
||||||
|
expect(result.stderr).to match /Failed to build foo_3/
|
||||||
|
expect(result.stderr).to match /Failed to build foo_4/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "clones n_threads attribute when cloning an Environment" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "clone_n_threads.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(lines(result.stdout)).to eq ["165"]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a builder's short description with 'command' echo mode if there is no command" do
|
||||||
|
test_dir("build_dir")
|
||||||
|
|
||||||
|
result = run_test(rsconsfile: "echo_command_ruby_builder.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(lines(result.stdout)).to eq ["Install inst.exe"]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "supports a string for a builder's echoed 'command' with Environment#print_builder_run_message" do
|
||||||
|
test_dir("build_dir")
|
||||||
|
|
||||||
|
result = run_test(rsconsfile: "echo_command_string.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(lines(result.stdout)).to eq ["MyBuilder foo command"]
|
||||||
|
end
|
||||||
|
|
||||||
|
context "colored output" do
|
||||||
|
it "does not output in color with --color=off" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rscons_args: %w[--color=off])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to_not match(/\e\[/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "displays output in color with --color=force" do
|
||||||
|
test_dir("simple")
|
||||||
|
|
||||||
|
result = run_test(rscons_args: %w[--color=force])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to match(/\e\[/)
|
||||||
|
|
||||||
|
File.open("simple.c", "wb") do |fh|
|
||||||
|
fh.write("foobar")
|
||||||
|
end
|
||||||
|
result = run_test(rscons_args: %w[--color=force])
|
||||||
|
expect(result.stderr).to match(/\e\[/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "backward compatibility" do
|
context "backward compatibility" do
|
||||||
it "allows a builder to call Environment#run_builder in a non-threaded manner" do
|
it "allows a builder to call Environment#run_builder in a non-threaded manner" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
@@ -768,6 +851,21 @@ EOF
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "prints the failed build command for a non-threaded builder" do
|
||||||
|
test_dir("simple")
|
||||||
|
File.open("simple.c", "wb") do |fh|
|
||||||
|
fh.write(<<EOF)
|
||||||
|
void one()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
result = run_test(rsconsfile: "build_sources.rb")
|
||||||
|
expect(result.status).to_not eq 0
|
||||||
|
expect(result.stderr).to match /main/
|
||||||
|
expect(result.stdout).to match /Failed command was: gcc/
|
||||||
|
end
|
||||||
|
|
||||||
it "prints the failed build command for a threaded builder when called via Environment#run_builder without delayed execution" do
|
it "prints the failed build command for a threaded builder when called via Environment#run_builder without delayed execution" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
File.open("simple.c", "wb") do |fh|
|
File.open("simple.c", "wb") do |fh|
|
||||||
@@ -796,8 +894,8 @@ EOF
|
|||||||
result = run_test(rsconsfile: "backward_compatible_build_hooks.rb")
|
result = run_test(rsconsfile: "backward_compatible_build_hooks.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(Set[*lines(result.stdout)]).to eq Set[
|
expect(Set[*lines(result.stdout)]).to eq Set[
|
||||||
'gcc -c -o one.o -MMD -MF one.mf -Isrc/one/ -Isrc/two/ -O1 src/two/two.c',
|
'gcc -c -o one.o -MMD -MF one.mf -MT TARGET -Isrc -Isrc/one -Isrc/two -O1 src/two/two.c',
|
||||||
'gcc -c -o two.o -MMD -MF two.mf -Isrc/one/ -Isrc/two/ -O2 src/two/two.c'
|
'gcc -c -o two.o -MMD -MF two.mf -MT TARGET -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
|
||||||
@@ -1164,6 +1262,81 @@ EOF
|
|||||||
"LD simple.exe",
|
"LD simple.exe",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "allows a VarSet to be passed in as the command parameter" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_varset.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(lines(result.stdout)).to eq [
|
||||||
|
"TestBuilder foo",
|
||||||
|
]
|
||||||
|
result = run_test(rsconsfile: "cache_varset.rb")
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(result.stdout).to eq ""
|
||||||
|
end
|
||||||
|
|
||||||
|
context "debugging" do
|
||||||
|
it "prints a message when the target does not exist" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because it does not exist on disk/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when there is no cached build information for the target" do
|
||||||
|
test_dir("simple")
|
||||||
|
FileUtils.touch("foo.o")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because there is no cached build information for it/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when the target file has changed on disk" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
File.open("foo.o", "wb") {|fh| fh.puts "hi"}
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because it has been changed on disk since being built last/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when the command has changed" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb", rscons_args: %w[command_change=yes])
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because the command used to build it has changed/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when strict_deps is in use and the set of dependencies does not match" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb", rscons_args: %w[strict_deps1=yes])
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb", rscons_args: %w[strict_deps2=yes])
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because the :strict_deps option is given and the set of dependencies does not match the previous set of dependencies/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when there is a new dependency" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb", rscons_args: %w[new_dep=yes])
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because there are new dependencies/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when there is a new user-specified dependency" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb", rscons_args: %w[new_user_dep=yes])
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because the set of user-specified dependency files has changed/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "prints a message when a dependency file has changed" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
f = File.read("simple.c", mode: "rb")
|
||||||
|
f += "\n"
|
||||||
|
File.open("simple.c", "wb") do |fh|
|
||||||
|
fh.write(f)
|
||||||
|
end
|
||||||
|
result = run_test(rsconsfile: "cache_debugging.rb")
|
||||||
|
expect(result.stdout).to match /Target foo\.o needs rebuilding because dependency file simple\.c has changed/
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "Object builder" do
|
context "Object builder" do
|
||||||
@@ -1181,7 +1354,7 @@ EOF
|
|||||||
result = run_test(rsconsfile: "override_depfilesuffix.rb")
|
result = run_test(rsconsfile: "override_depfilesuffix.rb")
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(lines(result.stdout)).to eq [
|
expect(lines(result.stdout)).to eq [
|
||||||
"gcc -c -o simple.o -MMD -MF simple.deppy simple.c",
|
"gcc -c -o simple.o -MMD -MF simple.deppy -MT TARGET simple.c",
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1245,6 +1418,13 @@ EOF
|
|||||||
result = run_test(rsconsfile: "build_after.rb", rscons_args: %w[-j 4])
|
result = run_test(rsconsfile: "build_after.rb", rscons_args: %w[-j 4])
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "allows the user to specify side-effect files produced by another builder" do
|
||||||
|
test_dir("custom_builder")
|
||||||
|
result = run_test(rsconsfile: "produces.rb", rscons_args: %w[-j 4])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(File.exists?("copy_inc.h")).to be_truthy
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "CLI" do
|
context "CLI" do
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
module Rscons
|
||||||
|
describe Ansi do
|
||||||
|
describe ".do_ansi?" do
|
||||||
|
|
||||||
|
context "on Windows" do
|
||||||
|
it "returns true when IO is a fifo on an xterm" do
|
||||||
|
stub_const("RUBY_PLATFORM", "mingw")
|
||||||
|
expect(ENV).to receive(:[]).with("TERM").and_return("xterm")
|
||||||
|
io = double
|
||||||
|
expect(io).to receive(:stat).and_return(Struct.new(:ftype).new("fifo"))
|
||||||
|
expect(Ansi.__send__(:do_ansi?, io)).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when TERM is not set appropriately" do
|
||||||
|
stub_const("RUBY_PLATFORM", "mingw")
|
||||||
|
expect(ENV).to receive(:[]).with("TERM").and_return(nil)
|
||||||
|
io = double
|
||||||
|
expect(Ansi.__send__(:do_ansi?, io)).to be_falsey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "on POSIX" do
|
||||||
|
it "returns true when IO is a TTY" do
|
||||||
|
stub_const("RUBY_PLATFORM", "linux")
|
||||||
|
io = double
|
||||||
|
expect(io).to receive(:tty?).and_return(true)
|
||||||
|
expect(Ansi.__send__(:do_ansi?, io)).to be_truthy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -190,38 +190,6 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#execute" do
|
|
||||||
context "with echo: :short" do
|
|
||||||
context "with no errors" do
|
|
||||||
it "prints the short description and executes the command" do
|
|
||||||
env = Environment.new(echo: :short)
|
|
||||||
expect(env).to receive(:puts).with("short desc")
|
|
||||||
expect(env).to receive(:system).with(*Rscons.command_executer, "a", "command").and_return(true)
|
|
||||||
env.execute("short desc", ["a", "command"])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with errors" do
|
|
||||||
it "prints the short description, executes the command, and prints the failed command line" do
|
|
||||||
env = Environment.new(echo: :short)
|
|
||||||
expect(env).to receive(:puts).with("short desc")
|
|
||||||
expect(env).to receive(:system).with(*Rscons.command_executer, "a", "command").and_return(false)
|
|
||||||
expect($stdout).to receive(:puts).with("Failed command was: a command")
|
|
||||||
env.execute("short desc", ["a", "command"])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with echo: :command" do
|
|
||||||
it "prints the command executed and executes the command" do
|
|
||||||
env = Environment.new(echo: :command)
|
|
||||||
expect(env).to receive(:puts).with("a command '--arg=val with spaces'")
|
|
||||||
expect(env).to receive(:system).with({modified: :environment}, *Rscons.command_executer, "a", "command", "--arg=val with spaces", {opt: :val}).and_return(false)
|
|
||||||
env.execute("short desc", ["a", "command", "--arg=val with spaces"], env: {modified: :environment}, options: {opt: :val})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#method_missing" do
|
describe "#method_missing" do
|
||||||
it "calls the original method missing when the target method is not a known builder" do
|
it "calls the original method missing when the target method is not a known builder" do
|
||||||
env = Environment.new
|
env = Environment.new
|
||||||
|
|||||||
@@ -199,5 +199,14 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#values_at" do
|
||||||
|
it "returns an array of the values associated with the given keys" do
|
||||||
|
v = VarSet.new({"fuz" => "a string", "foo" => 42, "bar" => :baz,
|
||||||
|
"qax" => [3, 6], "qux" => {a: :b}})
|
||||||
|
expect(v.values_at).to eq []
|
||||||
|
expect(v.values_at(*%w[fuz qux qax])).to eq ["a string", {a: :b}, [3, 6]]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Reference in new issue
Block a user