This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Restore the package name to overload errors; fix crash
[perl5.git] / Porting / bisect-runner.pl
CommitLineData
6a8dbfd7
NC
1#!/usr/bin/perl -w
2use strict;
3
4use Getopt::Long;
5
4daf2803 6my @targets = qw(miniperl lib/Config.pm perl test_prep);
6a8dbfd7
NC
7
8my $target = 'test_prep';
9my $j = '9';
10my $test_should_pass = 1;
11my $clean = 1;
12my $one_liner;
bc96a05a 13my $match;
6a8dbfd7
NC
14
15sub usage {
16 die "$0: [--target=...] [-j=4] [--expect-pass=0|1] thing to test";
17}
18
19unless(GetOptions('target=s' => \$target,
20 'jobs|j=i' => \$j,
21 'expect-pass=i' => \$test_should_pass,
22 'expect-fail' => sub { $test_should_pass = 0; },
23 'clean!' => \$clean, # mostly for debugging this
24 'one-liner|e=s' => \$one_liner,
bc96a05a 25 'match=s' => \$match,
6a8dbfd7
NC
26 )) {
27 usage();
28}
29
4daf2803
NC
30my $exe = $target eq 'perl' || $target eq 'test_prep' ? 'perl' : 'miniperl';
31my $expected = $target eq 'test_prep' ? 'perl' : $target;
6a8dbfd7 32
4daf2803 33unshift @ARGV, "./$exe", '-Ilib', '-e', $one_liner if defined $one_liner;
6a8dbfd7 34
bc96a05a 35usage() unless @ARGV || $match;
6a8dbfd7
NC
36
37die "$0: Can't build $target" unless grep {@targets} $target;
38
39$j = "-j$j" if $j =~ /\A\d+\z/;
40
41sub extract_from_file {
42 my ($file, $rx, $default) = @_;
43 open my $fh, '<', $file or die "Can't open $file: $!";
44 while (<$fh>) {
45 my @got = $_ =~ $rx;
46 return wantarray ? @got : $got[0]
47 if @got;
48 }
49 return $default if defined $default;
50 return;
51}
52
ab4a15f9
NC
53sub clean {
54 if ($clean) {
55 # Needed, because files that are build products in this checked out
56 # version might be in git in the next desired version.
57 system 'git clean -dxf';
58 # Needed, because at some revisions the build alters checked out files.
59 # (eg pod/perlapi.pod). Also undoes any changes to makedepend.SH
60 system 'git reset --hard HEAD';
61 }
62}
63
64sub skip {
65 my $reason = shift;
66 clean();
67 warn "skipping - $reason";
68 exit 125;
69}
70
f1050811
NC
71sub report_and_exit {
72 my ($ret, $pass, $fail, $desc) = @_;
73
74 clean();
75
76 my $got = ($test_should_pass ? !$ret : $ret) ? 'good' : 'bad';
77 if ($ret) {
78 print "$got - $fail $desc\n";
79 } else {
80 print "$got - $pass $desc\n";
81 }
82
83 exit($got eq 'bad');
84}
85
6a8dbfd7
NC
86# Not going to assume that system perl is yet new enough to have autodie
87system 'git clean -dxf' and die;
88
bc96a05a
NC
89if ($match) {
90 my $matches;
91 my $re = qr/$match/;
92 foreach my $file (`git ls-files`) {
93 chomp $file;
94 open my $fh, '<', $file or die "Can't open $file: $!";
95 while (<$fh>) {
96 if ($_ =~ $re) {
97 ++$matches;
98 $_ .= "\n" unless /\n\z/;
99 print "$file: $_";
100 }
101 }
102 close $fh or die "Can't close $file: $!";
103 }
104 report_and_exit(!$matches, 'matches for', 'no matches for', $match);
105}
106
4b081584
NC
107skip('no Configure - is this the //depot/perlext/Compiler branch?')
108 unless -f 'Configure';
109
dbcdc176
NC
110# This changes to PERL_VERSION in 4d8076ea25903dcb in 1999
111my $major
112 = extract_from_file('patchlevel.h',
113 qr/^#define\s+(?:PERL_VERSION|PATCHLEVEL)\s+(\d+)\s/,
114 0);
115
6a8dbfd7
NC
116# There was a bug in makedepend.SH which was fixed in version 96a8704c.
117# Symptom was './makedepend: 1: Syntax error: Unterminated quoted string'
118# Remove this if you're actually bisecting a problem related to makedepend.SH
119system 'git show blead:makedepend.SH > makedepend.SH' and die;
120
121my @paths = qw(/usr/local/lib64 /lib64 /usr/lib64);
122
123# if Encode is not needed for the test, you can speed up the bisect by
124# excluding it from the runs with -Dnoextensions=Encode
125# ccache is an easy win. Remove it if it causes problems.
126my @ARGS = ('-des', '-Dusedevel', '-Doptimize=-g', '-Dcc=ccache gcc',
127 '-Dld=gcc', "-Dlibpth=@paths");
128
129# Commit 1cfa4ec74d4933da adds ignore_versioned_solibs to Configure, and sets it
130# to true in hints/linux.sh
131# On dromedary, from that point on, Configure (by default) fails to find any
132# libraries, because it scans /usr/local/lib /lib /usr/lib, which only contain
133# versioned libraries. Without -lm, the build fails.
134# Telling /usr/local/lib64 /lib64 /usr/lib64 works from that commit onwards,
135# until commit faae14e6e968e1c0 adds it to the hints.
136# However, prior to 1cfa4ec74d4933da telling Configure the truth doesn't work,
137# because it will spot versioned libraries, pass them to the compiler, and then
138# bail out pretty early on. Configure won't let us override libswanted, but it
139# will let us override the entire libs list.
140
141unless (extract_from_file('Configure', 'ignore_versioned_solibs')) {
142 # Before 1cfa4ec74d4933da, so force the libs list.
143
144 my @libs;
145 # This is the current libswanted list from Configure, less the libs removed
146 # by current hints/linux.sh
147 foreach my $lib (qw(sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld
148 ld sun m crypt sec util c cposix posix ucb BSD)) {
149 foreach my $dir (@paths) {
150 next unless -f "$dir/lib$lib.so";
151 push @libs, "-l$lib";
152 last;
153 }
154 }
155 push @ARGS, "-Dlibs=@libs";
156}
157
4b081584
NC
158# This seems to be necessary to avoid makedepend becoming confused, and hanging
159# on stdin. Seems that the code after make shlist || ...here... is never run.
160push @ARGS, q{-Dtrnl='\n'}
161 if $major < 4;
162
6a8dbfd7
NC
163# </dev/null because it seems that some earlier versions of Configure can
164# call commands in a way that now has them reading from stdin (and hanging)
165my $pid = fork;
166die "Can't fork: $!" unless defined $pid;
167if (!$pid) {
dbcdc176
NC
168 # Before dfe9444ca7881e71, Configure would refuse to run if stdin was not a
169 # tty. With that commit, the tty requirement was dropped for -de and -dE
170 open STDIN, '<', '/dev/null' if $major > 4;
6a8dbfd7
NC
171 exec './Configure', @ARGS;
172 die "Failed to start Configure: $!";
173}
174waitpid $pid, 0
175 or die "wait for Configure, pid $pid failed: $!";
176
177# Skip if something went wrong with Configure
ab4a15f9 178skip('no config.sh') unless -f 'config.sh';
6a8dbfd7
NC
179
180# Correct makefile for newer GNU gcc
181# Only really needed if you comment out the use of blead's makedepend.SH
182{
183 local $^I = "";
184 local @ARGV = qw(makefile x2p/makefile);
185 while (<>) {
186 print unless /<(?:built-in|command|stdin)/;
187 }
188}
6a8dbfd7 189
9a999a97
NC
190# Parallel build for miniperl is safe
191system "make $j miniperl";
192
193if ($target ne 'miniperl') {
194 # Nearly all parallel build issues fixed by 5.10.0. Untrustworthy before that.
195 $j = '' unless $major > 10;
196
197 if ($target eq 'test_prep') {
198 if ($major < 8) {
199 # test-prep was added in 5.004_01, 3e3baf6d63945cb6.
200 # renamed to test_prep in 2001 in 5fe84fd29acaf55c.
201 # earlier than that, just make test. It will be fast enough.
202 $target = extract_from_file('Makefile.SH', qr/^(test[-_]prep):/,
203 'test');
204 }
6a8dbfd7 205 }
6a8dbfd7 206
9a999a97
NC
207 system "make $j $target";
208}
6a8dbfd7 209
ab4a15f9
NC
210skip("could not build $target")
211 if $expected =~ /perl$/ ? !-x $expected : !-r $expected;
6a8dbfd7
NC
212
213# This is what we came here to run:
214my $ret = system @ARGV;
215
f1050811 216report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
9a999a97
NC
217
218# Local variables:
219# cperl-indent-level: 4
220# indent-tabs-mode: nil
221# End:
222#
223# ex: set ts=8 sts=4 sw=4 et: