Compare commits

..
21 Commits
Author SHA1 Message Date
josh d60a5f0d01 Finish user guide for tasks and task parameters 2022-01-30 13:39:52 -05:00
josh ac0f6087fc Add Task#[] 2022-01-30 13:11:47 -05:00
josh f2a56f1c61 More user guide updates for tasks 2022-01-30 12:46:38 -05:00
josh c8a4accd12 Starting some large user guide updates 2022-01-29 11:27:45 -05:00
josh 7771d4c038 Fix Script execution of configure task blocks 2022-01-27 08:17:27 -05:00
josh d11981d4b2 Add specs for tasks 2022-01-26 23:36:43 -05:00
josh c3121f17cf Restore autoconf_false test 2022-01-26 22:18:46 -05:00
josh 2a9ccc2346 Print usage on invalid task option; fix a couple more tests 2022-01-26 22:10:22 -05:00
josh 679c013eaa Fix up some configure tests 2022-01-26 21:46:07 -05:00
josh 7189a04299 Fix subsidiary build tests 2022-01-26 20:55:16 -05:00
josh 9e94493531 Fix some of my broken vim substitutes 2022-01-26 19:53:54 -05:00
josh 1e5f1043d5 Update build step accounting to only count within one environment process run 2022-01-26 19:43:01 -05:00
josh 9d14cc7eb0 Cleaning up more test failures 2022-01-26 19:30:47 -05:00
josh d255c7f46e Allow task deps and params to be single values or arrays 2022-01-25 22:49:32 -05:00
josh fc17a14008 Remove "nop" builders; Install* builders always install 2022-01-25 22:45:39 -05:00
josh dbd764749b Remove Rscons.application.vars 2022-01-25 22:32:26 -05:00
josh b1b94595f6 Parse task parameters; handle configure task specially 2022-01-25 22:20:29 -05:00
josh 55dc22db05 Add --prefix as a configure task parameter 2022-01-23 21:03:30 -05:00
josh 67fa432750 Add Task::Param class 2022-01-23 20:43:21 -05:00
josh 1b3e459ada Rework Cli, fix a couple Task items 2022-01-23 19:38:21 -05:00
josh 125ab4c171 Checkpoint 2022-01-23 16:44:18 -05:00
10 changed files with 66 additions and 113 deletions

No files matched your search

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