Move rsconscache into build directory - close #136
This commit is contained in:
parent
a2f72c6b87
commit
97dbaeb82d
@ -78,9 +78,12 @@ cache file in order to avoid rebuilding a target when it is already up to date.
|
|||||||
### Build Directory
|
### Build Directory
|
||||||
|
|
||||||
Rscons was designed to store temporary build artifacts (for example, object
|
Rscons was designed to store temporary build artifacts (for example, object
|
||||||
files, dependency files, etc...) in a `build` directory.
|
files, dependency files, etc...) and build system metadata in a
|
||||||
|
"build directory".
|
||||||
This keeps files generated by the build cleanly separated from user-controlled
|
This keeps files generated by the build cleanly separated from user-controlled
|
||||||
source files.
|
source files.
|
||||||
|
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.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@ -94,7 +97,7 @@ To use Rscons on your project, you must:
|
|||||||
|
|
||||||
Rscons is designed to be distributed as a stand-alone single file script that
|
Rscons is designed to be distributed as a stand-alone single file script that
|
||||||
can be copied into and versioned in a project's source tree.
|
can be copied into and versioned in a project's source tree.
|
||||||
The only dependency required to run Rscons is to have a Ruby interpreter
|
The only requirement to run Rscons is that the system has a Ruby interpreter
|
||||||
installed.
|
installed.
|
||||||
The latest release can be downloaded from [https://github.com/holtrop/rscons/releases](https://github.com/holtrop/rscons/releases).
|
The latest release can be downloaded from [https://github.com/holtrop/rscons/releases](https://github.com/holtrop/rscons/releases).
|
||||||
Simply copy the `rscons` executable script into the desired location within
|
Simply copy the `rscons` executable script into the desired location within
|
||||||
|
@ -5,6 +5,10 @@ module Rscons
|
|||||||
# Functionality for an instance of the rscons application invocation.
|
# Functionality for an instance of the rscons application invocation.
|
||||||
class Application
|
class Application
|
||||||
|
|
||||||
|
# @return [String]
|
||||||
|
# Top-level build directory.
|
||||||
|
attr_accessor :build_dir
|
||||||
|
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether to output ANSI color escape sequences.
|
# Whether to output ANSI color escape sequences.
|
||||||
attr_accessor :do_ansi_color
|
attr_accessor :do_ansi_color
|
||||||
@ -23,6 +27,7 @@ module Rscons
|
|||||||
|
|
||||||
# Create Application instance.
|
# Create Application instance.
|
||||||
def initialize
|
def initialize
|
||||||
|
@build_dir = "build"
|
||||||
@n_threads = Util.determine_n_threads
|
@n_threads = Util.determine_n_threads
|
||||||
@vars = VarSet.new
|
@vars = VarSet.new
|
||||||
@operations = Set.new
|
@operations = Set.new
|
||||||
@ -171,11 +176,8 @@ module Rscons
|
|||||||
# Exit code.
|
# Exit code.
|
||||||
def distclean
|
def distclean
|
||||||
cache = Cache.instance
|
cache = Cache.instance
|
||||||
build_dir = cache["configuration_data"]["build_dir"]
|
|
||||||
clean
|
clean
|
||||||
if build_dir
|
FileUtils.rm_rf(@build_dir)
|
||||||
FileUtils.rm_rf(build_dir)
|
|
||||||
end
|
|
||||||
cache.clear
|
cache.clear
|
||||||
0
|
0
|
||||||
end
|
end
|
||||||
|
@ -51,9 +51,6 @@ module Rscons
|
|||||||
# }
|
# }
|
||||||
class Cache
|
class Cache
|
||||||
|
|
||||||
# Name of the file to store cache information in
|
|
||||||
CACHE_FILE = ".rsconscache"
|
|
||||||
|
|
||||||
# Prefix for phony cache entries.
|
# Prefix for phony cache entries.
|
||||||
PHONY_PREFIX = ":PHONY:"
|
PHONY_PREFIX = ":PHONY:"
|
||||||
|
|
||||||
@ -70,6 +67,11 @@ module Rscons
|
|||||||
initialize!
|
initialize!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Get the path to the cache file.
|
||||||
|
def cache_file
|
||||||
|
File.join(Rscons.application.build_dir, ".rsconscache")
|
||||||
|
end
|
||||||
|
|
||||||
# Access cache value.
|
# Access cache value.
|
||||||
def [](key)
|
def [](key)
|
||||||
@cache[key]
|
@cache[key]
|
||||||
@ -84,7 +86,7 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def clear
|
def clear
|
||||||
FileUtils.rm_f(CACHE_FILE)
|
FileUtils.rm_f(cache_file)
|
||||||
initialize!
|
initialize!
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -100,7 +102,7 @@ module Rscons
|
|||||||
# @return [void]
|
# @return [void]
|
||||||
def write
|
def write
|
||||||
@cache["version"] = VERSION
|
@cache["version"] = VERSION
|
||||||
File.open(CACHE_FILE, "w") do |fh|
|
File.open(cache_file, "w") do |fh|
|
||||||
fh.puts(JSON.dump(@cache))
|
fh.puts(JSON.dump(@cache))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -360,9 +362,9 @@ module Rscons
|
|||||||
# Create a Cache object and load in the previous contents from the cache
|
# Create a Cache object and load in the previous contents from the cache
|
||||||
# file.
|
# file.
|
||||||
def initialize!
|
def initialize!
|
||||||
@cache = JSON.load(File.read(CACHE_FILE)) rescue {}
|
@cache = JSON.load(File.read(cache_file)) rescue {}
|
||||||
unless @cache.is_a?(Hash)
|
unless @cache.is_a?(Hash)
|
||||||
$stderr.puts "Warning: #{CACHE_FILE} was corrupt. Contents:\n#{@cache.inspect}"
|
$stderr.puts "Warning: #{cache_file} was corrupt. Contents:\n#{@cache.inspect}"
|
||||||
@cache = {}
|
@cache = {}
|
||||||
end
|
end
|
||||||
@cache["targets"] ||= {}
|
@cache["targets"] ||= {}
|
||||||
|
@ -6,6 +6,7 @@ USAGE = <<EOF
|
|||||||
Usage: #{$0} [global options] [operation] [operation options]
|
Usage: #{$0} [global options] [operation] [operation options]
|
||||||
|
|
||||||
Global options:
|
Global options:
|
||||||
|
-b BUILD, --build=BUILD Set build directory (default: build)
|
||||||
-f FILE Use FILE as Rsconscript
|
-f FILE Use FILE as Rsconscript
|
||||||
-F, --show-failure Show failed command log from previous build and exit
|
-F, --show-failure Show failed command log from previous build and exit
|
||||||
-h, --help Show rscons help and exit
|
-h, --help Show rscons help and exit
|
||||||
@ -23,7 +24,6 @@ Operations:
|
|||||||
uninstall Uninstall project from installation destination
|
uninstall Uninstall project from installation destination
|
||||||
|
|
||||||
Configure options:
|
Configure options:
|
||||||
-b BUILD, --build=BUILD Set build directory (default: build)
|
|
||||||
--prefix=PREFIX Set installation prefix (default: /usr/local)
|
--prefix=PREFIX Set installation prefix (default: /usr/local)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@ -56,6 +56,10 @@ module Rscons
|
|||||||
private
|
private
|
||||||
|
|
||||||
def add_global_options(opts)
|
def add_global_options(opts)
|
||||||
|
opts.on("-b", "--build DIR") do |build_dir|
|
||||||
|
Rscons.application.build_dir = build_dir
|
||||||
|
end
|
||||||
|
|
||||||
opts.on("-j NTHREADS") do |n_threads|
|
opts.on("-j NTHREADS") do |n_threads|
|
||||||
Rscons.application.n_threads = n_threads.to_i
|
Rscons.application.n_threads = n_threads.to_i
|
||||||
end
|
end
|
||||||
@ -156,10 +160,6 @@ module Rscons
|
|||||||
end
|
end
|
||||||
|
|
||||||
def parse_configure_args(opts, argv, options)
|
def parse_configure_args(opts, argv, options)
|
||||||
opts.on("-b", "--build DIR") do |build_dir|
|
|
||||||
options[:build_dir] = build_dir
|
|
||||||
end
|
|
||||||
|
|
||||||
opts.on("--prefix PREFIX") do |prefix|
|
opts.on("--prefix PREFIX") do |prefix|
|
||||||
options[:prefix] = prefix
|
options[:prefix] = prefix
|
||||||
end
|
end
|
||||||
|
@ -9,30 +9,25 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
# Optional parameters.
|
# Optional parameters.
|
||||||
# @option options [String] :build_dir
|
|
||||||
# Build directory.
|
|
||||||
# @option options [String] :prefix
|
# @option options [String] :prefix
|
||||||
# Install prefix.
|
# Install prefix.
|
||||||
# @option options [String] :project_name
|
# @option options [String] :project_name
|
||||||
# Project name.
|
# Project name.
|
||||||
def initialize(options)
|
def initialize(options)
|
||||||
# Default options.
|
# Default options.
|
||||||
options[:build_dir] ||= "build"
|
|
||||||
options[:prefix] ||= "/usr/local"
|
options[:prefix] ||= "/usr/local"
|
||||||
@work_dir = "#{options[:build_dir]}/configure"
|
@work_dir = "#{Rscons.application.build_dir}/configure"
|
||||||
FileUtils.mkdir_p(@work_dir)
|
FileUtils.mkdir_p(@work_dir)
|
||||||
@log_fh = File.open("#{@work_dir}/config.log", "wb")
|
@log_fh = File.open("#{@work_dir}/config.log", "wb")
|
||||||
cache = Cache.instance
|
cache = Cache.instance
|
||||||
cache["failed_commands"] = []
|
cache["failed_commands"] = []
|
||||||
cache["configuration_data"] = {}
|
cache["configuration_data"] = {}
|
||||||
cache["configuration_data"]["build_dir"] = options[:build_dir]
|
|
||||||
cache["configuration_data"]["prefix"] = options[:prefix]
|
cache["configuration_data"]["prefix"] = options[:prefix]
|
||||||
if project_name = options[:project_name]
|
if project_name = options[:project_name]
|
||||||
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
|
Ansi.write($stdout, "Configuring ", :cyan, project_name, :reset, "...\n")
|
||||||
else
|
else
|
||||||
$stdout.puts "Configuring project..."
|
$stdout.puts "Configuring project..."
|
||||||
end
|
end
|
||||||
Ansi.write($stdout, "Setting build directory... ", :green, options[:build_dir], :reset, "\n")
|
|
||||||
Ansi.write($stdout, "Setting prefix... ", :green, options[:prefix], :reset, "\n")
|
Ansi.write($stdout, "Setting prefix... ", :green, options[:prefix], :reset, "\n")
|
||||||
store_merge("prefix" => options[:prefix])
|
store_merge("prefix" => options[:prefix])
|
||||||
end
|
end
|
||||||
|
@ -97,7 +97,7 @@ module Rscons
|
|||||||
else
|
else
|
||||||
:short
|
:short
|
||||||
end
|
end
|
||||||
@build_root = "#{Cache.instance["configuration_data"]["build_dir"]}/e.#{@id}"
|
@build_root = "#{Rscons.application.build_dir}/e.#{@id}"
|
||||||
@n_threads = Rscons.application.n_threads
|
@n_threads = Rscons.application.n_threads
|
||||||
|
|
||||||
if block_given?
|
if block_given?
|
||||||
|
@ -208,6 +208,15 @@ EOF
|
|||||||
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "builds a C program with one source file in an alternate build directory" do
|
||||||
|
test_dir("simple")
|
||||||
|
result = run_rscons(rscons_args: %w[-b b])
|
||||||
|
expect(result.stderr).to eq ""
|
||||||
|
expect(Dir.exist?("build")).to be_falsey
|
||||||
|
expect(File.exists?("b/e.1/simple.c.o")).to be_truthy
|
||||||
|
expect(nr(`./simple.exe`)).to eq "This is a simple C program\n"
|
||||||
|
end
|
||||||
|
|
||||||
it "allows specifying a Builder object as the source to another build target" do
|
it "allows specifying a Builder object as the source to another build target" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
result = run_rscons(rsconscript: "builder_as_source.rb")
|
result = run_rscons(rsconscript: "builder_as_source.rb")
|
||||||
@ -1296,7 +1305,8 @@ EOF
|
|||||||
context "Cache management" do
|
context "Cache management" do
|
||||||
it "prints a warning when the cache is corrupt" do
|
it "prints a warning when the cache is corrupt" do
|
||||||
test_dir("simple")
|
test_dir("simple")
|
||||||
File.open(Rscons::Cache::CACHE_FILE, "w") do |fh|
|
FileUtils.mkdir("build")
|
||||||
|
File.open("build/.rsconscache", "w") do |fh|
|
||||||
fh.puts("[1]")
|
fh.puts("[1]")
|
||||||
end
|
end
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
@ -1748,6 +1758,22 @@ EOF
|
|||||||
expect(result.status).to_not eq 0
|
expect(result.status).to_not eq 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "automatically runs the configure operation if the project is not yet configured in the given build directory" do
|
||||||
|
test_dir "configure"
|
||||||
|
|
||||||
|
result = run_rscons(rsconscript: "check_c_compiler.rb")
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
context "check_c_compiler" do
|
context "check_c_compiler" do
|
||||||
{"check_c_compiler.rb" => "when no arguments are given",
|
{"check_c_compiler.rb" => "when no arguments are given",
|
||||||
"check_c_compiler_find_first.rb" => "when arguments are given"}.each_pair do |rsconscript, desc|
|
"check_c_compiler_find_first.rb" => "when arguments are given"}.each_pair do |rsconscript, desc|
|
||||||
@ -2284,7 +2310,6 @@ EOF
|
|||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.status).to eq 0
|
expect(result.status).to eq 0
|
||||||
expect(result.stdout).to match /Configuring configure test\.\.\./
|
expect(result.stdout).to match /Configuring configure test\.\.\./
|
||||||
expect(result.stdout).to match /Setting build directory\.\.\. bb/
|
|
||||||
expect(result.stdout).to match %r{Setting prefix\.\.\. /my/prefix}
|
expect(result.stdout).to match %r{Setting prefix\.\.\. /my/prefix}
|
||||||
expect(result.stdout).to match /Checking for C compiler\.\.\. gcc/
|
expect(result.stdout).to match /Checking for C compiler\.\.\. gcc/
|
||||||
expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. g\+\+/
|
expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. g\+\+/
|
||||||
@ -2295,6 +2320,8 @@ EOF
|
|||||||
expect(result.stdout).to match /Checking for D import 'std.stdio'\.\.\. found/
|
expect(result.stdout).to match /Checking for D import 'std.stdio'\.\.\. found/
|
||||||
expect(result.stdout).to match /Checking for library 'm'\.\.\. found/
|
expect(result.stdout).to match /Checking for library 'm'\.\.\. found/
|
||||||
expect(result.stdout).to match /Checking for program 'ls'\.\.\. .*ls/
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
it "aggregates multiple set_define's" do
|
it "aggregates multiple set_define's" do
|
||||||
@ -2357,7 +2384,6 @@ EOF
|
|||||||
expect(result.status).to eq 0
|
expect(result.status).to eq 0
|
||||||
expect(File.exists?("simple.o")).to be_falsey
|
expect(File.exists?("simple.o")).to be_falsey
|
||||||
expect(File.exists?("build")).to be_falsey
|
expect(File.exists?("build")).to be_falsey
|
||||||
expect(File.exists?(Rscons::Cache::CACHE_FILE)).to be_falsey
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user