Support naming environments - close #140

This commit is contained in:
Josh Holtrop 2022-01-13 12:56:23 -05:00
parent 97dbaeb82d
commit a316c4f922
6 changed files with 65 additions and 9 deletions

View File

@ -0,0 +1,6 @@
build do
Environment.new(name: "typical") do |env|
env["CPPPATH"] += glob("src/**")
env.Program("^/typical.exe", glob("src/**/*.c"))
end
end

View File

@ -0,0 +1,9 @@
build do
base_env = Environment.new do |env|
env["CPPPATH"] += glob("src/**")
end
base_env.clone(name: "typical") do |env|
env.Program("^/typical.exe", glob("src/**/*.c"))
end
end

View File

@ -82,6 +82,15 @@ files, dependency files, etc...) and build system metadata in a
"build directory".
This keeps files generated by the build cleanly separated from user-controlled
source files.
In contrast to other build systems or build system generators, rscons executes
from the project base directory (up to the user) rather than executing from
*within* the build directory.
This keeps any file paths printed by compilers (such as in warning or error
messages) accurate relative to the project directory, so that the user does not
need to translate any paths to the correct path within a terminal or editor
application, for example.
By default a build directory named "build" is used, but this can be overridden
by the user by using the `-b`/`--build` command-line option.
@ -495,21 +504,26 @@ source files found recursively under the `src` directory.
An Environment includes:
- a name
- a collection of construction variables
- a collection of build hooks
- a collection of user-registered build targets
- a build root
All build targets must be registered within an `Environment`.
If the user does not specify a name for the environment, a name will be
automatically generated based on the Environment's internal ID, for example
"e.1".
The Environment's build root is a directory created within the top-level
Rscons build directory.
It is based on the Environment name.
By default it holds all intermediate files generated by Rscons that are needed
to produce a user-specified build target.
For example, for the `Rsconscript`:
```ruby
build do
Environment.new do |env|
Environment.new(name: "myproj") do |env|
env.Program("myprog.exe", glob("src/**/*.c"))
end
end
@ -517,6 +531,8 @@ end
Rscons will place an object file and dependency file corresponding to each C
source file under the Environment's build root.
Assuming a top-level build directory of "build", the Environment's build root
would be "build/myproj".
This keeps the intermediate generated build artifacts separate from the source
files.

View File

@ -16,7 +16,7 @@ module Rscons
def initialize(options)
# Default options.
options[:prefix] ||= "/usr/local"
@work_dir = "#{Rscons.application.build_dir}/configure"
@work_dir = "#{Rscons.application.build_dir}/_configure"
FileUtils.mkdir_p(@work_dir)
@log_fh = File.open("#{@work_dir}/config.log", "wb")
cache = Cache.instance

View File

@ -51,6 +51,10 @@ module Rscons
# global Rscons.application.n_threads value.
attr_accessor :n_threads
# @return [String]
# Environment name.
attr_reader :name
# Create an Environment object.
#
# @param options [Hash]
@ -58,6 +62,9 @@ module Rscons
# :command, :short, or :off (default :short)
# @option options [Boolean] :exclude_builders
# Whether to omit adding default builders (default false)
# @option options [String, nil] :name
# Environment name. This determines the folder name used to store all
# environment build files under the top-level build directory.
# @option options [String, Array<String>] :use
# Use flag(s). If specified, any configuration flags which were saved
# with a corresponding `:use` value will be applied to this Environment.
@ -97,7 +104,8 @@ module Rscons
else
:short
end
@build_root = "#{Rscons.application.build_dir}/e.#{@id}"
@name = options[:name] || "e.#{@id}"
@build_root = "#{Rscons.application.build_dir}/#{@name}"
@n_threads = Rscons.application.n_threads
if block_given?
@ -125,14 +133,14 @@ module Rscons
#
# @return [Environment] The newly created {Environment} object.
def clone(options = {})
options = options.dup
clone = options[:clone] || :all
clone = Set[:variables, :builders, :build_hooks] if clone == :all
clone = Set[] if clone == :none
clone = Set.new(clone) if clone.is_a?(Array)
clone.delete(:builders) if options[:exclude_builders]
env = self.class.new(
echo: options[:echo] || @echo,
exclude_builders: true)
options[:echo] ||= @echo
env = self.class.new(options.merge(exclude_builders: true))
if clone.include?(:builders)
@builders.each do |builder_name, builder|
env.add_builder(builder)

View File

@ -1085,6 +1085,23 @@ EOF
expect(result.status).to eq 0
end
it "stores build artifacts in a directory according to Environment name" do
test_dir "typical"
result = run_rscons
expect(File.exist?("build/typical/typical.exe")).to be_truthy
expect(File.exist?("build/typical/src/one/one.c.o")).to be_truthy
end
it "names Environment during clone" do
test_dir "typical"
result = run_rscons(rsconscript: "clone_and_name.rb")
expect(File.exist?("build/typical/typical.exe")).to be_truthy
expect(File.exist?("build/typical/src/one/one.c.o")).to be_truthy
expect(Dir.exist?("build/e.1")).to be_falsey
end
context "colored output" do
it "does not output in color with --color=off" do
test_dir("simple")
@ -1765,13 +1782,13 @@ EOF
expect(result.stderr).to eq ""
expect(result.status).to eq 0
expect(result.stdout).to match /Checking for C compiler\.\.\./
expect(Dir.exist?("build/configure")).to be_truthy
expect(Dir.exist?("build/_configure")).to be_truthy
result = run_rscons(rsconscript: "check_c_compiler.rb", rscons_args: %w[--build=bb])
expect(result.stderr).to eq ""
expect(result.status).to eq 0
expect(result.stdout).to match /Checking for C compiler\.\.\./
expect(Dir.exist?("bb/configure")).to be_truthy
expect(Dir.exist?("bb/_configure")).to be_truthy
end
context "check_c_compiler" do
@ -2321,7 +2338,7 @@ EOF
expect(result.stdout).to match /Checking for library 'm'\.\.\. found/
expect(result.stdout).to match /Checking for program 'ls'\.\.\. .*ls/
expect(Dir.exist?("build")).to be_falsey
expect(Dir.exist?("bb/configure")).to be_truthy
expect(Dir.exist?("bb/_configure")).to be_truthy
end
it "aggregates multiple set_define's" do