load configuration data when constructing a new Environment - close #60

This commit is contained in:
Josh Holtrop 2018-11-23 21:23:19 -05:00
parent 6dd9c835ce
commit bfdf3a12fd
5 changed files with 84 additions and 108 deletions

View File

@ -28,7 +28,6 @@ module Rscons
@vars = VarSet.new @vars = VarSet.new
@build_dir = "build" @build_dir = "build"
@prefix = "/usr/local" @prefix = "/usr/local"
@default_environment = Environment.new
end end
# Run the specified operation. # Run the specified operation.
@ -91,7 +90,7 @@ module Rscons
end end
Ansi.write($stdout, "Setting build directory... ", :green, @build_dir, :reset, "\n") Ansi.write($stdout, "Setting build directory... ", :green, @build_dir, :reset, "\n")
rv = 0 rv = 0
co = ConfigureOp.new("#{@build_dir}/configure", @default_environment) co = ConfigureOp.new("#{@build_dir}/configure")
begin begin
@script.configure(co) @script.configure(co)
rescue ConfigureOp::ConfigureFailure rescue ConfigureOp::ConfigureFailure

View File

@ -124,6 +124,7 @@ module Rscons
def write def write
if @dirty || (@cache["version"] != VERSION) if @dirty || (@cache["version"] != VERSION)
@cache["version"] = VERSION @cache["version"] = VERSION
validate_json_object(@cache)
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

View File

@ -12,11 +12,8 @@ module Rscons
# #
# @param work_dir [String] # @param work_dir [String]
# Work directory for configure operation. # Work directory for configure operation.
# @param env [Environment] def initialize(work_dir)
# Environment aggregating the configuration options.
def initialize(work_dir, env)
@work_dir = work_dir @work_dir = work_dir
@env = env
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")
end end
@ -95,7 +92,7 @@ module Rscons
command = [program, *args, package].compact command = [program, *args, package].compact
stdout, _, status = log_and_test_command(command) stdout, _, status = log_and_test_command(command)
if status == 0 if status == 0
parse_flags(stdout) store_parse(stdout, options)
end end
common_config_checks(status, options) common_config_checks(status, options)
end end
@ -116,7 +113,7 @@ module Rscons
"_SOURCES" => "#{@work_dir}/cfgtest.c", "_SOURCES" => "#{@work_dir}/cfgtest.c",
"_TARGET" => "#{@work_dir}/cfgtest.exe", "_TARGET" => "#{@work_dir}/cfgtest.exe",
} }
command = @env.build_command("${LDCMD}", vars) command = Environment.new.build_command("${LDCMD}", vars)
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
common_config_checks(status, options) common_config_checks(status, options)
end end
@ -137,7 +134,7 @@ module Rscons
"_SOURCES" => "#{@work_dir}/cfgtest.cxx", "_SOURCES" => "#{@work_dir}/cfgtest.cxx",
"_TARGET" => "#{@work_dir}/cfgtest.exe", "_TARGET" => "#{@work_dir}/cfgtest.exe",
} }
command = @env.build_command("${LDCMD}", vars) command = Environment.new.build_command("${LDCMD}", vars)
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
common_config_checks(status, options) common_config_checks(status, options)
end end
@ -158,7 +155,7 @@ module Rscons
"_SOURCES" => "#{@work_dir}/cfgtest.d", "_SOURCES" => "#{@work_dir}/cfgtest.d",
"_TARGET" => "#{@work_dir}/cfgtest.exe", "_TARGET" => "#{@work_dir}/cfgtest.exe",
} }
command = @env.build_command("${LDCMD}", vars) command = Environment.new.build_command("${LDCMD}", vars)
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
common_config_checks(status, options) common_config_checks(status, options)
end end
@ -179,7 +176,7 @@ module Rscons
"_SOURCES" => "#{@work_dir}/cfgtest.c", "_SOURCES" => "#{@work_dir}/cfgtest.c",
"_TARGET" => "#{@work_dir}/cfgtest.exe", "_TARGET" => "#{@work_dir}/cfgtest.exe",
} }
command = @env.build_command("${LDCMD}", vars) command = Environment.new.build_command("${LDCMD}", vars)
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
common_config_checks(status, options) common_config_checks(status, options)
end end
@ -237,7 +234,7 @@ module Rscons
end end
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
if status == 0 if status == 0
merge_vars(merge) store_merge(merge)
true true
end end
end end
@ -273,7 +270,7 @@ module Rscons
end end
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
if status == 0 if status == 0
merge_vars(merge) store_merge(merge)
true true
end end
end end
@ -301,10 +298,11 @@ module Rscons
merge = {"DC" => "gdc"} merge = {"DC" => "gdc"}
when "ldc2" when "ldc2"
command = %W[ldc2 -of #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.d] command = %W[ldc2 -of #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.d]
env = Environment.new
merge = { merge = {
"DC" => "ldc2", "DC" => "ldc2",
"DCCMD" => @env["DCCMD"].map {|e| if e == "-o"; "-of"; else; e; end}, "DCCMD" => env["DCCMD"].map {|e| if e == "-o"; "-of"; else; e; end},
"LDCMD" => @env["LDCMD"].map {|e| if e == "-o"; "-of"; else; e; end}, "LDCMD" => env["LDCMD"].map {|e| if e == "-o"; "-of"; else; e; end},
} }
else else
$stderr.puts "Unknown D compiler (#{dc})" $stderr.puts "Unknown D compiler (#{dc})"
@ -312,7 +310,7 @@ module Rscons
end end
_, _, status = log_and_test_command(command) _, _, status = log_and_test_command(command)
if status == 0 if status == 0
merge_vars(merge) store_merge(merge)
true true
end end
end end
@ -331,34 +329,59 @@ module Rscons
end end
end end
# Merge construction variables into the configured Environment. # Store construction variables for merging into the Cache.
# #
# @param vars [Hash] # @param vars [Hash]
# Hash containing the variables to merge. # Hash containing the variables to merge.
def merge_vars(vars) # @param options [Hash]
# Options.
def store_merge(vars, options = {})
usename = options[:use] || "_default_"
cache = Cache.instance
cache.configuration_data["vars"] ||= {}
cache.configuration_data["vars"][usename] ||= {}
cache.configuration_data["vars"][usename]["merge"] ||= {}
vars.each_pair do |key, value| vars.each_pair do |key, value|
@env[key] = value cache.configuration_data["vars"][usename]["merge"][key] = value
end end
end end
# Merge construction variables into the configured Environment. # Store construction variables for appending into the Cache.
#
# This method does the same thing as {#merge_vars}, except that Array
# values in +vars+ are appended to the end of Array construction variables
# instead of replacing their contents.
# #
# @param vars [Hash] # @param vars [Hash]
# Hash containing the variables to merge. # Hash containing the variables to append.
def append_vars(vars) # @param options [Hash]
vars.each_pair do |key, val| # Options.
if @env[key].is_a?(Array) and val.is_a?(Array) def store_append(vars, options = {})
@env[key] += val usename = options[:use] || "_default_"
cache = Cache.instance
cache.configuration_data["vars"] ||= {}
cache.configuration_data["vars"][usename] ||= {}
cache.configuration_data["vars"][usename]["append"] ||= {}
vars.each_pair do |key, value|
if cache.configuration_data["vars"][usename]["append"][key].is_a?(Array) and value.is_a?(Array)
cache.configuration_data["vars"][usename]["append"][key] += value
else else
@env[key] = val cache.configuration_data["vars"][usename]["append"][key] = value
end end
end end
end end
# Store flags to be parsed into the Cache.
#
# @param flags [String]
# String containing the flags to parse.
# @param options [Hash]
# Options.
def store_parse(flags, options = {})
usename = options[:use] || "_default_"
cache = Cache.instance
cache.configuration_data["vars"] ||= {}
cache.configuration_data["vars"][usename] ||= {}
cache.configuration_data["vars"][usename]["parse"] ||= []
cache.configuration_data["vars"][usename]["parse"] << flags
end
# Perform processing common to several configure checks. # Perform processing common to several configure checks.
# #
# @param status [Process::Status, Integer] # @param status [Process::Status, Integer]
@ -384,7 +407,7 @@ module Rscons
end end
end end
if options[:set_define] if options[:set_define]
@env["CPPDEFINES"] << options[:set_define] store_append("CPPDEFINES" => options[:set_define])
end end
end end
@ -417,82 +440,5 @@ module Rscons
end end
end end
# Parse compilation flags (from a program like pkg-config for example).
#
# @param flags [String]
# Compilation flags.
def parse_flags(flags)
vars = {}
words = Shellwords.split(flags)
skip = false
words.each_with_index do |word, i|
if skip
skip = false
next
end
append = lambda do |var, val|
vars[var] ||= []
vars[var] += val
end
handle = lambda do |var, val|
if val.nil? or val.empty?
val = words[i + 1]
skip = true
end
if val and not val.empty?
append[var, [val]]
end
end
if word == "-arch"
if val = words[i + 1]
append["CCFLAGS", ["-arch", val]]
append["LDFLAGS", ["-arch", val]]
end
skip = true
elsif word =~ /^#{@env["CPPDEFPREFIX"]}(.*)$/
handle["CPPDEFINES", $1]
elsif word == "-include"
if val = words[i + 1]
append["CCFLAGS", ["-include", val]]
end
skip = true
elsif word == "-isysroot"
if val = words[i + 1]
append["CCFLAGS", ["-isysroot", val]]
append["LDFLAGS", ["-isysroot", val]]
end
skip = true
elsif word =~ /^#{@env["INCPREFIX"]}(.*)$/
handle["CPPPATH", $1]
elsif word =~ /^#{@env["LIBLINKPREFIX"]}(.*)$/
handle["LIBS", $1]
elsif word =~ /^#{@env["LIBDIRPREFIX"]}(.*)$/
handle["LIBPATH", $1]
elsif word == "-mno-cygwin"
append["CCFLAGS", [word]]
append["LDFLAGS", [word]]
elsif word == "-mwindows"
append["LDFLAGS", [word]]
elsif word == "-pthread"
append["CCFLAGS", [word]]
append["LDFLAGS", [word]]
elsif word =~ /^-Wa,(.*)$/
append["ASFLAGS", $1.split(",")]
elsif word =~ /^-Wl,(.*)$/
append["LDFLAGS", $1.split(",")]
elsif word =~ /^-Wp,(.*)$/
append["CPPFLAGS", $1.split(",")]
elsif word.start_with?("-")
append["CCFLAGS", [word]]
elsif word.start_with?("+")
append["CCFLAGS", [word]]
append["LDFLAGS", [word]]
else
append["LIBS", [word]]
end
end
append_vars(vars)
end
end end
end end

View File

@ -62,6 +62,7 @@ module Rscons
end end
@echo = options[:echo] || :short @echo = options[:echo] || :short
@build_root = options[:build_root] || "build" @build_root = options[:build_root] || "build"
load_configuration_data!
if block_given? if block_given?
yield self yield self
@ -1102,5 +1103,28 @@ module Rscons
end end
deps deps
end end
# Load construction variables saved from the configure operation.
def load_configuration_data!
if vars = Cache.instance.configuration_data["vars"]
if default_vars = vars["_default_"]
apply_configuration_data!(default_vars)
end
end
end
def apply_configuration_data!(vars)
if merge_vars = vars["merge"]
append(merge_vars)
end
if append_vars = vars["append"]
merge_flags(append_vars)
end
if parse_vars = vars["parse"]
parse_vars.each do |parse_string|
parse_flags!(parse_string)
end
end
end
end end
end end

View File

@ -134,6 +134,12 @@ EOF
env = ENV.to_h env = ENV.to_h
env["PATH"] = "#{@build_test_run_dir}/_bin#{File::PATH_SEPARATOR}#{env["PATH"]}" env["PATH"] = "#{@build_test_run_dir}/_bin#{File::PATH_SEPARATOR}#{env["PATH"]}"
stdout, stderr, status = Open3.capture3(env, *command) stdout, stderr, status = Open3.capture3(env, *command)
File.open("#{@build_test_run_dir}/.stdout", "wb") do |fh|
fh.write(stdout)
end
File.open("#{@build_test_run_dir}/.stderr", "wb") do |fh|
fh.write(stderr)
end
end end
# Remove output lines generated as a result of the test environment # Remove output lines generated as a result of the test environment
stderr = stderr.lines.find_all do |line| stderr = stderr.lines.find_all do |line|