4 # Test driver for the Make test suite
6 # Usage: run_make_tests [testname]
14 # Copyright (C) 1992-2013 Free Software Foundation, Inc.
15 # This file is part of GNU Make.
17 # GNU Make is free software; you can redistribute it and/or modify it under
18 # the terms of the GNU General Public License as published by the Free Software
19 # Foundation; either version 3 of the License, or (at your option) any later
22 # GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
23 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
24 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
27 # You should have received a copy of the GNU General Public License along with
28 # this program. If not, see <http://www.gnu.org/licenses/>.
32 $valgrind = 0; # invoke make with valgrind
34 $memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full --suppressions=guile.supp';
35 $massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xcalloc --alloc-fn=xrealloc --alloc-fn=xstrdup --alloc-fn=xstrndup';
38 # The location of the GNU make source directory
45 require "test_driver.pl";
47 # Some target systems might not have the POSIX module...
48 $has_POSIX = eval { require "POSIX.pm" };
50 #$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; };
56 if ($option =~ /^-make([-_]?path)?$/i) {
57 $make_path = shift @argv;
59 print "$option $make_path: Not found.\n";
65 if ($option =~ /^-srcdir$/i) {
66 $srcdir = shift @argv;
67 if (! -f "$srcdir/gnumake.h") {
68 print "$option $srcdir: Not a valid GNU make source directory.\n";
74 if ($option =~ /^-all([-_]?tests)?$/i) {
79 if ($option =~ /^-(valgrind|memcheck)$/i) {
81 $valgrind_args = $memcheck_args;
85 if ($option =~ /^-massif$/i) {
87 $valgrind_args = $massif_args;
91 # This doesn't work--it _should_! Someone badly needs to fix this.
93 # elsif ($option =~ /^-work([-_]?dir)?$/)
95 # $workdir = shift @argv;
103 # This is an "all-in-one" function. Arguments are as follows:
105 # [0] (string): The makefile to be tested. undef means use the last one.
106 # [1] (string): Arguments to pass to make.
107 # [2] (string): Answer we should get back.
108 # [3] (integer): Exit code we expect. A missing code means 0 (success)
110 $old_makefile = undef;
112 sub subst_make_string
115 $makefile and s/#MAKEFILE#/$makefile/g;
116 s/#MAKEPATH#/$mkpath/g;
117 s/#MAKE#/$make_name/g;
118 s/#PERL#/$perl_name/g;
125 local ($makestring, $options, $answer, $err_code, $timeout) = @_;
127 # If the user specified a makefile string, create a new makefile to contain
128 # it. If the first value is not defined, use the last one (if there is
131 if (! defined $makestring) {
132 defined $old_makefile
133 || die "run_make_test(undef) invoked before run_make_test('...')\n";
134 $makefile = $old_makefile;
136 if (! defined($makefile)) {
137 $makefile = &get_tmpfile();
140 # Make sure it ends in a newline and substitute any special tokens.
141 $makestring && $makestring !~ /\n$/s and $makestring .= "\n";
142 $makestring = subst_make_string($makestring);
144 # Populate the makefile!
145 open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
146 print MAKEFILE $makestring;
147 close(MAKEFILE) || die "Failed to write $makefile: $!\n";
150 # Do the same processing on $answer as we did on $makestring.
151 if (defined $answer) {
152 $answer && $answer !~ /\n$/s and $answer .= "\n";
153 $answer = subst_make_string($answer);
156 run_make_with_options($makefile, $options, &get_logfile(0),
157 $err_code, $timeout);
158 &compare_output($answer, &get_logfile(1));
160 $old_makefile = $makefile;
164 # The old-fashioned way...
165 sub run_make_with_options {
166 local ($filename,$options,$logname,$expected_code,$timeout) = @_;
168 local($command) = $make_path;
170 $expected_code = 0 unless defined($expected_code);
172 # Reset to reflect this one test.
176 $command .= " -f $filename";
180 $command .= " $options";
183 $command_string = "$command\n";
186 print VALGRIND "\n\nExecuting: $command\n";
191 my $old_timeout = $test_timeout;
192 $timeout and $test_timeout = $timeout;
194 # If valgrind is enabled, turn off the timeout check
195 $valgrind and $test_timeout = 0;
197 $code = &run_command_with_output($logname,$command);
199 $test_timeout = $old_timeout;
202 # Check to see if we have Purify errors. If so, keep the logfile.
203 # For this to work you need to build with the Purify flag -exit-status=yes
205 if ($pure_log && -f $pure_log) {
206 if ($code & 0x7000) {
209 # If we have a purify log, save it
210 $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
211 print("Renaming purify log file to $tn\n") if $debug;
212 rename($pure_log, "$tn")
213 || die "Can't rename $log to $tn: $!\n";
220 if ($code != $expected_code) {
221 print "Error running $make_path (expected $expected_code; got $code): $command\n";
223 $runf = &get_runfile;
224 &create_file (&get_runfile, $command_string);
225 # If it's a SIGINT, stop here
227 print STDERR "\nCaught signal ".($code & 127)."!\n";
228 ($code & 127) == 2 and exit($code);
233 if ($profile & $vos) {
234 system "add_profile $make_path";
242 &print_standard_usage ("run_make_tests",
243 "[-make MAKE_PATHNAME] [-srcdir SRCDIR] [-memcheck] [-massif]",);
248 &print_standard_help (
250 "\tYou may specify the pathname of the copy of make to run.",
252 "\tSpecify the make source directory.",
255 "\tRun the test suite under valgrind's memcheck tool.",
256 "\tChange the default valgrind args with the VALGRIND_ARGS env var.",
258 "\tRun the test suite under valgrind's massif toool.",
259 "\tChange the default valgrind args with the VALGRIND_ARGS env var."
264 $delete_command = 'rm -f';
266 $__pwd = POSIX::getcwd();
268 $delete_command = "delete_file -no_ask";
269 $__pwd = `++(current_dir)`;
271 # No idea... just try using pwd as a last resort.
272 chop ($__pwd = `pwd`);
281 $testee = "GNU make";
283 $tmpfilesuffix = "mk";
284 $pwd = &get_this_pwd;
287 sub set_more_defaults
292 # find the type of the port. We do this up front to have a single
293 # point of change if it needs to be tweaked.
295 # This is probably not specific enough.
297 if ($osname =~ /Windows/i || $osname =~ /MINGW32/i || $osname =~ /CYGWIN_NT/i) {
300 # Bleah, the osname is so variable on DOS. This kind of bites.
301 # Well, as far as I can tell if we check for some text at the
302 # beginning of the line with either no spaces or a single space, then
303 # a D, then either "OS", "os", or "ev" and a space. That should
304 # match and be pretty specific.
305 elsif ($osname =~ /^([^ ]*|[^ ]* [^ ]*)D(OS|os|ev) /) {
309 elsif ($osname =~ m%OS/2%) {
312 # Everything else, right now, is UNIX. Note that we should integrate
313 # the VOS support into this as well and get rid of $vos; we'll do
319 # On DOS/Windows system the filesystem apparently can't track
320 # timestamps with second granularity (!!). Change the sleep time
321 # needed to force a file to be considered "old".
322 $wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4;
324 print "Port type: $port_type\n" if $debug;
325 print "Make path: $make_path\n" if $debug;
327 # Find the full pathname of Make. For DOS systems this is more
328 # complicated, so we ask make itself.
329 my $mk = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`;
331 $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n
332 'echo \"all:;\@echo \\\$(MAKE)\" | $make_path -f-' failed!\n";
334 print "Make\t= '$make_path'\n" if $debug;
336 $string = `$make_path -v -f /dev/null 2> /dev/null`;
338 $string =~ /^(GNU Make [^,\n]*)/;
339 $testee_version = "$1\n";
341 $string = `sh -c "$make_path -f /dev/null 2>&1"`;
342 if ($string =~ /(.*): \*\*\* No targets\. Stop\./) {
346 $make_path =~ /^(?:.*$pathsep)?(.+)$/;
350 # prepend pwd if this is a relative path (ie, does not
351 # start with a slash, but contains one). Thanks for the
354 if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0)
356 $mkpath = "$pwd$pathsep$make_path";
360 $mkpath = $make_path;
363 # If srcdir wasn't provided on the command line, see if the
364 # location of the make program gives us a clue. Don't fail if not;
365 # we'll assume it's been installed into /usr/include or wherever.
367 $make_path =~ /^(.*$pathsep)?/;
369 -f "${d}gnumake.h" and $srcdir = $d;
372 # Not with the make program, so see if we can get it out of the makefile
373 if (! $srcdir && open(MF, "< ../Makefile")) {
377 /^abs_srcdir\s*=\s*(.*?)\s*$/m;
378 -f "$1/gnumake.h" and $srcdir = $1;
381 # Get Purify log info--if any.
383 if (exists $ENV{PURIFYOPTIONS}
384 && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) {
385 $pure_log = $1 || '';
386 $pure_log =~ s/%v/$make_name/;
390 $string = `sh -c "$make_path -j 2 -f /dev/null 2>&1"`;
391 if ($string =~ /not supported/) {
398 %FEATURES = map { $_ => 1 } split /\s+/, `sh -c "echo '\\\$(info \\\$(.FEATURES))' | $make_path -f- 2>/dev/null"`;
400 # Set up for valgrind, if requested.
403 my $args = $valgrind_args;
404 open(VALGRIND, "> valgrind.out")
405 || die "Cannot open valgrind.out: $!\n";
406 # -q --leak-check=yes
407 exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS};
408 $make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path";
410 fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n";
411 system("echo Starting on `date` 1>&".fileno(VALGRIND));
412 print "Enabled valgrind support.\n";
418 $makefile = &get_tmpfile;
423 # Get rid of any Purify logs.
425 ($pure_testname = $testname) =~ tr,/,_,;
426 $pure_testname = "$pure_log.$pure_testname";
427 system("rm -f $pure_testname*");
428 print("Purify testfiles are: $pure_testname*\n") if $debug;