diff --git a/autobuild.pl b/autobuild.pl index d858e8c16..ac1a48b79 100755 --- a/autobuild.pl +++ b/autobuild.pl @@ -853,15 +853,44 @@ (\%) } } - if ($command_table{$NAME}->Run ($OPTIONS, $args) == 0) { + my $result = $command_table{$NAME}->Run ($OPTIONS, $args); + my $result_type = ref ($result); + my $failure = undef; + if ($result_type eq '') { + # This is the traditional command return mechanism. 0 is a fatal error + # and other values (usually 1) are a success. + $failure = 'fatal' if $result == 0; + } + elsif ($result_type eq 'HASH') { + # Newer command return mechanism: + # {} is success + # {failure => 'fatal'} is a fatal error intended for when something + # is probably fundamentally wrong with autobuild xml file and/or + # the command couldn't function correctly. + # {failure => 'non-fatal'} is a non-fatal error intended for when the + # command failed, but in a "normal" or at least possibly expected + # way, like if a test failed. + # (and others?) are a success. + if (exists ($result->{failure})) { + $failure = $result->{failure}; + if ($failure ne 'fatal' && $failure ne 'non-fatal') { + print STDERR "ERROR: $CMD $CMD2 " . + "set \"fail\" to unexpected value \"$failure\"\n"; + $failure = 'fatal'; + } + } + } + if (defined ($failure)) { print STDERR "ERROR: While $CMD $CMD2:\n" if ($verbose <= 1); print STDERR " The command failed"; - $status = 1; - if (!$keep_going) { - print STDERR ", exiting.\n"; - chdir ($starting_dir); - ChangeENV (%originalENV); - next INPFILE; + if ($failure eq 'fatal') { + $status = 1; + if (!$keep_going) { + print STDERR ", exiting.\n"; + chdir ($starting_dir); + ChangeENV (%originalENV); + next INPFILE; + } } print STDERR "!\n"; } diff --git a/command/cmake.pm b/command/cmake.pm index 1423cc402..177fcee71 100644 --- a/command/cmake.pm +++ b/command/cmake.pm @@ -52,6 +52,10 @@ sub Run ($) my $command_name = $self->{simple} ? "cmake_cmd" : "cmake"; + main::PrintStatus ( + ($self->{simple} && $options !~ /\W--build\W/) ? 'Configure' : 'Compile', + $command_name); + # Get cmake_var_* Autobuild Variables my @cmake_vars = (); my $autobuild_var_cmake_var_re = qr/^cmake_var_(\w+)$/; @@ -93,7 +97,7 @@ sub Run ($) else { print STDERR __FILE__, ": unexpected arg name \"$name\" in $command_name command\n"; - return 0; + return {failure => 'fatal'}; } } @@ -104,14 +108,17 @@ sub Run ($) $config_args .= " -G \"$cmake_generator\""; } + my $result = {}; + # cmake_cmd commmand if ($self->{simple}) { - return utility::run_command ("$cmake_command $options"); + utility::run_command ("$cmake_command $options", $result); + return $result; } elsif (length ($options)) { print STDERR __FILE__, ": options attribute not allowed for the cmake command\n"; - return 0; + return {failure => 'fatal'}; } # Insert cmake_var_* Autobuild Variables and var_* Arguments @@ -124,28 +131,28 @@ sub Run ($) # Recreate Build Directory if (!utility::remove_tree ($build_dir)) { - return 0; + return {failure => 'fatal'}; } if (!mkdir ($build_dir)) { print STDERR __FILE__, ": failed to make build directory \"$build_dir\": $!\n"; - return 0; + return {failure => 'fatal'}; } # Change to Build Directory my $build_cd = ChangeDir->new({dir => $build_dir}); - return 0 unless ($build_cd); + return {failure => 'fatal'} unless ($build_cd); # Run Configure CMake Command - if (!utility::run_command ("$cmake_command $config_args")) { - return 0; + if (!utility::run_command ("$cmake_command $config_args", $result)) { + return $result; } # Run Build CMake Command - if (!utility::run_command ("$cmake_command $build_args")) { - return 0; + if (!utility::run_command ("$cmake_command $build_args", $result)) { + return $result; } - return 1; + return $result; } ############################################################################## diff --git a/command/print_cmake_version.pm b/command/print_cmake_version.pm index 046bd845f..b16f9941a 100644 --- a/command/print_cmake_version.pm +++ b/command/print_cmake_version.pm @@ -46,9 +46,7 @@ sub Run ($) my $cmake_command = main::GetVariable ('cmake_command'); $cmake_command = "\"$cmake_command\" --version"; - main::PrintStatus ('Config', "print CMake Version"); - - print "

CMake version ($cmake_command)

\n"; + main::PrintStatus ('Config', "CMake Version ($cmake_command)"); return utility::run_command ($cmake_command); } diff --git a/common/utility.pm b/common/utility.pm index b337ee0eb..badf484a7 100644 --- a/common/utility.pm +++ b/common/utility.pm @@ -6,14 +6,13 @@ package utility; use File::Path qw(rmtree); # Run command, returns 0 if there was an error. If the second argument is -# passed and is true, then it always returns 1. +# passed, it's assumed to be an autobuild command result hashref and "failure" +# will be set to "fatal" if it is a total failure is fatal and "non-fatal" if +# the exit status result is just non-zero. sub run_command ($;$) { my $command = shift; - my $ignore_failure = shift; - if (!defined $ignore_failure) { - $ignore_failure = 0; - } + my $ab_command_result = shift; if ($main::verbose) { print ("===== Running Command: $command\n"); @@ -24,16 +23,25 @@ sub run_command ($;$) my $error_message; if ($? == -1) { $error_message = "Failed to Run: $!"; + if (defined ($ab_command_result)) { + $ab_command_result->{failure} = 'fatal'; + } } elsif ($signal) { $error_message = sprintf ("Exited on Signal %d, %s coredump", $signal, ($? & 128) ? 'with' : 'without'); + if (defined ($ab_command_result)) { + $ab_command_result->{failure} = 'non-fatal'; + } } else { $error_message = sprintf ("Returned %d", $? >> 8); + if (defined ($ab_command_result)) { + $ab_command_result->{failure} = 'non-fatal'; + } } print STDERR "Command \"$command\" $error_message\n"; - return $ignore_failure; + return 0; } return 1; } diff --git a/tests/autobuild/cmake/fake_cmake.pl b/tests/autobuild/cmake/fake_cmake.pl index d3e4fa58e..67a45af84 100755 --- a/tests/autobuild/cmake/fake_cmake.pl +++ b/tests/autobuild/cmake/fake_cmake.pl @@ -10,6 +10,10 @@ print ("fake_cmake.pl version 123.456.789\n"); } +if ($args =~ "<<--fail-on-purpose>>") { + exit (1); +} + my $file = "cmake_runs.txt"; open (my $fd, ">>$file") or die ("Couldn't open $file: $!"); print $fd "$args\n"; diff --git a/tests/autobuild/cmake/run_test.pl b/tests/autobuild/cmake/run_test.pl index 9c31c55cc..ee9cb128a 100755 --- a/tests/autobuild/cmake/run_test.pl +++ b/tests/autobuild/cmake/run_test.pl @@ -49,6 +49,10 @@ sub dump_log "<<--build>> <<.>>\n", "build/cmake_runs.txt"); +expect_file_contents ( + "<<..>> <<-G>> <> <<-DCMAKE_C_COMPILER=fake-cc>>\n", + "failed_build/cmake_runs.txt"); + expect_file_contents ( "<<..>> <<-G>> <> " . "<<-DCMAKE_C_COMPILER=super-fake-cc>> " . diff --git a/tests/autobuild/cmake/test.xml b/tests/autobuild/cmake/test.xml index b42b339bf..284f3b38e 100644 --- a/tests/autobuild/cmake/test.xml +++ b/tests/autobuild/cmake/test.xml @@ -11,11 +11,16 @@ - + + + failed_build + --fail-on-purpose + + super-fake-cc @@ -32,4 +37,5 @@ +