From 415fa424d1dabecbdf0c6107911f151b000ca683 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 4 Feb 2024 20:25:01 -0500 Subject: [PATCH] Fix configuration checks performed with ldc2 compiler - close #172 --- .../configure/check_d_compiler_find_first.rb | 2 +- build_tests/configure/check_lib_with_ldc.rb | 8 +++ lib/rscons/configure_op.rb | 57 +++++++++++++++---- lib/rscons/default_construction_variables.rb | 8 ++- spec/build_tests_spec.rb | 15 ++++- 5 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 build_tests/configure/check_lib_with_ldc.rb diff --git a/build_tests/configure/check_d_compiler_find_first.rb b/build_tests/configure/check_d_compiler_find_first.rb index 4467e4a..abe416d 100644 --- a/build_tests/configure/check_d_compiler_find_first.rb +++ b/build_tests/configure/check_d_compiler_find_first.rb @@ -1,3 +1,3 @@ configure do - check_d_compiler "gdc", "ldc2" + check_d_compiler "gdc", "ldc2", "ldc" end diff --git a/build_tests/configure/check_lib_with_ldc.rb b/build_tests/configure/check_lib_with_ldc.rb new file mode 100644 index 0000000..ee0a354 --- /dev/null +++ b/build_tests/configure/check_lib_with_ldc.rb @@ -0,0 +1,8 @@ +configure do + check_d_compiler "ldc2" + check_lib "z" +end + +env(echo: :command) do |env| + env.Program("simple.exe", "simple.d") +end diff --git a/lib/rscons/configure_op.rb b/lib/rscons/configure_op.rb index 5bab789..672b855 100644 --- a/lib/rscons/configure_op.rb +++ b/lib/rscons/configure_op.rb @@ -1,5 +1,6 @@ require "fileutils" require "open3" +require "set" module Rscons # Class to manage a configure operation. @@ -10,6 +11,7 @@ module Rscons # @param script [Script] # Build script. def initialize(script) + @tested_compilers = {} @work_dir = "#{Rscons.application.build_dir}/_configure" FileUtils.mkdir_p(@work_dir) @log_file_name = "#{@work_dir}/config.log" @@ -65,6 +67,10 @@ module Rscons cc = ccc.find do |cc| test_c_compiler(cc, options) end + if cc + @tested_compilers["c"] ||= Set.new + @tested_compilers["c"] << cc + end complete(cc ? 0 : 1, options.merge( success_message: cc, fail_message: "not found (checked #{ccc.join(", ")})")) @@ -89,6 +95,10 @@ module Rscons cc = ccc.find do |cc| test_cxx_compiler(cc, options) end + if cc + @tested_compilers["cxx"] ||= Set.new + @tested_compilers["cxx"] << cc + end complete(cc ? 0 : 1, options.merge( success_message: cc, fail_message: "not found (checked #{ccc.join(", ")})")) @@ -108,11 +118,15 @@ module Rscons end if cdc.empty? # Default D compiler search array. - cdc = %w[gdc ldc2] + cdc = %w[gdc ldc2 ldc] end dc = cdc.find do |dc| test_d_compiler(dc, options) end + if dc + @tested_compilers["d"] ||= Set.new + @tested_compilers["d"] << dc + end complete(dc ? 0 : 1, options.merge( success_message: dc, fail_message: "not found (checked #{cdc.join(", ")})")) @@ -252,17 +266,36 @@ module Rscons def check_lib(lib, options = {}) check_libpath = [nil] + (options[:check_libpath] || []) Ansi.write($stdout, "Checking for library '", :cyan, lib, :reset, "'... ") - File.open("#{@work_dir}/cfgtest.c", "wb") do |fh| - fh.puts <<-EOF - int main(int argc, char * argv[]) { - return 0; - } - EOF + if @tested_compilers["d"] + source_file = "#{@work_dir}/cfgtest.d" + File.open(source_file, "wb") do |fh| + fh.puts <<-EOF + int main() { + return 0; + } + EOF + end + else + source_file = "#{@work_dir}/cfgtest.c" + File.open(source_file, "wb") do |fh| + fh.puts <<-EOF + int main(int argc, char * argv[]) { + return 0; + } + EOF + end + end + ld = "${CC}" + %w[d cxx c].each do |language| + if @tested_compilers[language] + ld = @tested_compilers[language].first + break + end end vars = { - "LD" => "${CC}", + "LD" => ld, "LIBS" => [lib], - "_SOURCES" => "#{@work_dir}/cfgtest.c", + "_SOURCES" => source_file, "_TARGET" => "#{@work_dir}/cfgtest.exe", } status = 1 @@ -496,8 +529,10 @@ module Rscons env = BasicEnvironment.new merge = { "DC" => dc, - "DCCMD" => env["DCCMD"].map {|e| e.sub(/^-o$/, "-of")}, - "LDCMD" => env["LDCMD"].map {|e| e.sub(/^-o$/, "-of")}, + "DC:-o" => "-of", + "LD:-o" => "-of", + "LIBDIRPREFIX" => "-L-L", + "LIBLINKPREFIX" => "-L-l", "DDEPGEN" => ["-deps=${_DEPFILE}"], } merge["OBJSUFFIX"] = [ldc_objsuffix] diff --git a/lib/rscons/default_construction_variables.rb b/lib/rscons/default_construction_variables.rb index 5f25374..d03159d 100644 --- a/lib/rscons/default_construction_variables.rb +++ b/lib/rscons/default_construction_variables.rb @@ -35,8 +35,9 @@ module Rscons "CXXFLAGS" => [], "CXXSUFFIX" => %w[.cc .cpp .cxx .C], "DC" => "gdc", - "DCCMD" => %w[${DC} -c -o ${_TARGET} ${DDEPGEN} ${INCPREFIX}${D_IMPORT_PATH} ${DFLAGS} ${_SOURCES}], - "DCCMD:direct" => %w[${DC} -o ${_TARGET} ${DDEPGEN} ${INCPREFIX}${D_IMPORT_PATH} ${DFLAGS} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}], + "DC:-o" => "-o", + "DCCMD" => %w[${DC} -c ${DC:-o} ${_TARGET} ${DDEPGEN} ${INCPREFIX}${D_IMPORT_PATH} ${DFLAGS} ${_SOURCES}], + "DCCMD:direct" => %w[${DC} ${DC:-o} ${_TARGET} ${DDEPGEN} ${INCPREFIX}${D_IMPORT_PATH} ${DFLAGS} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}], "DDEPGEN" => %w[-MMD -MF ${_DEPFILE}], "DEPFILESUFFIX" => ".mf", "DFLAGS" => [], @@ -46,7 +47,8 @@ module Rscons "D_IMPORT_PATH" => [], "INCPREFIX" => "-I", "LD" => nil, - "LDCMD" => %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}], + "LD:-o" => "-o", + "LDCMD" => %w[${LD} ${LD:-o} ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}], "LDFLAGS" => [], "LEX" => "flex", "LEX_CMD" => %w[${LEX} ${LEX_FLAGS} -o ${_TARGET} ${_SOURCES}], diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index 55d0b8b..82c3e61 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -2047,10 +2047,11 @@ EOF test_dir "configure" create_exe "gdc", "exit 1" create_exe "ldc2", "exit 1" + create_exe "ldc", "exit 1" result = run_rscons(args: %W[-f #{rsconscript} configure]) expect(result.stderr).to match %r{Configuration failed; log file written to build/_configure/config.log} expect(result.status).to_not eq 0 - expect(result.stdout).to match /Checking for D compiler\.\.\. not found \(checked gdc, ldc2\)/ + expect(result.stdout).to match /Checking for D compiler\.\.\. not found \(checked gdc, ldc2, ldc\)/ end end end @@ -2287,6 +2288,18 @@ EOF expect(result.stdout).to_not match /-lm/ end + it "finds the requested library with only ldc compiler" do + test_dir "configure" + create_exe "gcc", "exit 1" + create_exe "clang", "exit 1" + create_exe "gcc++", "exit 1" + create_exe "clang++", "exit 1" + result = run_rscons(args: %w[-f check_lib_with_ldc.rb]) + expect(result.stderr).to eq "" + expect(result.status).to eq 0 + expect(result.stdout).to match /Checking for library 'z'... found/ + end + it "modifies LIBPATH based on check_libpath" do test_dir "configure" FileUtils.mkdir_p("usr1")