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