Commit | Line | Data |
---|---|---|
6a8dbfd7 NC |
1 | #!/usr/bin/perl -w |
2 | use strict; | |
3 | ||
4 | use Getopt::Long; | |
5 | ||
4daf2803 | 6 | my @targets = qw(miniperl lib/Config.pm perl test_prep); |
6a8dbfd7 NC |
7 | |
8 | my $target = 'test_prep'; | |
9 | my $j = '9'; | |
10 | my $test_should_pass = 1; | |
11 | my $clean = 1; | |
12 | my $one_liner; | |
bc96a05a | 13 | my $match; |
6a8dbfd7 NC |
14 | |
15 | sub usage { | |
16 | die "$0: [--target=...] [-j=4] [--expect-pass=0|1] thing to test"; | |
17 | } | |
18 | ||
19 | unless(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 |
30 | my $exe = $target eq 'perl' || $target eq 'test_prep' ? 'perl' : 'miniperl'; |
31 | my $expected = $target eq 'test_prep' ? 'perl' : $target; | |
6a8dbfd7 | 32 | |
4daf2803 | 33 | unshift @ARGV, "./$exe", '-Ilib', '-e', $one_liner if defined $one_liner; |
6a8dbfd7 | 34 | |
bc96a05a | 35 | usage() unless @ARGV || $match; |
6a8dbfd7 NC |
36 | |
37 | die "$0: Can't build $target" unless grep {@targets} $target; | |
38 | ||
39 | $j = "-j$j" if $j =~ /\A\d+\z/; | |
40 | ||
41 | sub 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 |
53 | sub 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 | ||
64 | sub skip { | |
65 | my $reason = shift; | |
66 | clean(); | |
67 | warn "skipping - $reason"; | |
68 | exit 125; | |
69 | } | |
70 | ||
f1050811 NC |
71 | sub 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 |
87 | system 'git clean -dxf' and die; | |
88 | ||
bc96a05a NC |
89 | if ($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 | ||
6a8dbfd7 NC |
107 | # There was a bug in makedepend.SH which was fixed in version 96a8704c. |
108 | # Symptom was './makedepend: 1: Syntax error: Unterminated quoted string' | |
109 | # Remove this if you're actually bisecting a problem related to makedepend.SH | |
110 | system 'git show blead:makedepend.SH > makedepend.SH' and die; | |
111 | ||
112 | my @paths = qw(/usr/local/lib64 /lib64 /usr/lib64); | |
113 | ||
114 | # if Encode is not needed for the test, you can speed up the bisect by | |
115 | # excluding it from the runs with -Dnoextensions=Encode | |
116 | # ccache is an easy win. Remove it if it causes problems. | |
117 | my @ARGS = ('-des', '-Dusedevel', '-Doptimize=-g', '-Dcc=ccache gcc', | |
118 | '-Dld=gcc', "-Dlibpth=@paths"); | |
119 | ||
120 | # Commit 1cfa4ec74d4933da adds ignore_versioned_solibs to Configure, and sets it | |
121 | # to true in hints/linux.sh | |
122 | # On dromedary, from that point on, Configure (by default) fails to find any | |
123 | # libraries, because it scans /usr/local/lib /lib /usr/lib, which only contain | |
124 | # versioned libraries. Without -lm, the build fails. | |
125 | # Telling /usr/local/lib64 /lib64 /usr/lib64 works from that commit onwards, | |
126 | # until commit faae14e6e968e1c0 adds it to the hints. | |
127 | # However, prior to 1cfa4ec74d4933da telling Configure the truth doesn't work, | |
128 | # because it will spot versioned libraries, pass them to the compiler, and then | |
129 | # bail out pretty early on. Configure won't let us override libswanted, but it | |
130 | # will let us override the entire libs list. | |
131 | ||
132 | unless (extract_from_file('Configure', 'ignore_versioned_solibs')) { | |
133 | # Before 1cfa4ec74d4933da, so force the libs list. | |
134 | ||
135 | my @libs; | |
136 | # This is the current libswanted list from Configure, less the libs removed | |
137 | # by current hints/linux.sh | |
138 | foreach my $lib (qw(sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld | |
139 | ld sun m crypt sec util c cposix posix ucb BSD)) { | |
140 | foreach my $dir (@paths) { | |
141 | next unless -f "$dir/lib$lib.so"; | |
142 | push @libs, "-l$lib"; | |
143 | last; | |
144 | } | |
145 | } | |
146 | push @ARGS, "-Dlibs=@libs"; | |
147 | } | |
148 | ||
149 | # </dev/null because it seems that some earlier versions of Configure can | |
150 | # call commands in a way that now has them reading from stdin (and hanging) | |
151 | my $pid = fork; | |
152 | die "Can't fork: $!" unless defined $pid; | |
153 | if (!$pid) { | |
154 | open STDIN, '<', '/dev/null'; | |
155 | exec './Configure', @ARGS; | |
156 | die "Failed to start Configure: $!"; | |
157 | } | |
158 | waitpid $pid, 0 | |
159 | or die "wait for Configure, pid $pid failed: $!"; | |
160 | ||
161 | # Skip if something went wrong with Configure | |
ab4a15f9 | 162 | skip('no config.sh') unless -f 'config.sh'; |
6a8dbfd7 NC |
163 | |
164 | # Correct makefile for newer GNU gcc | |
165 | # Only really needed if you comment out the use of blead's makedepend.SH | |
166 | { | |
167 | local $^I = ""; | |
168 | local @ARGV = qw(makefile x2p/makefile); | |
169 | while (<>) { | |
170 | print unless /<(?:built-in|command|stdin)/; | |
171 | } | |
172 | } | |
173 | ||
174 | # This changes to PERL_VERSION in 4d8076ea25903dcb in 1999 | |
175 | my $major | |
176 | = extract_from_file('patchlevel.h', | |
177 | qr/^#define\s+(?:PERL_VERSION|PATCHLEVEL)\s+(\d+)\s/, | |
178 | 0); | |
179 | ||
9a999a97 NC |
180 | # Parallel build for miniperl is safe |
181 | system "make $j miniperl"; | |
182 | ||
183 | if ($target ne 'miniperl') { | |
184 | # Nearly all parallel build issues fixed by 5.10.0. Untrustworthy before that. | |
185 | $j = '' unless $major > 10; | |
186 | ||
187 | if ($target eq 'test_prep') { | |
188 | if ($major < 8) { | |
189 | # test-prep was added in 5.004_01, 3e3baf6d63945cb6. | |
190 | # renamed to test_prep in 2001 in 5fe84fd29acaf55c. | |
191 | # earlier than that, just make test. It will be fast enough. | |
192 | $target = extract_from_file('Makefile.SH', qr/^(test[-_]prep):/, | |
193 | 'test'); | |
194 | } | |
6a8dbfd7 | 195 | } |
6a8dbfd7 | 196 | |
9a999a97 NC |
197 | system "make $j $target"; |
198 | } | |
6a8dbfd7 | 199 | |
ab4a15f9 NC |
200 | skip("could not build $target") |
201 | if $expected =~ /perl$/ ? !-x $expected : !-r $expected; | |
6a8dbfd7 NC |
202 | |
203 | # This is what we came here to run: | |
204 | my $ret = system @ARGV; | |
205 | ||
f1050811 | 206 | report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV"); |
9a999a97 NC |
207 | |
208 | # Local variables: | |
209 | # cperl-indent-level: 4 | |
210 | # indent-tabs-mode: nil | |
211 | # End: | |
212 | # | |
213 | # ex: set ts=8 sts=4 sw=4 et: |