Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5263ea03c6 | ||
|
|
6c91823ce2 | ||
|
|
8deb1eb6f8 | ||
|
|
6d6319799a | ||
|
|
694642dfbd | ||
|
|
6dd70ff65e | ||
|
|
eca01c38df | ||
|
|
4ad6ce1d9c | ||
|
|
a49ebc486e | ||
|
|
74d19ea235 | ||
|
|
d7a6d69a92 | ||
|
|
11864eb55b | ||
|
|
387c40176b | ||
|
|
f1b24ee8ba | ||
|
|
ef3150db0f | ||
|
|
ed4fb8b681 | ||
|
|
3a3f6d6d27 | ||
|
|
20affc0e1d | ||
|
|
010607d3b0 | ||
|
|
b7f609b7e8 | ||
|
|
10d4c647b9 | ||
|
|
db2ec82a25 | ||
|
|
aa192d7567 | ||
|
|
ed5d6e9e49 | ||
|
|
3436dc3a64 | ||
|
|
df52a7e0e1 | ||
|
|
6bd7e6f852 | ||
|
|
19a23c2aa9 | ||
|
|
c7e4e1ad9b | ||
|
|
43df46018c | ||
|
|
8cbb9fa30e | ||
|
|
1880e6650e | ||
|
|
d31b4725d2 | ||
|
|
6f242a1c64 | ||
|
|
c7943bc2cc | ||
|
|
b5826bd7f4 | ||
|
|
05bbea6fa1 | ||
|
|
68468b6422 | ||
|
|
80a80a7cb0 | ||
|
|
178940cd5d | ||
|
|
145d51c825 | ||
|
|
a11fab43cb | ||
|
|
83226e894d | ||
|
|
b454208117 | ||
|
|
df420fdf5c | ||
|
|
f3bf325c88 | ||
|
|
f815952ab3 | ||
|
|
1af3c5c9a4 | ||
|
|
dce88ece14 | ||
|
|
2655c119e4 | ||
|
|
221cde7e5f | ||
|
|
adcee373df | ||
|
|
e58b8bd109 | ||
|
|
8a1dfb0785 | ||
|
|
d315f86a36 | ||
|
|
0d46d616dd | ||
|
|
032e6d5d0a | ||
|
|
c9946da193 | ||
|
|
599d10b50f | ||
|
|
18c6c69871 | ||
|
|
2ffdf82d9a | ||
|
|
15e5d15424 | ||
|
|
a99e6e81b2 | ||
|
|
1509c95176 | ||
|
|
c7bba77581 | ||
|
|
957fd8c86d | ||
|
|
7e707e7e3b | ||
|
|
2be738be4f | ||
|
|
7b3bffd329 | ||
|
|
06cb4b7a55 | ||
|
|
bfbbc19728 | ||
|
|
28e56251dd | ||
|
|
2d8e08b493 | ||
|
|
5cef9896ac | ||
|
|
6344692087 | ||
|
|
267fc7124d | ||
|
|
e694199f33 | ||
|
|
4ed584701a | ||
|
|
5de52620e4 | ||
|
|
9cc59a35f0 | ||
|
|
ca445f5733 | ||
|
|
7534b29e26 | ||
|
|
800e7a51a4 | ||
|
|
5d36aa74a0 | ||
|
|
01851c2872 | ||
|
|
5fe55a584e | ||
|
|
9c13634eaf | ||
|
|
e4adaab003 | ||
|
|
6b8fda706d | ||
|
|
ef4f9882cd | ||
|
|
7a31039e35 | ||
|
|
3e4897c04b | ||
|
|
d46dc2014c | ||
|
|
9cfc0c20b7 | ||
|
|
19a00a7b84 | ||
|
|
9b6d2c5111 | ||
|
|
6a0ccad804 | ||
|
|
dab870854a | ||
|
|
695bf84092 | ||
|
|
7cba8c8424 | ||
|
|
551b8fa365 | ||
|
|
3601359c08 | ||
|
|
e1d8dfbab6 | ||
|
|
c69da1044d |
No files matched your search
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
|
/.bundle/
|
||||||
/.yardoc/
|
/.yardoc/
|
||||||
/_yardoc/
|
/_yardoc/
|
||||||
|
/build_test_run/
|
||||||
/coverage/
|
/coverage/
|
||||||
/doc/
|
/doc/
|
||||||
/pkg/
|
/pkg/
|
||||||
/build_test_run/
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
rscons (1.9.3)
|
rscons (1.11.0)
|
||||||
json (~> 1.0)
|
json (~> 1.0)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
|
|||||||
@@ -7,31 +7,30 @@ in Ruby.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add this line to your application's Gemfile:
|
|
||||||
|
|
||||||
gem "rscons"
|
|
||||||
|
|
||||||
And then execute:
|
|
||||||
|
|
||||||
$ bundle install
|
|
||||||
|
|
||||||
Or install it yourself as:
|
|
||||||
|
|
||||||
$ gem install rscons
|
$ gem install rscons
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Rscons is implemented as a Ruby library and distributed as a gem.
|
### Standalone
|
||||||
It also provides a "rscons" executable which can evaluate a build script (by
|
|
||||||
default named Rsconsfile or Rsconsfile.rb).
|
Rscons provides a standalone executable ("rscons") with a command-line
|
||||||
It can also be used from rake or from a standalone Ruby script.
|
interface. The rscons executable will read a build script (by default named
|
||||||
|
Rsconsfile or Rsconsfile.rb) and execute its contents.
|
||||||
|
|
||||||
|
### With Rake
|
||||||
|
|
||||||
|
Rscons can be used with rake as well. The same content that would be written
|
||||||
|
in Rsconsfile can be placed in a Rakefile. It could be placed within a rake
|
||||||
|
task block or split among multiple tasks.
|
||||||
|
|
||||||
|
## Example Build Scripts
|
||||||
|
|
||||||
### Example: Building a C Program
|
### Example: Building a C Program
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
Rscons::Environment.new do |env|
|
Rscons::Environment.new do |env|
|
||||||
env["CFLAGS"] << "-Wall"
|
env["CFLAGS"] << "-Wall"
|
||||||
env.Program("program", Dir["**/*.c"])
|
env.Program("program", Dir["src/**/*.c"])
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -40,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["**/*.d"])
|
env.Program("program", Dir["src/**/*.d"])
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -196,25 +195,6 @@ Rscons::Environment.new do |env|
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
Each build hook block will be invoked for every build operation, so the block
|
|
||||||
should test the target or sources if its action should only apply to some
|
|
||||||
subset of build targets or source files.
|
|
||||||
|
|
||||||
Build hooks can alter construction variable values for a particular build
|
|
||||||
operation. Build hooks can also register new build targets.
|
|
||||||
|
|
||||||
The `build_op` parameter to the build hook block is a Hash describing the
|
|
||||||
build operation with the following keys:
|
|
||||||
* `:builder` - `Builder` instance in use
|
|
||||||
* `:env` - `Environment` calling the build hook; note that this may be
|
|
||||||
different from the Environment that the build hook was added to in the case
|
|
||||||
that the original Environment was cloned with build hooks!
|
|
||||||
* `:target` - `String` name of the target file
|
|
||||||
* `:sources` - `Array` of the source files
|
|
||||||
* `:vars` - `Rscons::VarSet` containing the construction variables to use.
|
|
||||||
The build hook can overwrite entries in `build_op[:vars]` to alter the
|
|
||||||
construction variables in use for this specific build operation.
|
|
||||||
|
|
||||||
### Example: Creating a static library
|
### Example: Creating a static library
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
@@ -233,8 +213,52 @@ end
|
|||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
|
### Environments
|
||||||
|
|
||||||
|
The Environment is the main top-level object that Rscons operates with. An
|
||||||
|
Environment must be created by the user in order to build anything. All build
|
||||||
|
targets are registered within an Environment. In many cases only a single
|
||||||
|
Environment will be needed, but more than one can be created (either from
|
||||||
|
scratch or by cloning another existing Environment) if needed.
|
||||||
|
|
||||||
|
An Environment consists of:
|
||||||
|
|
||||||
|
* a collection of builders
|
||||||
|
* a collection of construction variables used by those builders
|
||||||
|
* a mapping of build directories from source directories
|
||||||
|
* a default build root to apply if no specific build directories are matched
|
||||||
|
* a collection of user-defined build targets
|
||||||
|
* a collection of user-defined build hooks
|
||||||
|
|
||||||
|
When cloning an environment, by default the construction variables, builders,
|
||||||
|
build hooks, build directories, and build root are cloned, but the new
|
||||||
|
environment does not inherit any of the registered build targets.
|
||||||
|
|
||||||
|
The set of environment attributes that are cloned is controllable via the
|
||||||
|
`:clone` option to the `#clone` method.
|
||||||
|
For example, `env.clone(clone: [:variables, :builders])` will include
|
||||||
|
construction variables, and builders but not build hooks, build directories, or
|
||||||
|
the build root.
|
||||||
|
|
||||||
|
The set of pending targets is never cloned.
|
||||||
|
|
||||||
|
Cloned environments contain "deep copies" of construction variables.
|
||||||
|
For example, in:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
base_env = Rscons::Environment.new
|
||||||
|
base_env["CPPPATH"] = ["one", "two"]
|
||||||
|
cloned_env = base_env.clone
|
||||||
|
cloned_env["CPPPATH"] << "three"
|
||||||
|
```
|
||||||
|
|
||||||
|
`base_env["CPPPATH"]` will not include "three".
|
||||||
|
|
||||||
### Builders
|
### Builders
|
||||||
|
|
||||||
|
Builders are the workhorses that Rscons uses to execute build operations.
|
||||||
|
Each builder is specialized to perform a particular operation.
|
||||||
|
|
||||||
Rscons ships with a number of builders:
|
Rscons ships with a number of builders:
|
||||||
|
|
||||||
* Command, which executes a user-defined command to produce the target.
|
* Command, which executes a user-defined command to produce the target.
|
||||||
@@ -246,9 +270,13 @@ Rscons ships with a number of builders:
|
|||||||
* Object, which compiles source files to produce an object file.
|
* Object, which compiles source files to produce an object file.
|
||||||
* Preprocess, which invokes the C/C++ preprocessor on a source file.
|
* Preprocess, which invokes the C/C++ preprocessor on a source file.
|
||||||
* Program, which links object files to produce an executable.
|
* Program, which links object files to produce an executable.
|
||||||
|
* SharedLibrary, which links object files to produce a dynamically loadable
|
||||||
|
library.
|
||||||
|
* SharedObject, which compiles source files to produce an object file, in a way
|
||||||
|
that is able to be used to create a shared library.
|
||||||
|
|
||||||
If you want to create an Environment that does not contain any builders,
|
If you want to create an Environment that does not contain any builders,
|
||||||
you can use the `exclude_builders` key to the Environment constructor.
|
you can use the `:exclude_builders` key to the Environment constructor.
|
||||||
|
|
||||||
#### Command
|
#### Command
|
||||||
|
|
||||||
@@ -313,7 +341,9 @@ env.Object(target, sources)
|
|||||||
env.Object("module.o", "module.c")
|
env.Object("module.o", "module.c")
|
||||||
```
|
```
|
||||||
|
|
||||||
The Object builder compiles the given sources to an object file.
|
The Object builder compiles the given sources to an object file. Although it
|
||||||
|
can be called explicitly, it is more commonly implicitly called by the Program
|
||||||
|
builder.
|
||||||
|
|
||||||
#### Preprocess
|
#### Preprocess
|
||||||
|
|
||||||
@@ -336,43 +366,121 @@ env.Program("myprog", Dir["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.
|
||||||
Object files or source files can be given as `sources`.
|
Object files or source files can be given as `sources`. A platform-dependent
|
||||||
|
program suffix will be appended to the target name if one is not specified.
|
||||||
|
This can be controlled with the `PROGSUFFIX` construction variable.
|
||||||
|
|
||||||
### Managing Environments
|
#### SharedLibrary
|
||||||
|
|
||||||
An Rscons::Environment consists of:
|
|
||||||
|
|
||||||
* a collection of construction variables
|
|
||||||
* a collection of builders
|
|
||||||
* a mapping of build directories from source directories
|
|
||||||
* a default build root to apply if no build directories are matched
|
|
||||||
* a collection of targets to build
|
|
||||||
* a collection of build hooks
|
|
||||||
|
|
||||||
When cloning an environment, by default the construction variables and builders
|
|
||||||
are cloned, but the new environment does not inherit any of the targets, build
|
|
||||||
hooks, build directories, or the build root from the source environment.
|
|
||||||
|
|
||||||
The set of environment attributes that are cloned is controllable via the
|
|
||||||
`:clone` option to the `#clone` method.
|
|
||||||
For example, `env.clone(clone: :all)` will include construction variables,
|
|
||||||
builders, build hooks, build directories, and the build root.
|
|
||||||
|
|
||||||
The set of pending targets is never cloned.
|
|
||||||
|
|
||||||
Cloned environments contain "deep copies" of construction variables.
|
|
||||||
For example, in:
|
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
base_env = Rscons::Environment.new
|
env.SharedLibrary(target, sources)
|
||||||
base_env["CPPPATH"] = ["one", "two"]
|
# Example
|
||||||
cloned_env = base_env.clone
|
env.SharedLibrary("mydll", Dir["src/**/*.cc"])
|
||||||
cloned_env["CPPPATH"] << "three"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`base_env["CPPPATH"]` will not include "three".
|
The SharedLibrary builder compiles and links the given sources to a dynamically
|
||||||
|
loadable library. Object files or source files can be given as `sources`.
|
||||||
|
A platform-dependent prefix and suffix will be appended to the target name if
|
||||||
|
they are not specified by the user. These values can be controlled by
|
||||||
|
overriding the `SHLIBPREFIX` and `SHLIBSUFFIX` construction variables.
|
||||||
|
|
||||||
#### Build Hooks
|
#### SharedObject
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
env.SharedObject(target, sources)
|
||||||
|
# Example
|
||||||
|
env.SharedObject("lib_module.o", "lib_module.c")
|
||||||
|
```
|
||||||
|
|
||||||
|
The SharedObject builder compiles the given sources to an object file. Any
|
||||||
|
compilation flags necessary to build the object file in a manner that allows it
|
||||||
|
to be used to create a shared library are added. Although it can be called
|
||||||
|
explicitly, it is more commonly implicitly called by the SharedLibrary builder.
|
||||||
|
|
||||||
|
### Construction Variables
|
||||||
|
|
||||||
|
Construction variables are used to define the toolset and any build options
|
||||||
|
that Rscons will use to build a project. The default construction variable
|
||||||
|
values are configured to build applications using gcc. However, all
|
||||||
|
construction variables can be overridden by the user.
|
||||||
|
|
||||||
|
| Name | Type | Description | Default |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| AR | String | Static library archiver executable | "ar" |
|
||||||
|
| ARCMD | Array | Static library archiver command line | ["${AR}", "${ARFLAGS}", "${_TARGET}", "${_SOURCES}"] |
|
||||||
|
| ARFLAGS | Array | Static library archiver flags | ["rcs"] |
|
||||||
|
| AS | String | Assembler executable | "${CC}" |
|
||||||
|
| ASCMD | Array | Assembler command line | ["${AS}", "-c", "-o", "${_TARGET}", "${ASDEPGEN}", "${INCPREFIX}${ASPPPATH}", "${ASPPFLAGS}", "${ASFLAGS}", "${_SOURCES}"] |
|
||||||
|
| ASDEPGEN | Array | Assembly dependency generation flags | ["-MMD", "-MF", "${_DEPFILE}"] |
|
||||||
|
| ASFLAGS | Array | Assembler flags | [] |
|
||||||
|
| ASPPFLAGS | Array | Assembler preprocessor flags | ["${CPPFLAGS}"] |
|
||||||
|
| ASPPPATH | Array | Assembler preprocessor path | ["${CPPPATH}"] |
|
||||||
|
| ASSUFFIX | Array | Assembly file suffixes | [".S"] |
|
||||||
|
| CC | String | C compiler executable | "gcc" |
|
||||||
|
| 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}"] |
|
||||||
|
| CCFLAGS | Array | Common flags for both C and C++ compiler | [] |
|
||||||
|
| CFLAGS | Array | C compiler flags | [] |
|
||||||
|
| CPP_CMD | Array | Preprocess command line | ["${_PREPROCESS_CC}", "-E", "${_PREPROCESS_DEPGEN}", "-o", "${_TARGET}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${_SOURCES}"] |
|
||||||
|
| CPP_TARGET_SUFFIX | String | Suffix used for crt:preprocess target filename. | ".c" |
|
||||||
|
| CPPDEFINES | Array | C preprocessor defines | [] |
|
||||||
|
| CPPDEFPREFIX | String | Prefix used for C preprocessor to introduce a define | "-D" |
|
||||||
|
| CPPFLAGS | Array | C preprocessor flags | ["${CPPDEFPREFIX}${CPPDEFINES}"] |
|
||||||
|
| CPPPATH | Array | C preprocessor path | [] |
|
||||||
|
| CSUFFIX | Array | C source file suffixes | [".c"] |
|
||||||
|
| CXX | String | C++ compiler executable | "g++" |
|
||||||
|
| 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}"] |
|
||||||
|
| CXXFLAGS | Array | C++ compiler flags | [] |
|
||||||
|
| CXXSUFFIX | Array | C++ source file suffixes | [".cc", ".cpp", ".cxx", ".C"] |
|
||||||
|
| D_IMPORT_PATH | Array | D compiler import path | [] |
|
||||||
|
| DC | String | D compiler executable | "gdc" |
|
||||||
|
| DCCMD | Array | D compiler command line | ["${DC}", "-c", "-o", "${_TARGET}", "${INCPREFIX}${D_IMPORT_PATH}", "${DFLAGS}", "${_SOURCES}"] |
|
||||||
|
| 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 | [] |
|
||||||
|
| DISASM_CMD | Array | Disassemble command line | ["${OBJDUMP}", "${DISASM_FLAGS}", "${_SOURCES}"] |
|
||||||
|
| DISASM_FLAGS | Array | Disassemble flags | ["--disassemble", "--source"] |
|
||||||
|
| DSUFFIX | String/Array | Default D source file suffix | ".d" |
|
||||||
|
| INCPREFIX | String | Prefix used for C preprocessor to add an include path | "-I" |
|
||||||
|
| LD | String | nil | Linker executable (automatically determined when nil) | nil (if nil, ${CC}, ${CXX}, or ${DC} is used depending on the sources being linked) |
|
||||||
|
| LDCMD | Array | Link command line | ["${LD}", "-o", "${_TARGET}", "${LDFLAGS}", "${_SOURCES}", "${LIBDIRPREFIX}${LIBPATH}", "${LIBLINKPREFIX}${LIBS}"] |
|
||||||
|
| LDFLAGS | Array | Linker flags | [] |
|
||||||
|
| LEX | String | Lex executable | "flex" |
|
||||||
|
| LEX_CMD | Array | Lex command line | ["${LEX}", "${LEX_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"] |
|
||||||
|
| LEX_FLAGS | Array | Lex flags | [] |
|
||||||
|
| LEXSUFFIX | Array | Lex input file suffixes | [".l", ".ll"] |
|
||||||
|
| LIBDIRPREFIX | String | Prefix given to linker to add a library search path | "-L" |
|
||||||
|
| LIBLINKPREFIX | String | Prefix given to linker to add a library to link with | "-l" |
|
||||||
|
| LIBPATH | Array | Library load path | [] |
|
||||||
|
| LIBS | Array | Libraries to link with | [] |
|
||||||
|
| LIBSUFFIX | String/Array | Default static library file suffix | ".a" |
|
||||||
|
| OBJDUMP | String | Objdump executable | "objdump" |
|
||||||
|
| OBJSUFFIX | String/Array | Default object file suffix | ".o" |
|
||||||
|
| PROGSUFFIX | String | Default program suffix. | Windows: ".exe", POSIX: "" |
|
||||||
|
| SHCC | String | Shared object C compiler | "${CC}" |
|
||||||
|
| SHCCCMD | Array | Shared object C compiler command line | ["${SHCC}", "-c", "-o", "${_TARGET}", "${CCDEPGEN}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${SHCFLAGS}", "${SHCCFLAGS}", "${_SOURCES}"] |
|
||||||
|
| SHCCFLAGS | Array | Shared object C and C++ compiler flags | Windows: ["${CCFLAGS}"], POSIX: ["${CCFLAGS}", -fPIC"] |
|
||||||
|
| SHCFLAGS | Array | Shared object C compiler flags | ["${CFLAGS}"] |
|
||||||
|
| SHCXX | String | Shared object C++ compiler | "${CXX}" |
|
||||||
|
| SHCXXCMD | Array | Shared object C++ compiler command line | ["${SHCXX}", "-c", "-o", "${_TARGET}", "${CXXDEPGEN}", "${INCPREFIX}${CPPPATH}", "${CPPFLAGS}", "${SHCXXFLAGS}", "${SHCCFLAGS}", "${_SOURCES}"] |
|
||||||
|
| SHCXXFLAGS | Array | Shared object C++ compiler flags | ["${CXXFLAGS}"] |
|
||||||
|
| SHDC | String | Shared object D compiler | "gdc" |
|
||||||
|
| SHDCCMD | Array | Shared object D compiler command line | ["${SHDC}", "-c", "-o", "${_TARGET}", "${INCPREFIX}${D_IMPORT_PATH}", "${SHDFLAGS}", "${_SOURCES}"] |
|
||||||
|
| SHDFLAGS | Array | Shared object D compiler flags | Windows: ["${DFLAGS}"], POSIX: ["${DFLAGS}", "-fPIC"] |
|
||||||
|
| SHLD | String | Shared library linker | nil (if nil, ${SHCC}, ${SHCXX}, or ${SHDC} is used depending on the sources being linked) |
|
||||||
|
| SHLDCMD | Array | Shared library linker command line | ["${SHLD}", "-o", "${_TARGET}", "${SHLDFLAGS}", "${_SOURCES}", "${SHLIBDIRPREFIX}${LIBPATH}", "${SHLIBLINKPREFIX}${LIBS}"] |
|
||||||
|
| SHLDFLAGS | Array | Shared library linker flags | ["${LDFLAGS}", "-shared"] |
|
||||||
|
| SHLIBDIRPREFIX | String | Prefix given to shared library linker to add a library search path | "-L" |
|
||||||
|
| SHLIBLINKPREFIX | String | Prefix given to shared library linker to add a library to link with | "-l" |
|
||||||
|
| SHLIBPREFIX | String | Shared library file name prefix | Windows: "", POSIX: "lib" |
|
||||||
|
| SHLIBSUFFIX | String | Shared library file name suffix | Windows: ".dll", POSIX: ".so" |
|
||||||
|
| SIZE | String | Size executable. | "size" |
|
||||||
|
| YACC | String | Yacc executable | "bison" |
|
||||||
|
| YACC_CMD | Array | Yacc command line | ["${YACC}", "${YACC_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"] |
|
||||||
|
| YACC_FLAGS | Array | Yacc flags | ["-d"] |
|
||||||
|
| YACCSUFFIX | Array | Yacc input file suffixes | [".y", ".yy"] |
|
||||||
|
|
||||||
|
### Build Hooks
|
||||||
|
|
||||||
Environments can have build hooks which are added with `env.add_build_hook()`.
|
Environments can have build hooks which are added with `env.add_build_hook()`.
|
||||||
Build hooks are invoked immediately before a builder executes.
|
Build hooks are invoked immediately before a builder executes.
|
||||||
@@ -385,6 +493,36 @@ Post-build hooks are only invoked if the build operation was a success.
|
|||||||
Post-build hooks can invoke commands using the newly-built files, or register
|
Post-build hooks can invoke commands using the newly-built files, or register
|
||||||
new build targets.
|
new build targets.
|
||||||
|
|
||||||
|
Each build hook block will be invoked for every build operation, so the block
|
||||||
|
should test the target or sources if its action should only apply to some
|
||||||
|
subset of build targets or source files.
|
||||||
|
|
||||||
|
Example build hook:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
# Build third party sources without -Wall
|
||||||
|
env.add_build_hook do |build_op|
|
||||||
|
if build_op[:builder].name == "Object" and
|
||||||
|
build_op[:sources].first =~ %r{src/third-party}
|
||||||
|
build_op[:vars]["CFLAGS"] -= ["-Wall"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
The `build_op` parameter to the build hook block is a Hash describing the
|
||||||
|
build operation with the following keys:
|
||||||
|
* `:builder` - `Builder` instance in use
|
||||||
|
* `:env` - `Environment` calling the build hook; note that this may be
|
||||||
|
different from the Environment that the build hook was added to in the case
|
||||||
|
that the original Environment was cloned with build hooks!
|
||||||
|
* `:target` - `String` name of the target file
|
||||||
|
* `:sources` - `Array` of the source files
|
||||||
|
* `:vars` - `Rscons::VarSet` containing the construction variables to use.
|
||||||
|
The build hook can overwrite entries in `build_op[:vars]` to alter the
|
||||||
|
construction variables in use for this specific build operation.
|
||||||
|
|
||||||
### Phony Targets
|
### Phony Targets
|
||||||
|
|
||||||
A build target name given as a Symbol instead of a String is interpreted as a
|
A build target name given as a Symbol instead of a String is interpreted as a
|
||||||
@@ -416,6 +554,7 @@ env.depends("my_app", "config/link.ld", "README.txt", *Dir.glob("assets/**/*"))
|
|||||||
### Construction Variable Naming
|
### Construction Variable Naming
|
||||||
|
|
||||||
* uppercase strings - the default construction variables that Rscons uses
|
* uppercase strings - the default construction variables that Rscons uses
|
||||||
|
* strings beginning with "_" - set and used internally by builders
|
||||||
* symbols, lowercase strings - reserved as user-defined construction variables
|
* symbols, lowercase strings - reserved as user-defined construction variables
|
||||||
|
|
||||||
### API documentation
|
### API documentation
|
||||||
@@ -425,6 +564,42 @@ http://rubydoc.info/github/holtrop/rscons/frames.
|
|||||||
|
|
||||||
## Release Notes
|
## 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
|
### v1.9.2
|
||||||
|
|
||||||
- allow phony targets in conjunction with build roots
|
- allow phony targets in conjunction with build roots
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ CLOBBER.include %w[pkg]
|
|||||||
|
|
||||||
RSpec::Core::RakeTask.new(:spec, :example_string) do |task, args|
|
RSpec::Core::RakeTask.new(:spec, :example_string) do |task, args|
|
||||||
if args.example_string
|
if args.example_string
|
||||||
|
ENV["partial_specs"] = "1"
|
||||||
task.rspec_opts = %W[-e "#{args.example_string}" -f documentation]
|
task.rspec_opts = %W[-e "#{args.example_string}" -f documentation]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
||||||
|
env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
|
||||||
|
env.Program('build_dir.exe', Dir['src/**/*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
class MyObject < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
env.run_builder(env.builders["Object"], target, sources, cache, vars)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.add_builder(MyObject.new)
|
||||||
|
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
||||||
|
env.add_build_hook do |build_op|
|
||||||
|
if build_op[:builder].name == "MyObject" && build_op[:sources].first =~ %r{one\.c}
|
||||||
|
build_op[:vars]["CFLAGS"] << "-O1"
|
||||||
|
build_op[:sources] = ['src/two/two.c']
|
||||||
|
elsif build_op[:builder].name == "MyObject" && build_op[:target] =~ %r{two\.o}
|
||||||
|
new_vars = build_op[:vars].clone
|
||||||
|
new_vars["CFLAGS"] << "-O2"
|
||||||
|
build_op[:vars] = new_vars
|
||||||
|
end
|
||||||
|
end
|
||||||
|
env.MyObject('one.o', 'src/one/one.c')
|
||||||
|
env.MyObject('two.o', 'src/two/two.c')
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
env = Rscons::Environment.new do |env|
|
||||||
|
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
||||||
|
env.build_dir("src", "build")
|
||||||
|
env.build_root = "build_root"
|
||||||
|
env.Program('build_dir.exe', Dir['src/**/*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
||||||
|
env.build_dir(%r{^src/([^/]+)/}, 'build_\\1/')
|
||||||
|
env.add_build_hook do |build_op|
|
||||||
|
if build_op[:target] =~ %r{build_one/.*\.o}
|
||||||
|
build_op[:vars]["CFLAGS"] << "-O1"
|
||||||
|
elsif build_op[:target] =~ %r{build_two/.*\.o}
|
||||||
|
build_op[:vars]["CFLAGS"] << "-O2"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
env.Program('build_hook.exe', Dir['src/**/*.c'].sort)
|
||||||
|
end
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
||||||
|
env.build_root = "build_root"
|
||||||
|
FileUtils.mkdir_p(env.build_root)
|
||||||
|
FileUtils.mv("src/one/one.c", "build_root")
|
||||||
|
env.Object("^/one.o", "^/one.c")
|
||||||
|
env.Program("build_dir.exe", Dir['src/**/*.c'] + ["^/one.o"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Copy("inst.exe", "copy.rb")
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CSUFFIX"] = %w[.yargh .c]
|
||||||
|
env["CFLAGS"] += %w[-x c]
|
||||||
|
env["CPPPATH"] += Dir["src/**/"]
|
||||||
|
env.Program("build_dir.exe", Dir["src/**/*.{c,yargh}"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Install("inst.exe", "install.rb")
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Directory("inst")
|
||||||
|
env.Install("inst", "install_directory.rb")
|
||||||
|
|
||||||
|
env.Install("noexist/src", "src")
|
||||||
|
|
||||||
|
env.Directory("exist/src")
|
||||||
|
env.Install("exist/src", "src")
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CPPPATH"] << "src/two"
|
||||||
|
env.Object("one.o", "src/one/one.c")
|
||||||
|
env.Object("one.o", "src/two/two.c")
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.append('CPPPATH' => Dir['src/**/*/'].sort)
|
||||||
|
env.build_dir("src2", "build")
|
||||||
|
env.build_root = "build_root"
|
||||||
|
env.Program('build_dir.exe', Dir['src/**/*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CPPPATH"] << "src/two"
|
||||||
|
env.Object("one.o", "src/one/one.c")
|
||||||
|
env.add_post_build_hook do |build_op|
|
||||||
|
if build_op[:target] == "one.o"
|
||||||
|
env["MODULE"] = "two"
|
||||||
|
env.Object("${MODULE}.o", "src/${MODULE}/${MODULE}.c")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.append("CPPPATH" => Dir["src/**/*/"].sort)
|
||||||
|
env.build_dir("src/one/", "build_one/")
|
||||||
|
env.build_dir("src/two", "build_two")
|
||||||
|
env.Program("build_dir.exe", Dir["src/**/*.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.CFile("lexer.c", "lexer.l")
|
||||||
|
env.CFile("parser.c", "parser.y")
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.CFile("file.c", "foo.bar")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
%{
|
||||||
|
%}
|
||||||
|
|
||||||
|
%%
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
%{
|
||||||
|
%}
|
||||||
|
|
||||||
|
%token ONE
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
one: ONE
|
||||||
|
;
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
debug = Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.build_dir('src', 'debug')
|
||||||
|
env['CFLAGS'] = '-O2'
|
||||||
|
env['CPPFLAGS'] = '-DSTRING="Debug Version"'
|
||||||
|
env.Program('program-debug.exe', Dir['src/*.c'])
|
||||||
|
end
|
||||||
|
|
||||||
|
release = debug.clone do |env|
|
||||||
|
env["CPPFLAGS"] = '-DSTRING="Release Version"'
|
||||||
|
env.build_dir('src', 'release')
|
||||||
|
env.Program('program-release.exe', Dir['src/*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
env1 = Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.build_dir('src', 'build')
|
||||||
|
env['CFLAGS'] = '-O2'
|
||||||
|
env.add_build_hook do |build_op|
|
||||||
|
build_op[:vars]['CPPFLAGS'] = '-DSTRING="Hello"'
|
||||||
|
end
|
||||||
|
env.add_post_build_hook do |build_op|
|
||||||
|
$stdout.puts "post #{build_op[:target]}"
|
||||||
|
end
|
||||||
|
env.Program('program.exe', Dir['src/*.c'])
|
||||||
|
end
|
||||||
|
|
||||||
|
env2 = env1.clone do |env|
|
||||||
|
env.Program('program2.exe', Dir['src/*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
class MySource < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
File.open(target, 'w') do |fh|
|
||||||
|
fh.puts <<EOF
|
||||||
|
#define THE_VALUE 5678
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(MySource.new)
|
||||||
|
env.MySource('inc.h', [])
|
||||||
|
env.Program('program.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Command("inc.c",
|
||||||
|
[],
|
||||||
|
"CMD" => %w[ruby gen.rb ${_TARGET}],
|
||||||
|
"CMD_DESC" => "Generating")
|
||||||
|
env["build_root"] = env.build_root
|
||||||
|
env["inc_c"] = "inc.c"
|
||||||
|
env.build_after("${build_root}/program.o", "${inc_c}")
|
||||||
|
env.Program("program.exe", ["program.c", "inc.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
class MySource < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
File.open(target, 'w') do |fh|
|
||||||
|
fh.puts <<EOF
|
||||||
|
#define THE_VALUE 678
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
env = Rscons::Environment.new do |env|
|
||||||
|
env["hdr"] = "inc.h"
|
||||||
|
env["src"] = "program.c"
|
||||||
|
env.add_builder(MySource.new)
|
||||||
|
env.MySource('${hdr}')
|
||||||
|
env.Program('program.exe', "${src}")
|
||||||
|
end
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
class MySource < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
File.open(target, 'w') do |fh|
|
||||||
|
fh.puts <<EOF
|
||||||
|
#define THE_VALUE #{env.expand_varref("${the_value}")}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
e1 = Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(MySource.new)
|
||||||
|
env["one"] = "5"
|
||||||
|
env[:cfg] = {val: "9"}
|
||||||
|
env["two"] = lambda do |args|
|
||||||
|
args[:env][:cfg][:val]
|
||||||
|
end
|
||||||
|
env["the_value"] = lambda do |args|
|
||||||
|
"${one}${two}78"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
e1.clone do |env|
|
||||||
|
env[:cfg][:val] = "6"
|
||||||
|
env.MySource('inc.h', [])
|
||||||
|
env.Program('program.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
sleep 1.0
|
||||||
|
c_file = ARGV.first
|
||||||
|
h_file = File.basename(c_file, ".c") + ".h"
|
||||||
|
File.open(c_file, "w") do |fh|
|
||||||
|
fh.puts
|
||||||
|
end
|
||||||
|
File.open(h_file, "w") do |fh|
|
||||||
|
fh.puts("#define THE_VALUE 191")
|
||||||
|
end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class CHGen < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
c_fname = target
|
||||||
|
h_fname = target.sub(/\.c$/, ".h")
|
||||||
|
unless cache.up_to_date?([c_fname, h_fname], "", sources, env)
|
||||||
|
puts "CHGen #{c_fname}"
|
||||||
|
File.open(c_fname, "w") {|fh| fh.puts "int THE_VALUE = 42;"}
|
||||||
|
File.open(h_fname, "w") {|fh| fh.puts "extern int THE_VALUE;"}
|
||||||
|
cache.register_build([c_fname, h_fname], "", sources, env)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(CHGen.new)
|
||||||
|
env.CHGen("inc.c", ["program.c"])
|
||||||
|
env.Program("program.exe", %w[program.c inc.c])
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.Program("hello-d.exe", Dir["*.d"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Program('header.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
require 'json'
|
||||||
|
require 'yaml'
|
||||||
|
env.add_builder(:JsonToYaml) do |target, sources, cache, env, vars|
|
||||||
|
unless cache.up_to_date?(target, :JsonToYaml, sources, env)
|
||||||
|
cache.mkdir_p(File.dirname(target))
|
||||||
|
File.open(target, 'w') do |f|
|
||||||
|
f.write(YAML.dump(JSON.load(IO.read(sources.first))))
|
||||||
|
end
|
||||||
|
cache.register_build(target, :JsonToYaml, sources, env)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
env.JsonToYaml('foo.yml', 'foo.json')
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.Program('library.exe', ['lib.a', 'three.c'])
|
||||||
|
env.Library("lib.a", ['one.c', 'two.c'], 'CPPFLAGS' => ['-Dmake_lib'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env["ARCMD"] = %w[ar rcf ${_TARGET} ${_SOURCES}]
|
||||||
|
env.Library("lib.a", Dir["*.c"].sort)
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Preprocess("pp", "foo.h")
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CPPPATH"] << "src/lib"
|
||||||
|
libmine = env.SharedLibrary("mine", Dir["src/lib/*.c"])
|
||||||
|
env.Program("test-shared.exe",
|
||||||
|
Dir["src/*.c"],
|
||||||
|
"LIBPATH" => %w[.],
|
||||||
|
"LIBS" => %w[mine])
|
||||||
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
|
env.Program("test-static.exe",
|
||||||
|
Dir["src/**/*.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
File.open("foo.xyz", "wb") do |fh|
|
||||||
|
fh.puts("hi")
|
||||||
|
end
|
||||||
|
env.SharedObject("foo.o", "foo.xyz")
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CPPPATH"] << "src/lib"
|
||||||
|
libmine = env.SharedLibrary("mine", Dir["src/lib/*.cc"])
|
||||||
|
env.Program("test-shared.exe",
|
||||||
|
Dir["src/*.cc"],
|
||||||
|
"LIBPATH" => %w[.],
|
||||||
|
"LIBS" => %w[mine])
|
||||||
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
|
env.Program("test-static.exe",
|
||||||
|
Dir["src/**/*.cc"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CPPPATH"] << "src/lib"
|
||||||
|
libmine = env.SharedLibrary("mine", Dir["src/lib/*.d"])
|
||||||
|
env.Program("test-shared.exe",
|
||||||
|
Dir["src/*.c"],
|
||||||
|
"LIBPATH" => %w[.],
|
||||||
|
"LIBS" => %w[mine])
|
||||||
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
|
end
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CPPPATH"] << "src/lib"
|
||||||
|
env["SHLD"] = "gcc"
|
||||||
|
libmine = env.SharedLibrary("mine", Dir["src/lib/*.c"])
|
||||||
|
env.Program("test-shared.exe",
|
||||||
|
Dir["src/*.c"],
|
||||||
|
"LIBPATH" => %w[.],
|
||||||
|
"LIBS" => %w[mine])
|
||||||
|
env.build_after("test-shared.exe", libmine.to_s)
|
||||||
|
env.Program("test-static.exe",
|
||||||
|
Dir["src/**/*.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void one(void)
|
||||||
|
{
|
||||||
|
printf("Hi from one()\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void one(void)
|
||||||
|
{
|
||||||
|
printf("Hi from one()\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import core.stdc.stdio;
|
||||||
|
|
||||||
|
extern (C) void one()
|
||||||
|
{
|
||||||
|
printf("Hi from one()\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#ifndef ONE_H
|
||||||
|
|
||||||
|
void one(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void two(void)
|
||||||
|
{
|
||||||
|
printf("Hi from two()\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void two(void)
|
||||||
|
{
|
||||||
|
printf("Hi from two()\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import core.stdc.stdio;
|
||||||
|
|
||||||
|
extern (C) void two()
|
||||||
|
{
|
||||||
|
printf("Hi from two()\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
#ifndef TWO_H
|
||||||
|
|
||||||
|
void two(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "one.h"
|
||||||
|
#include "two.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
one();
|
||||||
|
two();
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#include "one.h"
|
||||||
|
#include "two.h"
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
one();
|
||||||
|
two();
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Program('simple.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.build_root = "build"
|
||||||
|
tempdir = ENV["TEMP"] || ENV["TMP"] || "/tmp"
|
||||||
|
source_file = File.join(tempdir, "abs.c")
|
||||||
|
File.open(source_file, "w") do |fh|
|
||||||
|
fh.puts(<<-EOF)
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 29;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
env.Program("abs.exe", source_file)
|
||||||
|
end
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
class MyObject < Rscons::Builder
|
||||||
|
def produces?(target, source, env)
|
||||||
|
target.end_with?(".o") and source.end_with?(".xyz")
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
cflags = env.expand_varref("${CFLAGS}", vars)
|
||||||
|
vars = vars.merge(
|
||||||
|
"CFLAGS" => cflags + %w[-x c],
|
||||||
|
"CSUFFIX" => ".xyz")
|
||||||
|
env.run_builder(env.builders["Object"], target, sources, cache, vars)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(MyObject.new)
|
||||||
|
File.open("test.xyz", "w") do |fh|
|
||||||
|
fh.puts <<EOF
|
||||||
|
#include <stdio.h>
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
printf("XYZ!\\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
env.Program("test", "test.xyz")
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class TestBuilder < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.build_root = "build"
|
||||||
|
env.add_builder(TestBuilder.new)
|
||||||
|
env.TestBuilder("file")
|
||||||
|
end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
class MyProgram < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
|
objects = env.build_sources(sources, [".o"], cache, vars)
|
||||||
|
command = %W[gcc -o #{target}] + objects
|
||||||
|
return false unless env.execute("#{name} #{target}", command)
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(MyProgram.new)
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
File.open("two.c", "wb") do |fh|
|
||||||
|
fh.puts <<-EOF
|
||||||
|
void two(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
end
|
||||||
|
env.MyProgram("simple.exe", ["simple.o", "two.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["LIBS"] += ["c"]
|
||||||
|
env.Program('simple.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Copy("simple.copy", "simple.c")
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
env.process
|
||||||
|
env["LDCMD"] = %w[gcc -o ${_TARGET} simple.o]
|
||||||
|
env.Program('simple.exe', [])
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
env["LDCMD"] = %w[gcc -o ${_TARGET} simple.o]
|
||||||
|
env.Program('simple.exe', ["simple.o"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
env.Object("two.o", "two.c")
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
target = env.Program("simple.exe", "simple.c")
|
||||||
|
user_deps = File.read("user_deps", mode: "rb").split(" ")
|
||||||
|
target.depends(*user_deps)
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Program("simple.exe", "simple.c")
|
||||||
|
env.clear_targets
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env["LD"] = "gcc"
|
||||||
|
env.Program('simple.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
command = %W[gcc -o ${_TARGET} ${_SOURCES}]
|
||||||
|
env.Command("simple.exe",
|
||||||
|
"simple.c",
|
||||||
|
"CMD" => command,
|
||||||
|
"CMD_DESC" => "BuildIt")
|
||||||
|
end
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
env.Command("simple.txt",
|
||||||
|
"simple.o",
|
||||||
|
"CMD" => %w[objdump --disassemble --source ${_SOURCES}],
|
||||||
|
"CMD_STDOUT" => "${_TARGET}",
|
||||||
|
"CMD_DESC" => "My Disassemble")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["sources"] = Dir["*.c"].sort
|
||||||
|
env.Program("simple.exe", "${sources}")
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Directory("teh_dir")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
env.Disassemble("simple.txt", "simple.o")
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
env = Rscons::Environment.new do |env|
|
||||||
|
env["CFLAGS"] += %w[-O2 -fomit-frame-pointer]
|
||||||
|
env[:foo] = :bar
|
||||||
|
end
|
||||||
|
env.dump
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Command("foo", "bar")
|
||||||
|
env.Command("bar", "baz")
|
||||||
|
env.Command("baz", "foo")
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Command("foo", "foo")
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
File.open("foo.xyz", "wb") do |fh|
|
||||||
|
fh.puts("hi")
|
||||||
|
end
|
||||||
|
env.Object("foo.o", "foo.xyz")
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env["LD"] = "gcc"
|
||||||
|
env["LIBPATH"] += ["libdir"]
|
||||||
|
env.Program('simple.exe', Dir['*.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.Object("simple.o", "simple.c",
|
||||||
|
"CCCMD" => %w[${CC} -c -o ${_TARGET} -Dfoobar ${_SOURCES}])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env["DEPFILESUFFIX"] = ".deppy"
|
||||||
|
env.Object("simple.o", "simple.c")
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(:Checker) do |target, sources, cache, env, vars|
|
||||||
|
unless cache.up_to_date?(target, :Checker, sources, env)
|
||||||
|
puts "Checker #{sources.first}" if env.echo != :off
|
||||||
|
cache.register_build(target, :Checker, sources, env)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
env.Program("simple.exe", "simple.c")
|
||||||
|
env.Checker(:checker, "simple.exe")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Preprocess("simplepp.c", "simple.c")
|
||||||
|
env.Program("simple.exe", "simplepp.c")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["PROGSUFFIX"] = ".out"
|
||||||
|
env.Program("simple", Dir["*.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["MYSUFFIX"] = ".out"
|
||||||
|
env.Program("simple${MYSUFFIX}", Dir["*.c"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Program("simple", Dir["*.c"], "PROGSUFFIX" => ".xyz")
|
||||||
|
end
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Program("simple.exe", Dir["*.c"])
|
||||||
|
env.add_build_hook do |build_op|
|
||||||
|
if build_op[:target].end_with?(".o")
|
||||||
|
env.Disassemble("#{build_op[:target]}.txt", build_op[:target])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class MyObject < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
|
env.run_builder(env.builders["Object"], target, sources, cache, vars)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(MyObject.new)
|
||||||
|
env.MyObject("simple.o", "simple.c")
|
||||||
|
env.Program("simple.exe", "simple.o")
|
||||||
|
end
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class MyCommand < Rscons::Builder
|
||||||
|
def run(target, sources, cache, env, vars)
|
||||||
|
vars = vars.merge({
|
||||||
|
"_TARGET" => target,
|
||||||
|
"_SOURCES" => sources,
|
||||||
|
})
|
||||||
|
command = env.build_command("${CMD}", vars)
|
||||||
|
cmd_desc = vars["CMD_DESC"] || "MyCommand"
|
||||||
|
standard_build("#{cmd_desc} #{target}", target, command, sources, env, cache)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(MyCommand.new)
|
||||||
|
command = %w[gcc -c -o ${_TARGET} ${_SOURCES}]
|
||||||
|
env.MyCommand("simple.o", "simple.c", "CMD" => command)
|
||||||
|
end
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
class ThreadedTestBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
command = ["ruby", "-e", %[sleep 1]]
|
||||||
|
Rscons::ThreadedCommand.new(
|
||||||
|
command,
|
||||||
|
short_description: "ThreadedTestBuilder #{options[:target]}")
|
||||||
|
end
|
||||||
|
def finalize(options)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class NonThreadedTestBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
puts "NonThreadedTestBuilder #{options[:target]}"
|
||||||
|
sleep 1
|
||||||
|
options[:target]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.add_builder(ThreadedTestBuilder.new)
|
||||||
|
env.add_builder(NonThreadedTestBuilder.new)
|
||||||
|
env.ThreadedTestBuilder("a")
|
||||||
|
env.ThreadedTestBuilder("b")
|
||||||
|
env.ThreadedTestBuilder("c")
|
||||||
|
env.NonThreadedTestBuilder("d")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
program = env.Program("simple.exe", Dir["*.c"])
|
||||||
|
env.depends(program, "program.ld")
|
||||||
|
end
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Program('simple.exe', Dir['*.cc'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["CXXSUFFIX"] = %w[.cccc .cc]
|
||||||
|
env["CXXFLAGS"] += %w[-x c++]
|
||||||
|
env.Program("simple.exe", Dir["*.cc"] + Dir["*.cccc"])
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env.Preprocess("simplepp.cc", "simple.cc")
|
||||||
|
env.Program("simple.exe", "simplepp.cc")
|
||||||
|
end
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.Object("one.o", "one.c", 'CPPFLAGS' => ['-DONE'])
|
||||||
|
env.Program('two_sources.exe', ['one.o', 'two.c'])
|
||||||
|
end
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["ASSUFFIX"] = %w[.ssss .sss]
|
||||||
|
env["CFLAGS"] += %w[-S]
|
||||||
|
env.Object("one.ssss", "one.c", "CPPFLAGS" => ["-DONE"])
|
||||||
|
env.Object("two.sss", "two.c")
|
||||||
|
env.Program("two_sources.exe", %w[one.ssss two.sss], "ASFLAGS" => env["ASFLAGS"] + %w[-x assembler])
|
||||||
|
end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class StrictBuilder < Rscons::Builder
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env = options.values_at(:target, :sources, :cache, :env)
|
||||||
|
command = %W[gcc -o #{target}] + sources.sort
|
||||||
|
unless cache.up_to_date?(target, command, sources, env, strict_deps: true)
|
||||||
|
return false unless env.execute("StrictBuilder #{target}", command)
|
||||||
|
cache.register_build(target, command, sources, env)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Rscons::Environment.new(echo: :command) do |env|
|
||||||
|
env.add_builder(StrictBuilder.new)
|
||||||
|
env.Object("one.o", "one.c", "CCFLAGS" => %w[-DONE])
|
||||||
|
env.Object("two.o", "two.c")
|
||||||
|
sources = File.read("sources", mode: "rb").split(" ")
|
||||||
|
env.StrictBuilder("program.exe", sources)
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new() do |env|
|
||||||
|
env["LIBSUFFIX"] = %w[.aaaa .aaa]
|
||||||
|
env.Library("one.aaaa", "one.c", "CPPFLAGS" => ["-DONE"])
|
||||||
|
env.Library("two.aaa", "two.c")
|
||||||
|
env.Program("two_sources.exe", %w[one.aaaa two.aaa])
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
Rscons::Environment.new do |env|
|
||||||
|
env["OBJSUFFIX"] = %w[.oooo .ooo]
|
||||||
|
env.Object("one.oooo", "one.c", "CPPFLAGS" => ["-DONE"])
|
||||||
|
env.Object("two.ooo", "two.c")
|
||||||
|
env.Program("two_sources.exe", %w[one.oooo two.ooo])
|
||||||
|
end
|
||||||
+53
-1
@@ -2,6 +2,8 @@ require_relative "rscons/build_target"
|
|||||||
require_relative "rscons/builder"
|
require_relative "rscons/builder"
|
||||||
require_relative "rscons/cache"
|
require_relative "rscons/cache"
|
||||||
require_relative "rscons/environment"
|
require_relative "rscons/environment"
|
||||||
|
require_relative "rscons/job_set"
|
||||||
|
require_relative "rscons/threaded_command"
|
||||||
require_relative "rscons/varset"
|
require_relative "rscons/varset"
|
||||||
require_relative "rscons/version"
|
require_relative "rscons/version"
|
||||||
|
|
||||||
@@ -15,6 +17,8 @@ require_relative "rscons/builders/library"
|
|||||||
require_relative "rscons/builders/object"
|
require_relative "rscons/builders/object"
|
||||||
require_relative "rscons/builders/preprocess"
|
require_relative "rscons/builders/preprocess"
|
||||||
require_relative "rscons/builders/program"
|
require_relative "rscons/builders/program"
|
||||||
|
require_relative "rscons/builders/shared_library"
|
||||||
|
require_relative "rscons/builders/shared_object"
|
||||||
require_relative "rscons/builders/simple_builder"
|
require_relative "rscons/builders/simple_builder"
|
||||||
|
|
||||||
# Namespace module for rscons classes
|
# Namespace module for rscons classes
|
||||||
@@ -33,6 +37,8 @@ module Rscons
|
|||||||
:Object,
|
:Object,
|
||||||
:Preprocess,
|
:Preprocess,
|
||||||
:Program,
|
:Program,
|
||||||
|
:SharedLibrary,
|
||||||
|
:SharedObject,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Class to represent a fatal error while building a target.
|
# Class to represent a fatal error while building a target.
|
||||||
@@ -40,6 +46,10 @@ module Rscons
|
|||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
|
# @return [Integer]
|
||||||
|
# The number of threads to use when scheduling subprocesses.
|
||||||
|
attr_accessor :n_threads
|
||||||
|
|
||||||
# Remove all generated files.
|
# Remove all generated files.
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
@@ -65,7 +75,11 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [Boolean] Whether the given path is an absolute filesystem path.
|
# @return [Boolean] Whether the given path is an absolute filesystem path.
|
||||||
def absolute_path?(path)
|
def absolute_path?(path)
|
||||||
path =~ %r{^(/|\w:[\\/])}
|
if RUBY_PLATFORM =~ /mingw/
|
||||||
|
path =~ %r{^(?:\w:)?[\\/]}
|
||||||
|
else
|
||||||
|
path.start_with?("/")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return whether the given target is a phony target.
|
# Return whether the given target is a phony target.
|
||||||
@@ -146,7 +160,45 @@ module Rscons
|
|||||||
@command_executer = val
|
@command_executer = val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Determine the number of threads to use by default.
|
||||||
|
#
|
||||||
|
# @return [Integer]
|
||||||
|
# The number of threads to use by default.
|
||||||
|
def determine_n_threads
|
||||||
|
# If the user specifies the number of threads in the environment, then
|
||||||
|
# respect that.
|
||||||
|
if ENV["RSCONS_NTHREADS"] =~ /^(\d+)$/
|
||||||
|
return $1.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Otherwise try to figure out how many threads are available on the
|
||||||
|
# host hardware.
|
||||||
|
begin
|
||||||
|
case RbConfig::CONFIG["host_os"]
|
||||||
|
when /linux/
|
||||||
|
return File.read("/proc/cpuinfo").scan(/^processor\s*:/).size
|
||||||
|
when /mswin|mingw/
|
||||||
|
if `wmic cpu get NumberOfLogicalProcessors /value` =~ /NumberOfLogicalProcessors=(\d+)/
|
||||||
|
return $1.to_i
|
||||||
|
end
|
||||||
|
when /darwin/
|
||||||
|
if `sysctl -n hw.ncpu` =~ /(\d+)/
|
||||||
|
return $1.to_i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
end
|
||||||
|
|
||||||
|
# If we can't figure it out, default to 1.
|
||||||
|
1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
@n_threads = determine_n_threads
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Unbuffer $stdout
|
# Unbuffer $stdout
|
||||||
|
|||||||
+184
-11
@@ -24,6 +24,14 @@ module Rscons
|
|||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a set of build features that this builder provides.
|
||||||
|
#
|
||||||
|
# @return [Array<String>]
|
||||||
|
# Set of build features that this builder provides.
|
||||||
|
def features
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
# Create a BuildTarget object for this build target.
|
# Create a BuildTarget object for this build target.
|
||||||
#
|
#
|
||||||
# Builder sub-classes can override this method to manipulate parameters
|
# Builder sub-classes can override this method to manipulate parameters
|
||||||
@@ -36,6 +44,8 @@ module Rscons
|
|||||||
# The user-supplied target name.
|
# The user-supplied target name.
|
||||||
# @option options [Array<String>] :sources
|
# @option options [Array<String>] :sources
|
||||||
# The user-supplied source file name(s).
|
# The user-supplied source file name(s).
|
||||||
|
# @option options [Hash,VarSet] :vars
|
||||||
|
# Extra construction variables.
|
||||||
#
|
#
|
||||||
# @return [BuildTarget]
|
# @return [BuildTarget]
|
||||||
def create_build_target(options)
|
def create_build_target(options)
|
||||||
@@ -45,9 +55,12 @@ module Rscons
|
|||||||
# Return whether this builder object is capable of producing a given target
|
# Return whether this builder object is capable of producing a given target
|
||||||
# file name from a given source file name.
|
# file name from a given source file name.
|
||||||
#
|
#
|
||||||
# @param target [String] The target file name.
|
# @param target [String]
|
||||||
# @param source [String] The source file name.
|
# The target file name.
|
||||||
# @param env [Environment] The Environment.
|
# @param source [String]
|
||||||
|
# The source file name.
|
||||||
|
# @param env [Environment]
|
||||||
|
# The Environment.
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether this builder object is capable of producing a given target
|
# Whether this builder object is capable of producing a given target
|
||||||
@@ -56,22 +69,128 @@ module Rscons
|
|||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set up a build operation using this builder.
|
||||||
|
#
|
||||||
|
# This method is called when a build target is registered using this
|
||||||
|
# builder. This method should not do any building, but should perform any
|
||||||
|
# setup needed and register any prerequisite build targets that need to be
|
||||||
|
# built before the target being requested here.
|
||||||
|
#
|
||||||
|
# If the builder needs no special setup, it does not need to override this
|
||||||
|
# method. If there is any information produced in this method that will be
|
||||||
|
# needed later in the build, it can be stored in the return value from this
|
||||||
|
# method, which will be passed to the {#run} method.
|
||||||
|
#
|
||||||
|
# @since 1.10.0
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Options.
|
||||||
|
# @option options [String] :target
|
||||||
|
# Target file name.
|
||||||
|
# @option options [Array<String>] :sources
|
||||||
|
# Source file name(s).
|
||||||
|
# @option options [Environment] :env
|
||||||
|
# The Environment executing the builder.
|
||||||
|
# @option options [Hash,VarSet] :vars
|
||||||
|
# Extra construction variables.
|
||||||
|
#
|
||||||
|
# @return [Object]
|
||||||
|
# Any object that the builder author wishes to be saved and passed back
|
||||||
|
# in to the {#run} method.
|
||||||
|
def setup(options)
|
||||||
|
end
|
||||||
|
|
||||||
# Run the builder to produce a build target.
|
# Run the builder to produce a build target.
|
||||||
#
|
#
|
||||||
# @param target [String] Target file name.
|
# The run method supports two different signatures - an older signature
|
||||||
# @param sources [Array<String>] Source file name(s).
|
# with five separate arguments, and a newer one with one Hash argument. A
|
||||||
# @param cache [Cache] The Cache object.
|
# builder author can use either signature, and Rscons will automatically
|
||||||
# @param env [Environment] The Environment executing the builder.
|
# determine which arguments to pass when invoking the run method based on
|
||||||
# @param vars [Hash,VarSet] Extra construction variables.
|
# the method's arity.
|
||||||
#
|
#
|
||||||
# @return [String,false]
|
# @overload run(target, sources, cache, env, vars)
|
||||||
|
#
|
||||||
|
# @param target [String]
|
||||||
|
# Target file name.
|
||||||
|
# @param sources [Array<String>]
|
||||||
|
# Source file name(s).
|
||||||
|
# @param cache [Cache]
|
||||||
|
# The Cache object.
|
||||||
|
# @param env [Environment]
|
||||||
|
# The Environment executing the builder.
|
||||||
|
# @param vars [Hash,VarSet]
|
||||||
|
# Extra construction variables.
|
||||||
|
#
|
||||||
|
# @overload run(options)
|
||||||
|
#
|
||||||
|
# @since 1.10.0
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Run options.
|
||||||
|
# @option options [String] :target
|
||||||
|
# Target file name.
|
||||||
|
# @option options [Array<String>] :sources
|
||||||
|
# Source file name(s).
|
||||||
|
# @option options [Cache] :cache
|
||||||
|
# The Cache object.
|
||||||
|
# @option options [Environment] :env
|
||||||
|
# The Environment executing the builder.
|
||||||
|
# @option options [Hash,VarSet] :vars
|
||||||
|
# Extra construction variables.
|
||||||
|
# @option options [Object] :setup_info
|
||||||
|
# Whatever value was returned from this builder's {#setup} method call.
|
||||||
|
#
|
||||||
|
# @return [ThreadedCommand,String,false]
|
||||||
# Name of the target file on success or false on failure.
|
# Name of the target file on success or false on failure.
|
||||||
def run(target, sources, cache, env, vars)
|
# Since 1.10.0, this method may return an instance of {ThreadedCommand}.
|
||||||
|
# In that case, the build operation has not actually been completed yet
|
||||||
|
# but the command to do so will be executed by Rscons in a separate
|
||||||
|
# thread. This allows for build parallelization. If a {ThreadedCommand}
|
||||||
|
# object is returned, the {#finalize} method will be called after the
|
||||||
|
# command has completed. The {#finalize} method should then be used to
|
||||||
|
# record cache info, if needed, and to return the true result of the
|
||||||
|
# build operation. The builder can store information to be passed in to
|
||||||
|
# the {#finalize} method by populating the :builder_info field of the
|
||||||
|
# {ThreadedCommand} object returned here.
|
||||||
|
def run(options)
|
||||||
raise "This method must be overridden in a subclass"
|
raise "This method must be overridden in a subclass"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Finalize a build operation.
|
||||||
|
#
|
||||||
|
# This method is called after the {#run} method if the {#run} method
|
||||||
|
# returns a {ThreadedCommand} object.
|
||||||
|
#
|
||||||
|
# @since 1.10.0
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Options.
|
||||||
|
# @option options [String] :target
|
||||||
|
# Target file name.
|
||||||
|
# @option options [Array<String>] :sources
|
||||||
|
# Source file name(s).
|
||||||
|
# @option options [Cache] :cache
|
||||||
|
# The Cache object.
|
||||||
|
# @option options [Environment] :env
|
||||||
|
# The Environment executing the builder.
|
||||||
|
# @option options [Hash,VarSet] :vars
|
||||||
|
# Extra construction variables.
|
||||||
|
# @option options [Object] :setup_info
|
||||||
|
# Whatever value was returned from this builder's {#setup} method call.
|
||||||
|
# @option options [true,false,nil] :command_status
|
||||||
|
# If the {#run} method returns a {ThreadedCommand}, this field will
|
||||||
|
# contain the return value from executing the command with
|
||||||
|
# Kernel.system().
|
||||||
|
# @option options [ThreadedCommand] :tc
|
||||||
|
# The {ThreadedCommand} object that was returned by the #run method.
|
||||||
|
#
|
||||||
|
# @return [String,false]
|
||||||
|
# Name of the target file on success or false on failure.
|
||||||
|
def finalize(options)
|
||||||
|
end
|
||||||
|
|
||||||
# Check if the cache is up to date for the target and if not execute the
|
# Check if the cache is up to date for the target and if not execute the
|
||||||
# build command.
|
# build command. This method does not support parallelization.
|
||||||
#
|
#
|
||||||
# @param short_cmd_string [String]
|
# @param short_cmd_string [String]
|
||||||
# Short description of build action to be printed when env.echo ==
|
# Short description of build action to be printed when env.echo ==
|
||||||
@@ -96,5 +215,59 @@ module Rscons
|
|||||||
end
|
end
|
||||||
target
|
target
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Check if the cache is up to date for the target and if not create a
|
||||||
|
# {ThreadedCommand} object to execute the build command in a thread.
|
||||||
|
#
|
||||||
|
# @since 1.10.0
|
||||||
|
#
|
||||||
|
# @param short_cmd_string [String]
|
||||||
|
# Short description of build action to be printed when env.echo ==
|
||||||
|
# :short.
|
||||||
|
# @param target [String] Name of the target file.
|
||||||
|
# @param command [Array<String>]
|
||||||
|
# The command to execute to build the target.
|
||||||
|
# @param sources [Array<String>] Source file name(s).
|
||||||
|
# @param env [Environment] The Environment executing the builder.
|
||||||
|
# @param cache [Cache] The Cache object.
|
||||||
|
# @param options [Hash] Options.
|
||||||
|
# @options options [String] :stdout
|
||||||
|
# File name to redirect standard output to.
|
||||||
|
#
|
||||||
|
# @return [String,ThreadedCommand]
|
||||||
|
# The name of the target if it is already up to date or the
|
||||||
|
# {ThreadedCommand} object created to update it.
|
||||||
|
def standard_threaded_build(short_cmd_string, target, command, sources, env, cache, options = {})
|
||||||
|
if cache.up_to_date?(target, command, sources, env)
|
||||||
|
target
|
||||||
|
else
|
||||||
|
unless Rscons.phony_target?(target)
|
||||||
|
cache.mkdir_p(File.dirname(target))
|
||||||
|
FileUtils.rm_f(target)
|
||||||
|
end
|
||||||
|
tc_options = {short_description: short_cmd_string}
|
||||||
|
if options[:stdout]
|
||||||
|
tc_options[:system_options] = {out: options[:stdout]}
|
||||||
|
end
|
||||||
|
ThreadedCommand.new(command, tc_options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Register build results from a {ThreadedCommand} with the cache.
|
||||||
|
#
|
||||||
|
# @since 1.10.0
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Builder finalize options.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# The target name on success or nil on failure.
|
||||||
|
def standard_finalize(options)
|
||||||
|
if options[:command_status]
|
||||||
|
target, sources, cache, env = options.values_at(:target, :sources, :cache, :env)
|
||||||
|
cache.register_build(target, options[:tc].command, sources, env)
|
||||||
|
target
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -7,6 +7,7 @@ module Rscons
|
|||||||
# env.CFile("parser.tab.cc", "parser.yy")
|
# env.CFile("parser.tab.cc", "parser.yy")
|
||||||
# env.CFile("lex.yy.cc", "parser.ll")
|
# env.CFile("lex.yy.cc", "parser.ll")
|
||||||
class CFile < Builder
|
class CFile < Builder
|
||||||
|
|
||||||
# Return default construction variables for the builder.
|
# Return default construction variables for the builder.
|
||||||
#
|
#
|
||||||
# @param env [Environment] The Environment using the builder.
|
# @param env [Environment] The Environment using the builder.
|
||||||
@@ -17,9 +18,11 @@ module Rscons
|
|||||||
"YACC" => "bison",
|
"YACC" => "bison",
|
||||||
"YACC_FLAGS" => ["-d"],
|
"YACC_FLAGS" => ["-d"],
|
||||||
"YACC_CMD" => ["${YACC}", "${YACC_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
|
"YACC_CMD" => ["${YACC}", "${YACC_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
|
||||||
|
"YACCSUFFIX" => [".y", ".yy"],
|
||||||
"LEX" => "flex",
|
"LEX" => "flex",
|
||||||
"LEX_FLAGS" => [],
|
"LEX_FLAGS" => [],
|
||||||
"LEX_CMD" => ["${LEX}", "${LEX_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
|
"LEX_CMD" => ["${LEX}", "${LEX_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
|
||||||
|
"LEXSUFFIX" => [".l", ".ll"],
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -40,16 +43,28 @@ module Rscons
|
|||||||
})
|
})
|
||||||
cmd =
|
cmd =
|
||||||
case
|
case
|
||||||
when sources.first.end_with?(".l", ".ll")
|
when sources.first.end_with?(*env.expand_varref("${LEXSUFFIX}"))
|
||||||
"LEX"
|
"LEX"
|
||||||
when sources.first.end_with?(".y", ".yy")
|
when sources.first.end_with?(*env.expand_varref("${YACCSUFFIX}"))
|
||||||
"YACC"
|
"YACC"
|
||||||
else
|
else
|
||||||
raise "Unknown source file #{sources.first.inspect} for CFile builder"
|
raise "Unknown source file #{sources.first.inspect} for CFile builder"
|
||||||
end
|
end
|
||||||
command = env.build_command("${#{cmd}_CMD}", vars)
|
command = env.build_command("${#{cmd}_CMD}", vars)
|
||||||
standard_build("#{cmd} #{target}", target, command, sources, env, cache)
|
standard_threaded_build("#{cmd} #{target}", target, command, sources, env, cache)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Finalize a build.
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Finalize options.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# The target name on success or nil on failure.
|
||||||
|
def finalize(options)
|
||||||
|
standard_finalize(options)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -9,25 +9,40 @@ module Rscons
|
|||||||
# env.Command("docs.html", "docs.md",
|
# env.Command("docs.html", "docs.md",
|
||||||
# CMD => %w[pandoc -fmarkdown -thtml -o${_TARGET} ${_SOURCES}])
|
# CMD => %w[pandoc -fmarkdown -thtml -o${_TARGET} ${_SOURCES}])
|
||||||
class Command < Builder
|
class Command < Builder
|
||||||
|
|
||||||
# Run the builder to produce a build target.
|
# Run the builder to produce a build target.
|
||||||
#
|
#
|
||||||
# @param target [String] Target file name.
|
# @param options [Hash] Builder run options.
|
||||||
# @param sources [Array<String>] Source file name(s).
|
|
||||||
# @param cache [Cache] The Cache object.
|
|
||||||
# @param env [Environment] The Environment executing the builder.
|
|
||||||
# @param vars [Hash,VarSet] Extra construction variables.
|
|
||||||
#
|
#
|
||||||
# @return [String,false]
|
# @return [String, ThreadedCommand]
|
||||||
# Name of the target file on success or false on failure.
|
# Target file name if target is up to date or a {ThreadedCommand}
|
||||||
def run(target, sources, cache, env, vars)
|
# to execute to build the target.
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
vars = vars.merge({
|
vars = vars.merge({
|
||||||
"_TARGET" => target,
|
"_TARGET" => target,
|
||||||
"_SOURCES" => sources,
|
"_SOURCES" => sources,
|
||||||
})
|
})
|
||||||
command = env.build_command("${CMD}", vars)
|
command = env.build_command("${CMD}", vars)
|
||||||
cmd_desc = vars["CMD_DESC"] || "Command"
|
cmd_desc = vars["CMD_DESC"] || "Command"
|
||||||
standard_build("#{cmd_desc} #{target}", target, command, sources, env, cache)
|
options = {}
|
||||||
|
if vars["CMD_STDOUT"]
|
||||||
|
options[:stdout] = env.expand_varref("${CMD_STDOUT}", vars)
|
||||||
end
|
end
|
||||||
|
standard_threaded_build("#{cmd_desc} #{target}", target, command, sources, env, cache, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Finalize a build.
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Finalize options.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# The target name on success or nil on failure.
|
||||||
|
def finalize(options)
|
||||||
|
standard_finalize(options)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2,6 +2,7 @@ module Rscons
|
|||||||
module Builders
|
module Builders
|
||||||
# The Disassemble builder produces a disassembly listing of a source file.
|
# The Disassemble builder produces a disassembly listing of a source file.
|
||||||
class Disassemble < Builder
|
class Disassemble < Builder
|
||||||
|
|
||||||
# Return default construction variables for the builder.
|
# Return default construction variables for the builder.
|
||||||
#
|
#
|
||||||
# @param env [Environment] The Environment using the builder.
|
# @param env [Environment] The Environment using the builder.
|
||||||
@@ -28,13 +29,28 @@ module Rscons
|
|||||||
def run(target, sources, cache, env, vars)
|
def run(target, sources, cache, env, vars)
|
||||||
vars = vars.merge("_SOURCES" => sources)
|
vars = vars.merge("_SOURCES" => sources)
|
||||||
command = env.build_command("${DISASM_CMD}", vars)
|
command = env.build_command("${DISASM_CMD}", vars)
|
||||||
unless cache.up_to_date?(target, command, sources, env)
|
if cache.up_to_date?(target, command, sources, env)
|
||||||
cache.mkdir_p(File.dirname(target))
|
|
||||||
return false unless env.execute("Disassemble #{target}", command, options: {out: target})
|
|
||||||
cache.register_build(target, command, sources, env)
|
|
||||||
end
|
|
||||||
target
|
target
|
||||||
|
else
|
||||||
|
cache.mkdir_p(File.dirname(target))
|
||||||
|
ThreadedCommand.new(
|
||||||
|
command,
|
||||||
|
short_description: "Disassemble #{target}",
|
||||||
|
system_options: {out: target})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Finalize a build.
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Finalize options.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# The target name on success or nil on failure.
|
||||||
|
def finalize(options)
|
||||||
|
standard_finalize(options)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2,6 +2,7 @@ module Rscons
|
|||||||
module Builders
|
module Builders
|
||||||
# A default Rscons builder that produces a static library archive.
|
# A default Rscons builder that produces a static library archive.
|
||||||
class Library < Builder
|
class Library < Builder
|
||||||
|
|
||||||
# Return default construction variables for the builder.
|
# Return default construction variables for the builder.
|
||||||
#
|
#
|
||||||
# @param env [Environment] The Environment using the builder.
|
# @param env [Environment] The Environment using the builder.
|
||||||
@@ -16,28 +17,48 @@ module Rscons
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set up a build operation using this builder.
|
||||||
|
#
|
||||||
|
# @param options [Hash] Builder setup options.
|
||||||
|
#
|
||||||
|
# @return [Object]
|
||||||
|
# Any object that the builder author wishes to be saved and passed back
|
||||||
|
# in to the {#run} method.
|
||||||
|
def setup(options)
|
||||||
|
target, sources, env, vars = options.values_at(:target, :sources, :env, :vars)
|
||||||
|
suffixes = env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars)
|
||||||
|
# Register builders to build each source to an object file or library.
|
||||||
|
env.register_builds(target, sources, suffixes, vars)
|
||||||
|
end
|
||||||
|
|
||||||
# Run the builder to produce a build target.
|
# Run the builder to produce a build target.
|
||||||
#
|
#
|
||||||
# @param target [String] Target file name.
|
# @param options [Hash] Builder run options.
|
||||||
# @param sources [Array<String>] Source file name(s).
|
|
||||||
# @param cache [Cache] The Cache object.
|
|
||||||
# @param env [Environment] The Environment executing the builder.
|
|
||||||
# @param vars [Hash,VarSet] Extra construction variables.
|
|
||||||
#
|
#
|
||||||
# @return [String,false]
|
# @return [String,false]
|
||||||
# Name of the target file on success or false on failure.
|
# Name of the target file on success or false on failure.
|
||||||
def run(target, sources, cache, env, vars)
|
def run(options)
|
||||||
# build sources to linkable objects
|
target, sources, cache, env, vars, objects = options.values_at(:target, :sources, :cache, :env, :vars, :setup_info)
|
||||||
objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)
|
|
||||||
if objects
|
|
||||||
vars = vars.merge({
|
vars = vars.merge({
|
||||||
'_TARGET' => target,
|
'_TARGET' => target,
|
||||||
'_SOURCES' => objects,
|
'_SOURCES' => objects,
|
||||||
})
|
})
|
||||||
|
options[:sources] = objects
|
||||||
command = env.build_command("${ARCMD}", vars)
|
command = env.build_command("${ARCMD}", vars)
|
||||||
standard_build("AR #{target}", target, command, objects, env, cache)
|
standard_threaded_build("AR #{target}", target, command, objects, env, cache)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Finalize a build.
|
||||||
|
#
|
||||||
|
# @param options [Hash]
|
||||||
|
# Finalize options.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# The target name on success or nil on failure.
|
||||||
|
def finalize(options)
|
||||||
|
standard_finalize(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3,6 +3,7 @@ module Rscons
|
|||||||
# A default Rscons builder which knows how to produce an object file from
|
# A default Rscons builder which knows how to produce an object file from
|
||||||
# various types of source files.
|
# various types of source files.
|
||||||
class Object < Builder
|
class Object < Builder
|
||||||
|
|
||||||
# Mapping of known sources from which to build object files.
|
# Mapping of known sources from which to build object files.
|
||||||
KNOWN_SUFFIXES = {
|
KNOWN_SUFFIXES = {
|
||||||
"AS" => "ASSUFFIX",
|
"AS" => "ASSUFFIX",
|
||||||
@@ -61,54 +62,66 @@ module Rscons
|
|||||||
# Return whether this builder object is capable of producing a given target
|
# Return whether this builder object is capable of producing a given target
|
||||||
# file name from a given source file name.
|
# file name from a given source file name.
|
||||||
#
|
#
|
||||||
# @param target [String] The target file name.
|
# @param target [String]
|
||||||
# @param source [String] The source file name.
|
# The target file name.
|
||||||
# @param env [Environment] The Environment.
|
# @param source [String]
|
||||||
|
# The source file name.
|
||||||
|
# @param env [Environment]
|
||||||
|
# The Environment.
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether this builder object is capable of producing a given target
|
# Whether this builder object is capable of producing a given target
|
||||||
# file name from a given source file name.
|
# file name from a given source file name.
|
||||||
def produces?(target, source, env)
|
def produces?(target, source, env)
|
||||||
target.end_with?(*env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
target.end_with?(*env['OBJSUFFIX']) and
|
||||||
|
KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
||||||
source.end_with?(*env[suffix_var])
|
source.end_with?(*env[suffix_var])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run the builder to produce a build target.
|
# Run the builder to produce a build target.
|
||||||
#
|
#
|
||||||
# @param target [String] Target file name.
|
# @param options [Hash] Builder run options.
|
||||||
# @param sources [Array<String>] Source file name(s).
|
|
||||||
# @param cache [Cache] The Cache object.
|
|
||||||
# @param env [Environment] The Environment executing the builder.
|
|
||||||
# @param vars [Hash,VarSet] Extra construction variables.
|
|
||||||
#
|
#
|
||||||
# @return [String,false]
|
# @return [String, ThreadedCommand]
|
||||||
# Name of the target file on success or false on failure.
|
# Target file name if target is up to date or a {ThreadedCommand}
|
||||||
def run(target, sources, cache, env, vars)
|
# to execute to build the target.
|
||||||
|
def run(options)
|
||||||
|
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
|
||||||
vars = vars.merge({
|
vars = vars.merge({
|
||||||
'_TARGET' => target,
|
'_TARGET' => target,
|
||||||
'_SOURCES' => sources,
|
'_SOURCES' => sources,
|
||||||
'_DEPFILE' => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)),
|
'_DEPFILE' => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)),
|
||||||
})
|
})
|
||||||
com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
||||||
sources.first.end_with?(*env.expand_varref("${#{suffix_var}}"))
|
sources.first.end_with?(*env.expand_varref("${#{suffix_var}}", vars))
|
||||||
end.tap do |v|
|
end.tap do |v|
|
||||||
v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
|
v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}"
|
||||||
end.first
|
end.first
|
||||||
command = env.build_command("${#{com_prefix}CMD}", vars)
|
command = env.build_command("${#{com_prefix}CMD}", vars)
|
||||||
unless cache.up_to_date?(target, command, sources, env)
|
# Store vars back into options so new keys are accessible in #finalize.
|
||||||
cache.mkdir_p(File.dirname(target))
|
options[:vars] = vars
|
||||||
FileUtils.rm_f(target)
|
standard_threaded_build("#{com_prefix} #{target}", target, command, sources, env, cache)
|
||||||
return false unless env.execute("#{com_prefix} #{target}", command)
|
end
|
||||||
deps = sources
|
|
||||||
|
# Finalize the build operation.
|
||||||
|
#
|
||||||
|
# @param options [Hash] Builder finalize options.
|
||||||
|
#
|
||||||
|
# @return [String, nil]
|
||||||
|
# Name of the target file on success or nil on failure.
|
||||||
|
def finalize(options)
|
||||||
|
if options[:command_status]
|
||||||
|
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, command, deps.uniq, env)
|
cache.register_build(target, options[:tc].command, deps.uniq, env)
|
||||||
end
|
|
||||||
target
|
target
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Loaded 100 of 123 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user