From d54d363a256a4f4d17830ef9d476a018104c35b7 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 7 Nov 2018 18:53:06 -0500 Subject: [PATCH] implement ConfigureOp#check_cxx_compiler --- build_tests/configure/check_cxx_compiler.rb | 3 ++ .../check_cxx_compiler_find_first.rb | 3 ++ lib/rscons/application.rb | 3 ++ lib/rscons/configure_op.rb | 54 +++++++++++++++++++ spec/build_tests_spec.rb | 34 ++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 build_tests/configure/check_cxx_compiler.rb create mode 100644 build_tests/configure/check_cxx_compiler_find_first.rb diff --git a/build_tests/configure/check_cxx_compiler.rb b/build_tests/configure/check_cxx_compiler.rb new file mode 100644 index 0000000..56eb33e --- /dev/null +++ b/build_tests/configure/check_cxx_compiler.rb @@ -0,0 +1,3 @@ +configure do + check_cxx_compiler +end diff --git a/build_tests/configure/check_cxx_compiler_find_first.rb b/build_tests/configure/check_cxx_compiler_find_first.rb new file mode 100644 index 0000000..564c60f --- /dev/null +++ b/build_tests/configure/check_cxx_compiler_find_first.rb @@ -0,0 +1,3 @@ +configure do + check_cxx_compiler "g++", "clang++" +end diff --git a/lib/rscons/application.rb b/lib/rscons/application.rb index e7bad87..12e4a21 100644 --- a/lib/rscons/application.rb +++ b/lib/rscons/application.rb @@ -88,6 +88,9 @@ module Rscons if ccc = @script.check_c_compiler co.check_c_compiler(ccc) end + if ccc = @script.check_cxx_compiler + co.check_cxx_compiler(ccc) + end rescue ConfigureOp::ConfigureFailure rv = 1 end diff --git a/lib/rscons/configure_op.rb b/lib/rscons/configure_op.rb index 8643421..0225e42 100644 --- a/lib/rscons/configure_op.rb +++ b/lib/rscons/configure_op.rb @@ -49,6 +49,29 @@ module Rscons end end + # Check for a working C++ compiler. + # + # @param ccc [Array] + # C++ compiler(s) to check for. + # + # @return [void] + def check_cxx_compiler(ccc) + $stdout.write("Checking for C++ compiler... ") + if ccc.empty? + # Default C++ compiler search array. + ccc = %w[g++ clang++] + end + cc = ccc.find do |cc| + test_cxx_compiler(cc) + end + if cc + Ansi.write($stdout, :green, cc, "\n") + else + Ansi.write($stdout, :red, "not found\n") + raise ConfigureFailure.new + end + end + private # Test a C compiler. @@ -81,6 +104,37 @@ module Rscons status == 0 end + # Test a C++ compiler. + # + # @param cc [String] + # C++ compiler to test. + # + # @return [Boolean] + # Whether the C++ compiler tested successfully. + def test_cxx_compiler(cc) + File.open("#{@work_dir}/cfgtest.cxx", "wb") do |fh| + fh.puts <<-EOF + #include + using namespace std; + int main(int argc, char * argv[]) { + cout << "Hello." << endl; + return 0; + } + EOF + end + case cc + when "g++" + command = %W[g++ -o #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.cxx] + when "clang++" + command = %W[clang++ -o #{@work_dir}/cfgtest.exe #{@work_dir}/cfgtest.cxx] + else + $stderr.puts "Unknown C++ compiler (#{cc})" + raise ConfigureFailure.new + end + _, _, status = log_and_test_command(command) + status == 0 + end + # Execute a test command and log the result. def log_and_test_command(command) begin diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index 5fa0560..ddf9bb1 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -1534,6 +1534,40 @@ EOF end end end + + context "check_cxx_compiler" do + {"check_cxx_compiler.rb" => "when no arguments are given", + "check_cxx_compiler_find_first.rb" => "when arguments are given"}.each_pair do |rsconsfile, desc| + context desc do + it "finds the first listed C++ compiler" do + test_dir "configure" + result = run_rscons(rsconsfile: rsconsfile, op: "configure") + expect(result.stderr).to eq "" + expect(result.status).to eq 0 + expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. g\+\+/ + end + + it "finds the second listed C++ compiler" do + test_dir "configure" + create_exe "g++", "exit 1" + result = run_rscons(rsconsfile: rsconsfile, op: "configure") + expect(result.stderr).to eq "" + expect(result.status).to eq 0 + expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. clang\+\+/ + end + + it "fails to configure when it cannot find a C++ compiler" do + test_dir "configure" + create_exe "g++", "exit 1" + create_exe "clang++", "exit 1" + result = run_rscons(rsconsfile: rsconsfile, op: "configure") + expect(result.stderr).to eq "" + expect(result.status).to_not eq 0 + expect(result.stdout).to match /Checking for C\+\+ compiler\.\.\. not found/ + end + end + end + end end end