Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44dd279f93 | ||
|
|
7b746db64e | ||
|
|
3aca248e9d | ||
|
|
3914dd896c | ||
|
|
df120af953 | ||
|
|
b745ae1153 | ||
|
|
693f8cec64 | ||
|
|
e12acccd33 | ||
|
|
bd9cf55b85 |
No files matched your search
+1
-1
@@ -7,7 +7,7 @@
|
||||
|
||||
### Fixes
|
||||
|
||||
- #121 - env.depends() does not work with built-root-relative "^/" paths
|
||||
- #121 - env.depends() does not work with build-root-relative "^/" paths
|
||||
- #130 - Document -f command line option
|
||||
- #133 - Clarify failed command error message indicating to run -F
|
||||
- #134 - Document CMD_STDOUT variable for Command builder
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2019 Josh Holtrop
|
||||
Copyright (c) 2013-2022 Josh Holtrop
|
||||
|
||||
MIT License
|
||||
|
||||
|
||||
+1
-1
@@ -76,7 +76,7 @@ task :gen_large_project, [:size] => :build_dist do |task, args|
|
||||
end
|
||||
File.open("large_project/Rsconscript", "w") do |fh|
|
||||
fh.puts <<EOF
|
||||
build do
|
||||
default do
|
||||
Environment.new do |env|
|
||||
env.Program("project", glob("src/*.c"))
|
||||
end
|
||||
|
||||
+44
-35
@@ -15,12 +15,12 @@ It supports the following features:
|
||||
|
||||
At its core, Rscons is mainly an engine to:
|
||||
|
||||
* determine the proper order to perform build operations,
|
||||
* determine the proper order to perform build steps,
|
||||
* determine whether each build target is up to date or in need of rebuild, and
|
||||
* schedule those build operations across multiple threads as efficiently as possible.
|
||||
* schedule those build steps across multiple threads as efficiently as possible.
|
||||
|
||||
Along the way, Rscons provides a concise syntax for specifying common types of
|
||||
build operations, but also provides an extensible framework for performing
|
||||
build steps, but also provides an extensible framework for performing
|
||||
custom build operations as well.
|
||||
|
||||
Rscons takes inspiration from:
|
||||
@@ -48,8 +48,8 @@ ${/remove}
|
||||
### Build Correctness
|
||||
|
||||
The number one design principle in Rscons is build correctness.
|
||||
This means that a build operation will be performed when Rscons cannot
|
||||
determine that a build target is already up-to-date.
|
||||
This means that a target will be built when Rscons cannot determine that a
|
||||
build target is already up-to-date.
|
||||
A build target will be built whenever:
|
||||
|
||||
* the target file has been removed or changed since it was last built
|
||||
@@ -80,10 +80,10 @@ files coming from a particular source directory.
|
||||
|
||||
Rscons will automatically determine the number of threads to use based on the
|
||||
host CPU configuration, and will schedule jobs as efficiently as possible
|
||||
across the available threads in order to complete the build operation in as
|
||||
little time as possible.
|
||||
As development occurs and build operations are executed, Rscons makes use of a
|
||||
cache file in order to avoid rebuilding a target when it is already up to date.
|
||||
across the available threads in order to complete the build in as little time
|
||||
as possible.
|
||||
As development occurs and builders are executed, Rscons makes use of a cache
|
||||
file in order to avoid rebuilding a target when it is already up to date.
|
||||
|
||||
### Build Directory
|
||||
|
||||
@@ -130,8 +130,8 @@ The following files should be added to source control:
|
||||
* `rscons`
|
||||
* `Rsconscript`
|
||||
|
||||
Add the following contents to `.gitignore` (or the equivalent thereof for different
|
||||
version control systems):
|
||||
Add the following contents to `.gitignore` (or the equivalent thereof for
|
||||
different version control systems):
|
||||
|
||||
```
|
||||
/.rscons*
|
||||
@@ -224,7 +224,7 @@ task "build" do
|
||||
end
|
||||
|
||||
task "flash", deps: "build" do
|
||||
sh "nrfjprog", "-f", "NRF52", "--program", env.expand_path("^^/proj.elf")
|
||||
sh "nrfjprog", "-f", "NRF52", "--program", env.expand("^^/proj.elf")
|
||||
end
|
||||
```
|
||||
|
||||
@@ -649,8 +649,8 @@ The command and its output are also logged to the config.log file.
|
||||
The [`store_merge`](../yard/Rscons/ConfigureOp.html#store_merge-instance_method),
|
||||
[`store_append`](../yard/Rscons/ConfigureOp.html#store_append-instance_method),
|
||||
and [`store_parse`](../yard/Rscons/ConfigureOp.html#store_parse-instance_method)
|
||||
methods can be used to store construction variables for Environments created
|
||||
during the `build` operation.
|
||||
methods can be used to store construction variables to be used in Environments
|
||||
created later.
|
||||
Finally, the [`complete`](../yard/Rscons/ConfigureOp.html#complete-instance_method)
|
||||
method can be used to complete the configuration check and indicate a success
|
||||
or failure.
|
||||
@@ -831,7 +831,7 @@ There are several default builders that are built-in to Rscons:
|
||||
* `Directory`, which creates a directory.
|
||||
* `Disassemble`, which disassembles an object file to a disassembly listing.
|
||||
* `Install`, which installs files or directories to a specified destination.
|
||||
* `InstallDirectory`, which creates a directory during an install operation.
|
||||
* `InstallDirectory`, which creates a directory in an install destination.
|
||||
* `Library`, which collects object files into a static library archive file.
|
||||
* `Object`, which compiles source files to produce an object file.
|
||||
* `Preprocess`, which invokes the C/C++ preprocessor on a source file.
|
||||
@@ -923,8 +923,12 @@ env.Install("${prefix}/share", "share")
|
||||
|
||||
The `Install` builder can install files or directories to their installation
|
||||
target location.
|
||||
`Install` builders are only processed when the user has requested to perform
|
||||
an `install` operation from the command line.
|
||||
It functions almost identically to the `Copy` builder.
|
||||
The only difference relates to the `clean` and `uninstall` tasks.
|
||||
The `clean` task removes targets created by the `Copy` builder but not by
|
||||
the `Install` builder.
|
||||
The `uninstall` task removes targets created by the `Install` builder but not
|
||||
by the `Copy` builder.
|
||||
|
||||
####> The InstallDirectory Builder
|
||||
|
||||
@@ -934,12 +938,18 @@ env.InstallDirectory(target)
|
||||
env.InstallDirectory("${prefix}/share")
|
||||
```
|
||||
|
||||
The `InstallDirectory` builder can be used to explicitly create a directory.
|
||||
`InstallDirectory` builders are only processed when the user has requested to
|
||||
perform an `install` operation from the command line.
|
||||
The `InstallDirectory` builder can be used to explicitly create a directory in
|
||||
an installation location.
|
||||
This can also disambiguate whether the target for a subsequent builder
|
||||
(e.g. `Install`) refers to a file path or directory path.
|
||||
|
||||
It functions almost identically to the `Directory` builder.
|
||||
The only difference relates to the `clean` and `uninstall` tasks.
|
||||
The `clean` task removes targets created by the `Directory` builder but not by
|
||||
the `InstallDirectory` builder.
|
||||
The `uninstall` task removes targets created by the `InstallDirectory` builder
|
||||
but not by the `Directory` builder.
|
||||
|
||||
####> The Library Builder
|
||||
|
||||
```ruby
|
||||
@@ -1133,7 +1143,7 @@ This example script would compile all C sources under the `src` directory with
|
||||
the `-Wall` flag except for sources under the `src/tests` directory.
|
||||
|
||||
A post-build hook can be added with `env.add_post_build_hook`.
|
||||
Post-build hooks are only invoked if the build operation was a success.
|
||||
Post-build hooks are only invoked if the build step was a success.
|
||||
|
||||
Build hooks and post-build hooks can register new build targets.
|
||||
|
||||
@@ -1248,10 +1258,10 @@ environment variable.
|
||||
|
||||
The
|
||||
[`rscons`](../yard/Rscons/Script/GlobalDsl.html#rscons-instance_method)
|
||||
build script method can be used to invoke an rscons subprocess to
|
||||
perform an operation using a subsidiary rscons build script.
|
||||
build script method can be used to invoke an rscons subprocess using a
|
||||
subsidiary rscons build script.
|
||||
This can be used, for example, when a subproject is imported and a top-level
|
||||
`configure` or `build` operation should also perform the same operation in the
|
||||
`configure` or `build` task should also perform the same task in the
|
||||
subproject directory.
|
||||
|
||||
The first argument to the `rscons` method specifies either a directory name, or
|
||||
@@ -1273,7 +1283,7 @@ task "build" do
|
||||
end
|
||||
```
|
||||
|
||||
It is also perfectly valid to perform a different operation in the subsidiary
|
||||
It is also perfectly valid to perform different task(s) in the subsidiary
|
||||
script from the one being performed in the top-level script.
|
||||
For example, in a project that requires a particular cross compiler, the
|
||||
top-level `configure` script could build the necessary cross compiler using a
|
||||
@@ -1445,13 +1455,13 @@ The base constructor will set several instance attributes within the builder:
|
||||
* `@env` will contain a reference to the Environment object that registered
|
||||
the build target using the builder
|
||||
* `@vars` will contain any user-specified construction variable values that
|
||||
should be used for the build operation (overriding any Environment-wide
|
||||
should be used for the builder execution (overriding any Environment-wide
|
||||
construction variable values)
|
||||
|
||||
####> Custom Builder Operation
|
||||
|
||||
In order for a builder to perform a build operation, the builder class must
|
||||
implement a the `Builder#run()` method.
|
||||
In order for a builder to run, the builder class must implement a the
|
||||
`Builder#run()` method.
|
||||
Generally, the `run()` method will use the source file(s) to produce the target
|
||||
file.
|
||||
Here is an example of a trivial builder:
|
||||
@@ -1469,16 +1479,15 @@ end
|
||||
|
||||
##### Return Value
|
||||
|
||||
If the build operation has completed and failed, the `run` method should return
|
||||
If the builder has completed and failed, the `run` method should return
|
||||
`false`.
|
||||
In this case, generally the command executed or the builder itself would be
|
||||
expected to output something to `$stderr` indicating the reason for the build
|
||||
failure.
|
||||
If the build operation has completed successfully, the `run` method should
|
||||
If the builder has completed successfully, the `run` method should
|
||||
return `true`.
|
||||
If the build operation is not yet complete and is waiting on other operations,
|
||||
the `run` method should return the return value from the `Builder#wait_for`
|
||||
method.
|
||||
If the builder is not yet complete and is waiting on other steps, the `run`
|
||||
method should return the return value from the `Builder#wait_for` method.
|
||||
See ${#Custom Builder Parallelization}.
|
||||
|
||||
##### Printing Build Status
|
||||
@@ -1552,9 +1561,9 @@ In any of these cases, the builder's `run` method should make use of
|
||||
`Builder#wait_for` to "sleep" until one of the items being waited for has
|
||||
completed.
|
||||
|
||||
###### Using a Ruby Thread to Parallelize a Build Operation
|
||||
###### Using a Ruby Thread to Parallelize a Builder
|
||||
|
||||
Here is an example of using a Ruby thread to parallelize a build operation:
|
||||
Here is an example of using a Ruby thread to parallelize a builder:
|
||||
|
||||
```ruby
|
||||
${include build_tests/custom_builder/wait_for_thread.rb}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require "net/http"
|
||||
require "digest"
|
||||
require_relative "rscons/ansi"
|
||||
require_relative "rscons/application"
|
||||
require_relative "rscons/basic_environment"
|
||||
|
||||
@@ -103,7 +103,7 @@ module Rscons
|
||||
# @return [void]
|
||||
def produces(*side_effects)
|
||||
side_effects.each do |side_effect|
|
||||
side_effect_expanded = @env.expand_path(@env.expand_varref(side_effect))
|
||||
side_effect_expanded = @env.expand(side_effect)
|
||||
@env.register_side_effect(side_effect_expanded)
|
||||
@side_effects << side_effect_expanded
|
||||
end
|
||||
|
||||
@@ -337,10 +337,10 @@ module Rscons
|
||||
unless vars.is_a?(Hash) or vars.is_a?(VarSet)
|
||||
raise "Unexpected construction variable set: #{vars.inspect}"
|
||||
end
|
||||
target = expand_path(expand_varref(target))
|
||||
target = expand(target)
|
||||
sources = Array(sources).map do |source|
|
||||
source = source.target if source.is_a?(Builder)
|
||||
expand_path(expand_varref(source))
|
||||
expand(source)
|
||||
end.flatten
|
||||
builder = @builders[method.to_s].new(
|
||||
target: target,
|
||||
@@ -369,12 +369,12 @@ module Rscons
|
||||
if target.is_a?(Builder)
|
||||
target = target.target
|
||||
end
|
||||
target = expand_path(expand_varref(target.to_s))
|
||||
target = expand(target.to_s)
|
||||
user_deps = user_deps.map do |ud|
|
||||
if ud.is_a?(Builder)
|
||||
ud = ud.target
|
||||
end
|
||||
expand_path(expand_varref(ud))
|
||||
expand(ud)
|
||||
end
|
||||
@user_deps[target] ||= []
|
||||
@user_deps[target] = (@user_deps[target] + user_deps).uniq
|
||||
@@ -408,13 +408,13 @@ module Rscons
|
||||
targets = Array(targets)
|
||||
prerequisites = Array(prerequisites)
|
||||
targets.each do |target|
|
||||
target = expand_path(expand_varref(target))
|
||||
target = expand(target)
|
||||
@registered_build_dependencies[target] ||= Set.new
|
||||
prerequisites.each do |prerequisite|
|
||||
if prerequisite.is_a?(Builder)
|
||||
prerequisite = prerequisite.target
|
||||
end
|
||||
prerequisite = expand_path(expand_varref(prerequisite))
|
||||
prerequisite = expand(prerequisite)
|
||||
@registered_build_dependencies[target] << prerequisite
|
||||
end
|
||||
end
|
||||
@@ -430,7 +430,7 @@ module Rscons
|
||||
#
|
||||
# @return [void]
|
||||
def produces(target, *side_effects)
|
||||
target = expand_path(expand_varref(target))
|
||||
target = expand(target)
|
||||
@builder_sets.reverse.each do |builder_set|
|
||||
if builders = builder_set[target]
|
||||
builders.last.produces(*side_effects)
|
||||
@@ -514,6 +514,18 @@ module Rscons
|
||||
end
|
||||
end
|
||||
|
||||
# Expand construction variable references and paths.
|
||||
#
|
||||
# @param expr [String]
|
||||
# Expression to expand. Can contain construction variable references and
|
||||
# a path.
|
||||
#
|
||||
# @return [String, Array<String>]
|
||||
# Expanded value.
|
||||
def expand(expr)
|
||||
expand_path(expand_varref(expr))
|
||||
end
|
||||
|
||||
# Print the builder run message, depending on the Environment's echo mode.
|
||||
#
|
||||
# @param builder [Builder]
|
||||
|
||||
@@ -37,6 +37,39 @@ module Rscons
|
||||
end.sort
|
||||
end
|
||||
|
||||
# Download a file.
|
||||
#
|
||||
# @param url [String]
|
||||
# URL.
|
||||
# @param dest [String]
|
||||
# Path to where to save the file.
|
||||
# @param options [Hash]
|
||||
# Options.
|
||||
# @option options [String] :sha256sum
|
||||
# Expected file checksum.
|
||||
#
|
||||
# @return [void]
|
||||
def download(url, dest, options = {})
|
||||
if File.exist?(dest) && options[:sha256sum]
|
||||
if Digest::SHA2.hexdigest(File.binread(dest)) == options[:sha256sum]
|
||||
# Destination file already exists and has the expected checksum.
|
||||
return
|
||||
end
|
||||
end
|
||||
uri = URI(url)
|
||||
http = Net::HTTP.new(uri.host)
|
||||
digest = Digest::SHA2.new
|
||||
File.open(dest, "wb") do |fh|
|
||||
http.get(uri.path) do |data|
|
||||
fh.write(data)
|
||||
digest << data
|
||||
end
|
||||
end
|
||||
if options[:sha256sum] && options[:sha256sum] != digest.hexdigest
|
||||
raise RsconsError.new("Unexpected checksum on #{dest}")
|
||||
end
|
||||
end
|
||||
|
||||
# Construct a task parameter.
|
||||
#
|
||||
# @param name [String]
|
||||
|
||||
@@ -7,23 +7,15 @@
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
#body-table {
|
||||
#body-content {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#body-left-border {
|
||||
width: 10px;
|
||||
background-image: linear-gradient(to right, #CCC, #000, #FFF);
|
||||
}
|
||||
#body-right-border {
|
||||
width: 10px;
|
||||
background-image: linear-gradient(to right, #FFF, #000, #CCC);
|
||||
}
|
||||
#body-center {
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
border: 1px solid black;
|
||||
background-color: #FFF;
|
||||
width: 120ex;
|
||||
padding: 1ex;
|
||||
padding: 2ex;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
@@ -71,12 +63,6 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table id="body-table">
|
||||
<tr>
|
||||
<td id="body-left-border"></td>
|
||||
<td id="body-center"><%= content %></td>
|
||||
<td id="body-right-border"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="body-content"><%= content %></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -60,6 +60,8 @@ combined_file.each do |line|
|
||||
end
|
||||
end
|
||||
|
||||
license = File.read("LICENSE.txt").gsub(/^/, "# ")
|
||||
|
||||
require "zlib"
|
||||
require "base64"
|
||||
compressed_script = Zlib::Deflate.deflate(stripped.join)
|
||||
@@ -71,6 +73,9 @@ FileUtils.mkdir_p(DIST)
|
||||
File.open("#{DIST}/#{PROG_NAME}", "wb", 0755) do |fh|
|
||||
fh.write(<<EOF)
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
#{license}
|
||||
|
||||
script = File.join(File.dirname(__FILE__), ".rscons-#{VERSION}-#{hash}.rb")
|
||||
unless File.exists?(script)
|
||||
if File.read(__FILE__, mode: "rb") =~ /^#==>(.*)/
|
||||
|
||||
Reference in new issue
Block a user