This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
In bisect-runner.pl, refactor the code to extract previous versions of files.
[perl5.git] / Porting / bisect-runner.pl
CommitLineData
6a8dbfd7
NC
1#!/usr/bin/perl -w
2use strict;
3
390a69a9 4use Getopt::Long qw(:config bundling no_auto_abbrev);
77ae6092 5use Pod::Usage;
2526f4b8 6use Config;
69bf9aba 7use Carp;
6a8dbfd7 8
2526f4b8
NC
9my @targets
10 = qw(config.sh config.h miniperl lib/Config.pm Fcntl perl test_prep);
6a8dbfd7 11
e4516dd0
NC
12my $cpus;
13if (open my $fh, '<', '/proc/cpuinfo') {
14 while (<$fh>) {
15 ++$cpus if /^processor\s+:\s+\d+$/;
16 }
d64af352
NC
17} elsif (-x '/sbin/sysctl') {
18 $cpus = 1 + $1 if `/sbin/sysctl hw.ncpu` =~ /^hw\.ncpu: (\d+)$/;
da83cd31
NC
19} elsif (-x '/usr/bin/getconf') {
20 $cpus = 1 + $1 if `/usr/bin/getconf _NPROCESSORS_ONLN` =~ /^(\d+)$/;
e4516dd0
NC
21}
22
f4800c99
NC
23my %options =
24 (
e4516dd0 25 jobs => defined $cpus ? $cpus + 1 : 2,
f4800c99
NC
26 'expect-pass' => 1,
27 clean => 1, # mostly for debugging this
28 );
6a8dbfd7 29
fdbac266
NC
30my $linux64 = `uname -sm` eq "Linux x86_64\n" ? '64' : '';
31
599ee4f7
NC
32my @paths;
33
34if ($^O eq 'linux') {
35 # This is the search logic for a multi-arch library layout
36 # added to linux.sh in commits 40f026236b9959b7 and dcffd848632af2c7.
37 my $gcc = -x '/usr/bin/gcc' ? '/usr/bin/gcc' : 'gcc';
38
39 foreach (`$gcc -print-search-dirs`) {
40 next unless /^libraries: =(.*)/;
41 foreach (split ':', $1) {
42 next if m/gcc/;
43 next unless -d $_;
44 s!/$!!;
45 push @paths, $_;
46 }
47 }
48}
49
50push @paths, map {$_ . $linux64} qw(/usr/local/lib /lib /usr/lib);
390a69a9
NC
51
52my %defines =
53 (
54 usedevel => '',
55 optimize => '-g',
9913adee
NC
56 cc => 'ccache cc',
57 ld => 'cc',
fdbac266 58 ($linux64 ? (libpth => \@paths) : ()),
390a69a9
NC
59 );
60
f4800c99
NC
61unless(GetOptions(\%options,
62 'target=s', 'jobs|j=i', 'expect-pass=i',
63 'expect-fail' => sub { $options{'expect-pass'} = 0; },
64 'clean!', 'one-liner|e=s', 'match=s', 'force-manifest',
77ae6092 65 'test-build', 'check-args', 'A=s@', 'usage|help|?',
390a69a9
NC
66 'D=s@' => sub {
67 my (undef, $val) = @_;
68 if ($val =~ /\A([^=]+)=(.*)/s) {
69 $defines{$1} = length $2 ? $2 : "\0";
70 } else {
71 $defines{$val} = '';
72 }
73 },
74 'U=s@' => sub {
75 $defines{$_[1]} = undef;
76 },
6a8dbfd7 77 )) {
77ae6092 78 pod2usage(exitval => 255, verbose => 1);
6a8dbfd7
NC
79}
80
f4800c99 81my ($target, $j, $match) = @options{qw(target jobs match)};
e295b7be 82
77ae6092
NC
83pod2usage(exitval => 255, verbose => 1) if $options{usage};
84pod2usage(exitval => 255, verbose => 1)
85 unless @ARGV || $match || $options{'test-build'} || defined $options{'one-liner'};
6a8dbfd7 86
f4800c99 87exit 0 if $options{'check-args'};
6a8dbfd7 88
77ae6092
NC
89=head1 NAME
90
91bisect.pl - use git bisect to pinpoint changes
92
93=head1 SYNOPSIS
94
95 # When did this become an error?
96 .../Porting/bisect.pl -e 'my $a := 2;'
71d80638 97 # When did this stop being an error?
77ae6092
NC
98 .../Porting/bisect.pl --expect-fail -e '1 // 2'
99 # When did this stop matching?
100 .../Porting/bisect.pl --match '\b(?:PL_)hash_seed_set\b'
101 # When did this start matching?
102 .../Porting/bisect.pl --expect-fail --match '\buseithreads\b'
103 # When did this test program stop working?
d398528a 104 .../Porting/bisect.pl -- ./perl -Ilib ../test_prog.pl
77ae6092
NC
105 # When did this first become valid syntax?
106 .../Porting/bisect.pl --target=miniperl --end=v5.10.0 \
107 --expect-fail -e 'my $a := 2;'
108 # What was the last revision to build with these options?
109 .../Porting/bisect.pl --test-build -Dd_dosuid
110
111=head1 DESCRIPTION
112
facd1b88 113Together F<bisect.pl> and F<bisect-runner.pl> attempt to automate the use
77ae6092
NC
114of C<git bisect> as much as possible. With one command (and no other files)
115it's easy to find out
116
117=over 4
118
119=item *
120
121Which commit caused this example code to break?
122
123=item *
124
125Which commit caused this example code to start working?
126
127=item *
128
129Which commit added the first to match this regex?
130
131=item *
132
133Which commit removed the last to match this regex?
134
135=back
136
137usually without needing to know which versions of perl to use as start and
138end revisions.
139
facd1b88 140By default F<bisect.pl> will process all options, then use the rest of the
77ae6092
NC
141command line as arguments to list C<system> to run a test case. By default,
142the test case should pass (exit with 0) on earlier perls, and fail (exit
facd1b88 143non-zero) on I<blead>. F<bisect.pl> will use F<bisect-runner.pl> to find the
77ae6092 144earliest stable perl version on which the test case passes, check that it
facd1b88 145fails on blead, and then use F<bisect-runner.pl> with C<git bisect run> to
77ae6092
NC
146find the commit which caused the failure.
147
148Because the test case is the complete argument to C<system>, it is easy to
149run something other than the F<perl> built, if necessary. If you need to run
150the perl built, you'll probably need to invoke it as C<./perl -Ilib ...>
151
5842706e
NC
152You need a clean checkout to run a bisect, and you can't use the checkout
153which contains F<Porting/bisect.pl> (because C<git bisect>) will check out
154a revision before F<Porting/bisect-runner.pl> was added, which
155C<git bisect run> needs). If your working checkout is called F<perl>, the
156simplest solution is to make a local clone, and run from that. I<i.e.>:
157
158 cd ..
159 git clone perl perl2
160 cd perl2
161 ../perl/Porting/bisect.pl ...
162
facd1b88 163By default, F<bisect-runner.pl> will automatically disable the build of
cfadff5f
NC
164L<DB_File> for commits earlier than ccb44e3bf3be2c30, as it's not practical
165to patch DB_File 1.70 and earlier to build with current Berkeley DB headers.
166(ccb44e3bf3be2c30 was in September 1999, between 5.005_62 and 5.005_63.)
167If your F<db.h> is old enough you can override this with C<-Unoextensions>.
168
77ae6092
NC
169=head1 OPTIONS
170
171=over 4
172
173=item *
174
175--start I<commit-ish>
176
177Earliest revision to test, as a I<commit-ish> (a tag, commit or anything
facd1b88 178else C<git> understands as a revision). If not specified, F<bisect.pl> will
77ae6092
NC
179search stable perl releases from 5.002 to 5.14.0 until it finds one where
180the test case passes.
181
182=item *
183
184--end I<commit-ish>
185
186Most recent revision to test, as a I<commit-ish>. If not specified, defaults
b4f0ec5f 187to I<blead>.
77ae6092
NC
188
189=item *
190
191--target I<target>
192
193F<Makefile> target (or equivalent) needed, to run the test case. If specified,
194this should be one of
195
196=over 4
197
198=item *
199
200I<config.sh>
201
facd1b88 202Just run F<./Configure>
77ae6092
NC
203
204=item *
205
206I<config.h>
207
208Run the various F<*.SH> files to generate F<Makefile>, F<config.h>, I<etc>.
209
210=item *
211
212I<miniperl>
213
214Build F<miniperl>.
215
216=item *
217
218I<lib/Config.pm>
219
220Use F<miniperl> to build F<lib/Config.pm>
221
222=item *
223
2526f4b8
NC
224I<Fcntl>
225
226Build F<lib/auto/Fcntl/Fnctl.so> (strictly, C<.$Config{so}>). As L<Fcntl>
227is simple XS module present since 5.000, this provides a fast test of
b4f0ec5f 228whether XS modules can be built. Note, XS modules are built by F<miniperl>,
2526f4b8
NC
229hence this target will not build F<perl>.
230
231=item *
232
77ae6092
NC
233I<perl>
234
235Build F<perl>. This also builds pure-Perl modules in F<cpan>, F<dist> and
2526f4b8
NC
236F<ext>. XS modules (such as L<Fcntl>) are not built.
237
238=item *
239
77ae6092
NC
240I<test_prep>
241
242Build everything needed to run the tests. This is the default if we're
243running test code, but is time consuming, as it means building all
b4f0ec5f 244XS modules. For older F<Makefile>s, the previous name of C<test-prep>
77ae6092
NC
245is automatically substituted. For very old F<Makefile>s, C<make test> is
246run, as there is no target provided to just get things ready, and for 5.004
247and earlier the tests run very quickly.
248
249=back
250
251=item *
252
253--one-liner 'code to run'
254
255=item *
256
257-e 'code to run'
258
a1756669 259Example code to run, just like you'd use with C<perl -e>.
77ae6092
NC
260
261This prepends C<./perl -Ilib -e 'code to run'> to the test case given,
facd1b88 262or F<./miniperl> if I<target> is C<miniperl>.
77ae6092
NC
263
264(Usually you'll use C<-e> instead of providing a test case in the
facd1b88 265non-option arguments to F<bisect.pl>)
77ae6092
NC
266
267C<-E> intentionally isn't supported, as it's an error in 5.8.0 and earlier,
268which interferes with detecting errors in the example code itself.
269
270=item *
271
272--expect-fail
273
274The test case should fail for the I<start> revision, and pass for the I<end>
275revision. The bisect run will find the first commit where it passes.
276
277=item *
278
af7c500f 279-Dnoextensions=Encode
77ae6092
NC
280
281=item *
282
283-Uusedevel
284
285=item *
286
287-Accflags=-DNO_MATHOMS
288
289Arguments to pass to F<Configure>. Repeated C<-A> arguments are passed
290through as is. C<-D> and C<-U> are processed in order, and override
af7c500f
NC
291previous settings for the same parameter. F<bisect-runner.pl> emulates
292C<-Dnoextensions> when F<Configure> itself does not provide it, as it's
293often very useful to be able to disable some XS extensions.
77ae6092
NC
294
295=item *
296
b4f0ec5f 297--jobs I<jobs>
77ae6092
NC
298
299=item *
300
b4f0ec5f 301-j I<jobs>
77ae6092 302
da83cd31
NC
303Number of C<make> jobs to run in parallel. If F</proc/cpuinfo> exists and
304can be parsed, or F</sbin/sysctl> exists and reports C<hw.ncpu>, or
305F</usr/bin/getconf> exists and reports C<_NPROCESSORS_ONLN> defaults to 1 +
306I<number of CPUs>. Otherwise defaults to 2.
77ae6092
NC
307
308=item *
309
b4f0ec5f 310--match pattern
77ae6092
NC
311
312Instead of running a test program to determine I<pass> or I<fail>, pass
313if the given regex matches, and hence search for the commit that removes
314the last matching file.
315
316If no I<target> is specified, the match is against all files in the
317repository (which is fast). If a I<target> is specified, that target is
318built, and the match is against only the built files. C<--expect-fail> can
319be used with C<--match> to search for a commit that adds files that match.
320
321=item *
322
323--test-build
324
325Test that the build completes, without running any test case.
326
327By default, if the build for the desired I<target> fails to complete,
328F<bisect-runner.pl> reports a I<skip> back to C<git bisect>, the assumption
329being that one wants to find a commit which changed state "builds && passes"
330to "builds && fails". If instead one is interested in which commit broke the
331build (possibly for particular F<Configure> options), use I<--test-build>
332to treat a build failure as a failure, not a "skip".
333
b4f0ec5f
NC
334Often this option isn't as useful as it first seems, because I<any> build
335failure will be reported to C<git bisect> as a failure, not just the failure
336that you're interested in. Generally, to debug a particular problem, it's
337more useful to use a I<target> that builds properly at the point of interest,
338and then a test case that runs C<make>. For example:
339
340 .../Porting/bisect.pl --start=perl-5.000 --end=perl-5.002 \
341 --expect-fail --force-manifest --target=miniperl make perl
342
facd1b88
NC
343will find the first revision capable of building L<DynaLoader> and then
344F<perl>, without becoming confused by revisions where F<miniperl> won't
b4f0ec5f
NC
345even link.
346
77ae6092
NC
347=item *
348
b4f0ec5f
NC
349--force-manifest
350
77ae6092
NC
351By default, a build will "skip" if any files listed in F<MANIFEST> are not
352present. Usually this is useful, as it avoids false-failures. However, there
353are some long ranges of commits where listed files are missing, which can
354cause a bisect to abort because all that remain are skipped revisions.
355
356In these cases, particularly if the test case uses F<miniperl> and no modules,
357it may be more useful to force the build to continue, even if files
358F<MANIFEST> are missing.
359
360=item *
361
362--expect-pass [0|1]
363
364C<--expect-pass=0> is equivalent to C<--expect-fail>. I<1> is the default.
365
366=item *
367
368--no-clean
369
370Tell F<bisect-runner.pl> not to clean up after the build. This allows one
371to use F<bisect-runner.pl> to build the current particular perl revision for
372interactive testing, or for debugging F<bisect-runner.pl>.
373
374Passing this to F<bisect.pl> will likely cause the bisect to fail badly.
375
376=item *
377
378--check-args
379
380Validate the options and arguments, and exit silently if they are valid.
381
382=item *
383
384--usage
385
386=item *
387
388--help
389
390=item *
391
392-?
393
394Display the usage information and exit.
395
396=back
397
398=cut
399
0afef97d 400die "$0: Can't build $target" if defined $target && !grep {@targets} $target;
6a8dbfd7
NC
401
402$j = "-j$j" if $j =~ /\A\d+\z/;
403
0142f0ce
NC
404# Sadly, however hard we try, I don't think that it will be possible to build
405# modules in ext/ on x86_64 Linux before commit e1666bf5602ae794 on 1999/12/29,
406# which updated to MakeMaker 3.7, which changed from using a hard coded ld
407# in the Makefile to $(LD). On x86_64 Linux the "linker" is gcc.
408
69bf9aba
NC
409sub open_or_die {
410 my $file = shift;
411 my $mode = @_ ? shift : '<';
412 open my $fh, $mode, $file or croak("Can't open $file: $!");
413 ${*$fh{SCALAR}} = $file;
414 return $fh;
415}
416
417sub close_or_die {
418 my $fh = shift;
419 return if close $fh;
420 croak("Can't close: $!") unless ref $fh eq 'GLOB';
421 croak("Can't close ${*$fh{SCALAR}}: $!");
422}
423
6a8dbfd7
NC
424sub extract_from_file {
425 my ($file, $rx, $default) = @_;
69bf9aba 426 my $fh = open_or_die($file);
6a8dbfd7
NC
427 while (<$fh>) {
428 my @got = $_ =~ $rx;
429 return wantarray ? @got : $got[0]
430 if @got;
431 }
432 return $default if defined $default;
433 return;
434}
435
c59e8fd6
NC
436sub edit_file {
437 my ($file, $munger) = @_;
438 local $/;
69bf9aba 439 my $fh = open_or_die($file);
c59e8fd6
NC
440 my $orig = <$fh>;
441 die "Can't read $file: $!" unless defined $orig && close $fh;
442 my $new = $munger->($orig);
443 return if $new eq $orig;
69bf9aba 444 $fh = open_or_die($file, '>');
c59e8fd6 445 print $fh $new or die "Can't print to $file: $!";
69bf9aba 446 close_or_die($fh);
c59e8fd6
NC
447}
448
449sub apply_patch {
450 my $patch = shift;
451
452 my ($file) = $patch =~ qr!^diff.*a/(\S+) b/\1!;
453 open my $fh, '|-', 'patch', '-p1' or die "Can't run patch: $!";
454 print $fh $patch;
5fceabf3
NC
455 return if close $fh;
456 print STDERR "Patch is <<'EOPATCH'\n${patch}EOPATCH\n";
457 die "Can't patch $file: $?, $!";
c59e8fd6
NC
458}
459
4e540a4e
NC
460sub apply_commit {
461 my ($commit, @files) = @_;
462 return unless system "git show $commit @files | patch -p1";
463 die "Can't apply commit $commit to @files" if @files;
464 die "Can't apply commit $commit";
465}
466
467sub revert_commit {
468 my ($commit, @files) = @_;
469 return unless system "git show -R $commit @files | patch -p1";
470 die "Can't apply revert $commit from @files" if @files;
471 die "Can't apply revert $commit";
472}
473
91ad6f8a
NC
474sub checkout_file {
475 my ($file, $commit) = @_;
476 $commit ||= 'blead';
477 system "git show $commit:$file > $file </dev/null"
478 and die "Could not extract $file at revision $commit";
479}
480
ab4a15f9 481sub clean {
f4800c99 482 if ($options{clean}) {
ab4a15f9
NC
483 # Needed, because files that are build products in this checked out
484 # version might be in git in the next desired version.
9da8cb0a 485 system 'git clean -dxf </dev/null';
ab4a15f9
NC
486 # Needed, because at some revisions the build alters checked out files.
487 # (eg pod/perlapi.pod). Also undoes any changes to makedepend.SH
9da8cb0a 488 system 'git reset --hard HEAD </dev/null';
ab4a15f9
NC
489 }
490}
491
492sub skip {
493 my $reason = shift;
494 clean();
495 warn "skipping - $reason";
496 exit 125;
497}
498
f1050811
NC
499sub report_and_exit {
500 my ($ret, $pass, $fail, $desc) = @_;
501
502 clean();
503
f4800c99 504 my $got = ($options{'expect-pass'} ? !$ret : $ret) ? 'good' : 'bad';
f1050811
NC
505 if ($ret) {
506 print "$got - $fail $desc\n";
507 } else {
508 print "$got - $pass $desc\n";
509 }
510
511 exit($got eq 'bad');
512}
513
0afef97d
NC
514sub match_and_exit {
515 my $target = shift;
516 my $matches = 0;
517 my $re = qr/$match/;
518 my @files;
519
520 {
521 local $/ = "\0";
522 @files = defined $target ? `git ls-files -o -z`: `git ls-files -z`;
523 chomp @files;
524 }
525
526 foreach my $file (@files) {
69bf9aba 527 my $fh = open_or_die($file);
0afef97d
NC
528 while (<$fh>) {
529 if ($_ =~ $re) {
530 ++$matches;
531 if (tr/\t\r\n -~\200-\377//c) {
532 print "Binary file $file matches\n";
533 } else {
534 $_ .= "\n" unless /\n\z/;
535 print "$file: $_";
536 }
537 }
538 }
69bf9aba 539 close_or_die($fh);
0afef97d
NC
540 }
541 report_and_exit(!$matches,
542 $matches == 1 ? '1 match for' : "$matches matches for",
543 'no matches for', $match);
544}
545
6a8dbfd7 546# Not going to assume that system perl is yet new enough to have autodie
9da8cb0a 547system 'git clean -dxf </dev/null' and die;
6a8dbfd7 548
0afef97d
NC
549if (!defined $target) {
550 match_and_exit() if $match;
551 $target = 'test_prep';
bc96a05a
NC
552}
553
4b081584
NC
554skip('no Configure - is this the //depot/perlext/Compiler branch?')
555 unless -f 'Configure';
556
dbcdc176
NC
557# This changes to PERL_VERSION in 4d8076ea25903dcb in 1999
558my $major
559 = extract_from_file('patchlevel.h',
560 qr/^#define\s+(?:PERL_VERSION|PATCHLEVEL)\s+(\d+)\s/,
561 0);
562
0142f0ce
NC
563if ($major < 1) {
564 if (extract_from_file('Configure',
565 qr/^ \*=\*\) echo "\$1" >> \$optdef;;$/)) {
566 # This is " Spaces now allowed in -D command line options.",
567 # part of commit ecfc54246c2a6f42
568 apply_patch(<<'EOPATCH');
569diff --git a/Configure b/Configure
570index 3d3b38d..78ffe16 100755
571--- a/Configure
572+++ b/Configure
573@@ -652,7 +777,8 @@ while test $# -gt 0; do
574 echo "$me: use '-U symbol=', not '-D symbol='." >&2
575 echo "$me: ignoring -D $1" >&2
576 ;;
577- *=*) echo "$1" >> $optdef;;
578+ *=*) echo "$1" | \
579+ sed -e "s/'/'\"'\"'/g" -e "s/=\(.*\)/='\1'/" >> $optdef;;
580 *) echo "$1='define'" >> $optdef;;
581 esac
582 shift
583EOPATCH
584 }
585 if (extract_from_file('Configure', qr/^if \$contains 'd_namlen' \$xinc\b/)) {
586 # Configure's original simple "grep" for d_namlen falls foul of the
587 # approach taken by the glibc headers:
588 # #ifdef _DIRENT_HAVE_D_NAMLEN
589 # # define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
590 #
591 # where _DIRENT_HAVE_D_NAMLEN is not defined on Linux.
592 # This is also part of commit ecfc54246c2a6f42
593 apply_patch(<<'EOPATCH');
594diff --git a/Configure b/Configure
595index 3d3b38d..78ffe16 100755
596--- a/Configure
597+++ b/Configure
598@@ -3935,7 +4045,8 @@ $rm -f try.c
599
600 : see if the directory entry stores field length
601 echo " "
602-if $contains 'd_namlen' $xinc >/dev/null 2>&1; then
603+$cppstdin $cppflags $cppminus < "$xinc" > try.c
604+if $contains 'd_namlen' try.c >/dev/null 2>&1; then
605 echo "Good, your directory entry keeps length information in d_namlen." >&4
606 val="$define"
607 else
608EOPATCH
609 }
610}
d90ae42b 611
ac08709a
NC
612if ($major < 2
613 && !extract_from_file('Configure',
614 qr/Try to guess additional flags to pick up local libraries/)) {
615 my $mips = extract_from_file('Configure',
616 qr!(''\) if (?:\./)?mips; then)!);
617 # This is part of perl-5.001n. It's needed, to add -L/usr/local/lib to the
618 # ld flags if libraries are found there. It shifts the code to set up
619 # libpth earlier, and then adds the code to add libpth entries to ldflags
620 # mips was changed to ./mips in ecfc54246c2a6f42, perl5.000 patch.0g
621 apply_patch(sprintf <<'EOPATCH', $mips);
622diff --git a/Configure b/Configure
623index 53649d5..0635a6e 100755
624--- a/Configure
625+++ b/Configure
626@@ -2749,6 +2749,52 @@ EOM
627 ;;
628 esac
629
630+: Set private lib path
631+case "$plibpth" in
632+'') if ./mips; then
633+ plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
634+ fi;;
635+esac
636+case "$libpth" in
637+' ') dlist='';;
638+'') dlist="$plibpth $glibpth";;
639+*) dlist="$libpth";;
640+esac
641+
642+: Now check and see which directories actually exist, avoiding duplicates
643+libpth=''
644+for xxx in $dlist
645+do
646+ if $test -d $xxx; then
647+ case " $libpth " in
648+ *" $xxx "*) ;;
649+ *) libpth="$libpth $xxx";;
650+ esac
651+ fi
652+done
653+$cat <<'EOM'
654+
655+Some systems have incompatible or broken versions of libraries. Among
656+the directories listed in the question below, please remove any you
657+know not to be holding relevant libraries, and add any that are needed.
658+Say "none" for none.
659+
660+EOM
661+case "$libpth" in
662+'') dflt='none';;
663+*)
664+ set X $libpth
665+ shift
666+ dflt=${1+"$@"}
667+ ;;
668+esac
669+rp="Directories to use for library searches?"
670+. ./myread
671+case "$ans" in
672+none) libpth=' ';;
673+*) libpth="$ans";;
674+esac
675+
676 : flags used in final linking phase
677 case "$ldflags" in
678 '') if ./venix; then
679@@ -2765,6 +2811,23 @@ case "$ldflags" in
680 ;;
681 *) dflt="$ldflags";;
682 esac
683+
684+: Possible local library directories to search.
685+loclibpth="/usr/local/lib /opt/local/lib /usr/gnu/lib"
686+loclibpth="$loclibpth /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib"
687+
688+: Try to guess additional flags to pick up local libraries.
689+for thislibdir in $libpth; do
690+ case " $loclibpth " in
691+ *" $thislibdir "*)
692+ case "$dflt " in
693+ "-L$thislibdir ") ;;
694+ *) dflt="$dflt -L$thislibdir" ;;
695+ esac
696+ ;;
697+ esac
698+done
699+
700 echo " "
701 rp="Any additional ld flags (NOT including libraries)?"
702 . ./myread
703@@ -2828,52 +2891,6 @@ n) echo "OK, that should do.";;
704 esac
705 $rm -f try try.* core
706
707-: Set private lib path
708-case "$plibpth" in
709-%s
710- plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib"
711- fi;;
712-esac
713-case "$libpth" in
714-' ') dlist='';;
715-'') dlist="$plibpth $glibpth";;
716-*) dlist="$libpth";;
717-esac
718-
719-: Now check and see which directories actually exist, avoiding duplicates
720-libpth=''
721-for xxx in $dlist
722-do
723- if $test -d $xxx; then
724- case " $libpth " in
725- *" $xxx "*) ;;
726- *) libpth="$libpth $xxx";;
727- esac
728- fi
729-done
730-$cat <<'EOM'
731-
732-Some systems have incompatible or broken versions of libraries. Among
733-the directories listed in the question below, please remove any you
734-know not to be holding relevant libraries, and add any that are needed.
735-Say "none" for none.
736-
737-EOM
738-case "$libpth" in
739-'') dflt='none';;
740-*)
741- set X $libpth
742- shift
743- dflt=${1+"$@"}
744- ;;
745-esac
746-rp="Directories to use for library searches?"
747-. ./myread
748-case "$ans" in
749-none) libpth=' ';;
750-*) libpth="$ans";;
751-esac
752-
753 : compute shared library extension
754 case "$so" in
755 '')
756EOPATCH
757}
758
bc70704d
NC
759if ($major < 5 && extract_from_file('Configure',
760 qr!if \$cc \$ccflags try\.c -o try >/dev/null 2>&1; then!)) {
761 # Analogous to the more general fix of dfe9444ca7881e71
762 # Without this flags such as -m64 may not be passed to this compile, which
763 # results in a byteorder of '1234' instead of '12345678', which can then
764 # cause crashes.
765
766 if (extract_from_file('Configure', qr/xxx_prompt=y/)) {
767 # 8e07c86ebc651fe9 or later
768 # ("This is my patch patch.1n for perl5.001.")
769 apply_patch(<<'EOPATCH');
770diff --git a/Configure b/Configure
771index 62249dd..c5c384e 100755
772--- a/Configure
773+++ b/Configure
774@@ -8247,7 +8247,7 @@ main()
775 }
776 EOCP
777 xxx_prompt=y
778- if $cc $ccflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
779+ if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then
780 dflt=`./try`
781 case "$dflt" in
782 [1-4][1-4][1-4][1-4]|12345678|87654321)
783EOPATCH
784 } else {
785 apply_patch(<<'EOPATCH');
786diff --git a/Configure b/Configure
787index 53649d5..f1cd64a 100755
788--- a/Configure
789+++ b/Configure
790@@ -6362,7 +6362,7 @@ main()
791 printf("\n");
792 }
793 EOCP
794- if $cc $ccflags try.c -o try >/dev/null 2>&1 ; then
795+ if $cc $ccflags $ldflags try.c -o try >/dev/null 2>&1 ; then
796 dflt=`./try`
797 case "$dflt" in
798 ????|????????) echo "(The test program ran ok.)";;
799EOPATCH
800 }
801}
802
af7c500f
NC
803if ($major < 8 && !extract_from_file('Configure',
804 qr/^\t\tif test ! -t 0; then$/)) {
7c22f158
NC
805 # Before dfe9444ca7881e71, Configure would refuse to run if stdin was not a
806 # tty. With that commit, the tty requirement was dropped for -de and -dE
af7c500f 807 # Commit aaeb8e512e8e9e14 dropped the tty requirement for -S
7c22f158
NC
808 # For those older versions, it's probably easiest if we simply remove the
809 # sanity test.
af7c500f
NC
810 edit_file('Configure', sub {
811 my $code = shift;
812 $code =~ s/test ! -t 0/test Perl = rules/;
813 return $code;
814 });
7c22f158
NC
815}
816
678e580e
NC
817if ($major == 8 || $major == 9) {
818 # Fix symbol detection to that of commit 373dfab3839ca168 if it's any
819 # intermediate version 5129fff43c4fe08c or later, as the intermediate
820 # versions don't work correctly on (at least) Sparc Linux.
821 # 5129fff43c4fe08c adds the first mention of mistrustnm.
822 # 373dfab3839ca168 removes the last mention of lc=""
823 edit_file('Configure', sub {
824 my $code = shift;
825 return $code
826 if $code !~ /\btc="";/; # 373dfab3839ca168 or later
827 return $code
828 if $code !~ /\bmistrustnm\b/; # before 5129fff43c4fe08c
829 my $fixed = <<'EOC';
830
831: is a C symbol defined?
832csym='tlook=$1;
833case "$3" in
834-v) tf=libc.tmp; tdc="";;
835-a) tf=libc.tmp; tdc="[]";;
836*) tlook="^$1\$"; tf=libc.list; tdc="()";;
837esac;
838tx=yes;
839case "$reuseval-$4" in
840true-) ;;
841true-*) tx=no; eval "tval=\$$4"; case "$tval" in "") tx=yes;; esac;;
842esac;
843case "$tx" in
844yes)
845 tval=false;
846 if $test "$runnm" = true; then
847 if $contains $tlook $tf >/dev/null 2>&1; then
848 tval=true;
849 elif $test "$mistrustnm" = compile -o "$mistrustnm" = run; then
850 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
851 $cc -o try $optimize $ccflags $ldflags try.c >/dev/null 2>&1 $libs && tval=true;
852 $test "$mistrustnm" = run -a -x try && { $run ./try$_exe >/dev/null 2>&1 || tval=false; };
853 $rm -f try$_exe try.c core core.* try.core;
854 fi;
855 else
856 echo "void *(*(p()))$tdc { extern void *$1$tdc; return &$1; } int main() { if(p()) return(0); else return(1); }"> try.c;
857 $cc -o try $optimize $ccflags $ldflags try.c $libs >/dev/null 2>&1 && tval=true;
858 $rm -f try$_exe try.c;
859 fi;
860 ;;
861*)
862 case "$tval" in
863 $define) tval=true;;
864 *) tval=false;;
865 esac;
866 ;;
867esac;
868eval "$2=$tval"'
869
870EOC
871 $code =~ s/\n: is a C symbol defined\?\n.*?\neval "\$2=\$tval"'\n\n/$fixed/sm
872 or die "substitution failed";
873 return $code;
874 });
875}
876
d90ae42b 877if ($major < 10 && extract_from_file('Configure', qr/^set malloc\.h i_malloc$/)) {
5541f5e3
NC
878 # This is commit 01d07975f7ef0e7d, trimmed, with $compile inlined as
879 # prior to bd9b35c97ad661cc Configure had the malloc.h test before the
880 # definition of $compile.
d90ae42b
NC
881 apply_patch(<<'EOPATCH');
882diff --git a/Configure b/Configure
883index 3d2e8b9..6ce7766 100755
884--- a/Configure
885+++ b/Configure
886@@ -6743,5 +6743,22 @@ set d_dosuid
887
888 : see if this is a malloc.h system
889-set malloc.h i_malloc
890-eval $inhdr
891+: we want a real compile instead of Inhdr because some systems have a
892+: malloc.h that just gives a compile error saying to use stdlib.h instead
893+echo " "
894+$cat >try.c <<EOCP
895+#include <stdlib.h>
896+#include <malloc.h>
897+int main () { return 0; }
898+EOCP
899+set try
5541f5e3 900+if $cc $optimize $ccflags $ldflags -o try $* try.c $libs > /dev/null 2>&1; then
d90ae42b
NC
901+ echo "<malloc.h> found." >&4
902+ val="$define"
903+else
904+ echo "<malloc.h> NOT found." >&4
905+ val="$undef"
906+fi
907+$rm -f try.c try
908+set i_malloc
909+eval $setvar
910
911EOPATCH
912}
a1756669 913
686af304
NC
914# Cwd.xs added in commit 0d2079faa739aaa9. Cwd.pm moved to ext/ 8 years later
915# in commit 403f501d5b37ebf0
916if ($major > 0 && <*/Cwd/Cwd.xs>) {
917 if ($major < 10 && !extract_from_file('Makefile.SH', qr/^extra_dep=''$/)) {
918 # The Makefile.PL for Unicode::Normalize needs
919 # lib/unicore/CombiningClass.pl. Even without a parallel build, we need
920 # a dependency to ensure that it builds. This is a variant of commit
921 # 9f3ef600c170f61e. Putting this for earlier versions gives us a spot
922 # on which to hang the edits below
923 apply_patch(<<'EOPATCH');
6ff3edb1
NC
924diff --git a/Makefile.SH b/Makefile.SH
925index f61d0db..6097954 100644
926--- a/Makefile.SH
927+++ b/Makefile.SH
928@@ -155,10 +155,20 @@ esac
929
930 : Prepare dependency lists for Makefile.
931 dynamic_list=' '
932+extra_dep=''
933 for f in $dynamic_ext; do
934 : the dependency named here will never exist
935 base=`echo "$f" | sed 's/.*\///'`
936- dynamic_list="$dynamic_list lib/auto/$f/$base.$dlext"
937+ this_target="lib/auto/$f/$base.$dlext"
938+ dynamic_list="$dynamic_list $this_target"
939+
940+ : Parallel makes reveal that we have some interdependencies
941+ case $f in
942+ Math/BigInt/FastCalc) extra_dep="$extra_dep
943+$this_target: lib/auto/List/Util/Util.$dlext" ;;
944+ Unicode/Normalize) extra_dep="$extra_dep
945+$this_target: lib/unicore/CombiningClass.pl" ;;
946+ esac
947 done
948
949 static_list=' '
950@@ -987,2 +997,9 @@ n_dummy $(nonxs_ext): miniperl$(EXE_EXT) preplibrary $(DYNALOADER) FORCE
951 @$(LDLIBPTH) sh ext/util/make_ext nonxs $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL)
952+!NO!SUBS!
953+
954+$spitshell >>Makefile <<EOF
955+$extra_dep
956+EOF
957+
958+$spitshell >>Makefile <<'!NO!SUBS!'
959
960EOPATCH
686af304
NC
961 }
962 if ($major < 14) {
963 # Commits dc0655f797469c47 and d11a62fe01f2ecb2
964 edit_file('Makefile.SH', sub {
965 my $code = shift;
966 foreach my $ext (qw(Encode SDBM_File)) {
967 next if $code =~ /\b$ext\) extra_dep=/s;
968 $code =~ s!(\) extra_dep="\$extra_dep
969\$this_target: .*?" ;;)
970( esac
971)!$1
972 $ext) extra_dep="\$extra_dep
973\$this_target: lib/auto/Cwd/Cwd.\$dlext" ;;
974$2!;
975 }
976 return $code;
977 });
978 }
979}
980if ($major == 7) {
981 # Remove commits 9fec149bb652b6e9 and 5bab1179608f81d8, which add/amend
982 # rules to automatically run regen scripts that rebuild C headers. These
983 # cause problems because a git checkout doesn't preserve relative file
984 # modification times, hence the regen scripts may fire. This will obscure
985 # whether the repository had the correct generated headers checked in.
986 # Also, the dependency rules for running the scripts were not correct,
987 # which could cause spurious re-builds on re-running make, and can cause
988 # complete build failures for a parallel make.
989 if (extract_from_file('Makefile.SH',
990 qr/Writing it this way gives make a big hint to always run opcode\.pl before/)) {
4e540a4e 991 apply_commit('70c6e6715e8fec53');
686af304
NC
992 } elsif (extract_from_file('Makefile.SH',
993 qr/^opcode\.h opnames\.h pp_proto\.h pp\.sym: opcode\.pl$/)) {
4e540a4e 994 revert_commit('9fec149bb652b6e9');
686af304 995 }
6ff3edb1
NC
996}
997
6a8dbfd7
NC
998# There was a bug in makedepend.SH which was fixed in version 96a8704c.
999# Symptom was './makedepend: 1: Syntax error: Unterminated quoted string'
1000# Remove this if you're actually bisecting a problem related to makedepend.SH
91ad6f8a 1001checkout_file('makedepend.SH');
6a8dbfd7 1002
d64af352
NC
1003if ($^O eq 'freebsd') {
1004 # There are rather too many version-specific FreeBSD hints fixes to patch
1005 # individually. Also, more than once the FreeBSD hints file has been
1006 # written in what turned out to be a rather non-future-proof style,
1007 # with case statements treating the most recent version as the exception,
1008 # instead of treating previous versions' behaviour explicitly and changing
1009 # the default to cater for the current behaviour. (As strangely, future
1010 # versions inherit the current behaviour.)
91ad6f8a 1011 checkout_file('hints/freebsd.sh');
915f531b
NC
1012} elsif ($^O eq 'darwin') {
1013 if ($major < 8) {
1014 my $faking_it;
1015 # We can't build on darwin without some of the data in the hints file.
1016 foreach ('ext/DynaLoader/dl_dyld.xs', 'hints/darwin.sh') {
1017 next if -f $_;
1018 ++$faking_it;
1019 # Probably less surprising to use the earliest version of
1020 # hints/darwin.sh and then edit in place just below, than use
1021 # blead's version, as that would create a discontinuity at
1022 # f556e5b971932902 - before it, hints bugs would be "fixed", after
1023 # it they'd resurface. This way, we should give the illusion of
1024 # monotonic bug fixing.
91ad6f8a 1025 checkout_file($_, 'f556e5b971932902');
915f531b
NC
1026 }
1027 if ($faking_it) {
1028 apply_patch(<<'EOPATCH');
1029diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
1030--- a/ext/DynaLoader/dl_dyld.xs~ 2011-10-11 21:41:27.000000000 +0100
1031+++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 21:42:20.000000000 +0100
1032@@ -41,6 +41,35 @@
1033 #include "perl.h"
1034 #include "XSUB.h"
1035
1036+#ifndef pTHX
1037+# define pTHX void
1038+# define pTHX_
1039+#endif
1040+#ifndef aTHX
1041+# define aTHX
1042+# define aTHX_
1043+#endif
1044+#ifndef dTHX
1045+# define dTHXa(a) extern int Perl___notused(void)
1046+# define dTHX extern int Perl___notused(void)
1047+#endif
1048+
1049+#ifndef Perl_form_nocontext
1050+# define Perl_form_nocontext form
1051+#endif
1052+
1053+#ifndef Perl_warn_nocontext
1054+# define Perl_warn_nocontext warn
1055+#endif
1056+
1057+#ifndef PTR2IV
1058+# define PTR2IV(p) (IV)(p)
1059+#endif
1060+
1061+#ifndef get_av
1062+# define get_av perl_get_av
1063+#endif
1064+
1065 #define DL_LOADONCEONLY
1066
1067 #include "dlutils.c" /* SaveError() etc */
1068@@ -185,7 +191,7 @@
1069 CODE:
1070 DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):\n", filename,flags));
1071 if (flags & 0x01)
1072- Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
1073+ Perl_warn_nocontext("Can't make loaded symbols global on this platform while loading %s",filename);
1074 RETVAL = dlopen(filename, mode) ;
1075 DLDEBUG(2,PerlIO_printf(Perl_debug_log, " libref=%x\n", RETVAL));
1076 ST(0) = sv_newmortal() ;
1077EOPATCH
1078 if ($major < 4 && !extract_from_file('util.c', qr/^form/m)) {
1079 apply_patch(<<'EOPATCH');
1080diff -u a/ext/DynaLoader/dl_dyld.xs~ a/ext/DynaLoader/dl_dyld.xs
1081--- a/ext/DynaLoader/dl_dyld.xs~ 2011-10-11 21:56:25.000000000 +0100
1082+++ b/ext/DynaLoader/dl_dyld.xs 2011-10-11 22:00:00.000000000 +0100
1083@@ -60,6 +60,18 @@
1084 # define get_av perl_get_av
1085 #endif
1086
1087+static char *
1088+form(char *pat, ...)
1089+{
1090+ char *retval;
1091+ va_list args;
1092+ va_start(args, pat);
1093+ vasprintf(&retval, pat, &args);
1094+ va_end(args);
1095+ SAVEFREEPV(retval);
1096+ return retval;
1097+}
1098+
1099 #define DL_LOADONCEONLY
1100
1101 #include "dlutils.c" /* SaveError() etc */
1102EOPATCH
1103 }
1104 }
1105
1106 edit_file('hints/darwin.sh', sub {
1107 my $code = shift;
1108 # Part of commit 8f4f83badb7d1ba9, which mostly undoes
1109 # commit 0511a818910f476c.
1110 $code =~ s/^cppflags='-traditional-cpp';$/cppflags="\${cppflags} -no-cpp-precomp"/m;
1111 # commit 14c11978e9b52e08/803bb6cc74d36a3f
1112 # Without this, code in libperl.bundle links against op.o
1113 # in preference to opmini.o on the linker command line,
1114 # and hence miniperl tries to use File::Glob instead of
1115 # csh
1116 $code =~ s/^(lddlflags=)/ldflags="\${ldflags} -flat_namespace"\n$1/m;
1117 # f556e5b971932902 also patches Makefile.SH with some
1118 # special case code to deal with useshrplib for darwin.
1119 # Given that post 5.8.0 the darwin hints default was
1120 # changed to false, and it would be very complex to splice
1121 # in that code in various versions of Makefile.SH back
1122 # to 5.002, lets just turn it off.
1123 $code =~ s/^useshrplib='true'/useshrplib='false'/m
1124 if $faking_it;
1125 return $code;
1126 });
1127 }
283e4721
NC
1128} elsif ($^O eq 'netbsd') {
1129 if ($major < 6) {
1130 # These are part of commit 099685bc64c7dbce
1131 edit_file('hints/netbsd.sh', sub {
1132 my $code = shift;
1133 my $fixed = <<'EOC';
1134case "$osvers" in
11350.9|0.8*)
1136 usedl="$undef"
1137 ;;
1138*)
1139 if [ -f /usr/libexec/ld.elf_so ]; then
1140 d_dlopen=$define
1141 d_dlerror=$define
1142 ccdlflags="-Wl,-E -Wl,-R${PREFIX}/lib $ccdlflags"
1143 cccdlflags="-DPIC -fPIC $cccdlflags"
1144 lddlflags="--whole-archive -shared $lddlflags"
1145 elif [ "`uname -m`" = "pmax" ]; then
1146# NetBSD 1.3 and 1.3.1 on pmax shipped an `old' ld.so, which will not work.
1147 d_dlopen=$undef
1148 elif [ -f /usr/libexec/ld.so ]; then
1149 d_dlopen=$define
1150 d_dlerror=$define
1151 ccdlflags="-Wl,-R${PREFIX}/lib $ccdlflags"
1152# we use -fPIC here because -fpic is *NOT* enough for some of the
1153# extensions like Tk on some netbsd platforms (the sparc is one)
1154 cccdlflags="-DPIC -fPIC $cccdlflags"
1155 lddlflags="-Bforcearchive -Bshareable $lddlflags"
1156 else
1157 d_dlopen=$undef
1158 fi
1159 ;;
1160esac
1161EOC
1162 $code =~ s/^case "\$osvers" in\n0\.9\|0\.8.*?^esac\n/$fixed/ms;
1163 return $code;
1164 });
1165 if (!extract_from_file('unixish.h',
1166 qr/defined\(NSIG\).*defined\(__NetBSD__\)/)) {
1167 apply_patch(<<'EOPATCH')
1168diff --git a/unixish.h b/unixish.h
1169index 2a6cbcd..eab2de1 100644
1170--- a/unixish.h
1171+++ b/unixish.h
1172@@ -89,7 +89,7 @@
1173 */
1174 /* #define ALTERNATE_SHEBANG "#!" / **/
1175
1176-#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
1177+#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) || defined(__NetBSD__)
1178 # include <signal.h>
1179 #endif
1180
1181EOPATCH
1182 }
1183 }
6f8c21fa 1184} elsif ($^O eq 'openbsd') {
91ad6f8a
NC
1185 checkout_file('hints/openbsd.sh', '43051805d53a3e4c')
1186 unless -f 'hints/openbsd.sh';
6f8c21fa
NC
1187
1188 if ($major < 8) {
1189 my $which = extract_from_file('hints/openbsd.sh',
1190 qr/# from (2\.8|3\.1) onwards/,
1191 '');
1192 if ($which eq '') {
1193 my $was = extract_from_file('hints/openbsd.sh',
1194 qr/(lddlflags="(?:-Bforcearchive )?-Bshareable)/);
1195 # This is commit 154d43cbcf57271c and parts of 5c75dbfa77b0949c
1196 # and 29b5585702e5e025
1197 apply_patch(sprintf <<'EOPATCH', $was);
1198diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1199index a7d8bf2..5b79709 100644
1200--- a/hints/openbsd.sh
1201+++ b/hints/openbsd.sh
1202@@ -37,7 +37,25 @@ OpenBSD.alpha|OpenBSD.mips|OpenBSD.powerpc|OpenBSD.vax)
1203 # we use -fPIC here because -fpic is *NOT* enough for some of the
1204 # extensions like Tk on some OpenBSD platforms (ie: sparc)
1205 cccdlflags="-DPIC -fPIC $cccdlflags"
1206- %s $lddlflags"
1207+ case "$osvers" in
1208+ [01].*|2.[0-7]|2.[0-7].*)
1209+ lddlflags="-Bshareable $lddlflags"
1210+ ;;
1211+ 2.[8-9]|3.0)
1212+ ld=${cc:-cc}
1213+ lddlflags="-shared -fPIC $lddlflags"
1214+ ;;
1215+ *) # from 3.1 onwards
1216+ ld=${cc:-cc}
1217+ lddlflags="-shared -fPIC $lddlflags"
1218+ libswanted=`echo $libswanted | sed 's/ dl / /'`
1219+ ;;
1220+ esac
1221+
1222+ # We need to force ld to export symbols on ELF platforms.
1223+ # Without this, dlopen() is crippled.
1224+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1225+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1226 ;;
1227 esac
1228
1229EOPATCH
1230 } elsif ($which eq '2.8') {
1231 # This is parts of 5c75dbfa77b0949c and 29b5585702e5e025, and
1232 # possibly eb9cd59d45ad2908
1233 my $was = extract_from_file('hints/openbsd.sh',
1234 qr/lddlflags="(-shared(?: -fPIC)?) \$lddlflags"/);
1235
1236 apply_patch(sprintf <<'EOPATCH', $was);
1237--- a/hints/openbsd.sh 2011-10-21 17:25:20.000000000 +0200
1238+++ b/hints/openbsd.sh 2011-10-21 16:58:43.000000000 +0200
1239@@ -44,11 +44,21 @@
1240 [01].*|2.[0-7]|2.[0-7].*)
1241 lddlflags="-Bshareable $lddlflags"
1242 ;;
1243- *) # from 2.8 onwards
1244+ 2.[8-9]|3.0)
1245 ld=${cc:-cc}
1246- lddlflags="%s $lddlflags"
1247+ lddlflags="-shared -fPIC $lddlflags"
1248+ ;;
1249+ *) # from 3.1 onwards
1250+ ld=${cc:-cc}
1251+ lddlflags="-shared -fPIC $lddlflags"
1252+ libswanted=`echo $libswanted | sed 's/ dl / /'`
1253 ;;
1254 esac
1255+
1256+ # We need to force ld to export symbols on ELF platforms.
1257+ # Without this, dlopen() is crippled.
1258+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1259+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1260 ;;
1261 esac
1262
1263EOPATCH
1264 } elsif ($which eq '3.1'
1265 && !extract_from_file('hints/openbsd.sh',
1266 qr/We need to force ld to export symbols on ELF platforms/)) {
1267 # This is part of 29b5585702e5e025
1268 apply_patch(<<'EOPATCH');
1269diff --git a/hints/openbsd.sh b/hints/openbsd.sh
1270index c6b6bc9..4839d04 100644
1271--- a/hints/openbsd.sh
1272+++ b/hints/openbsd.sh
1273@@ -54,6 +54,11 @@ alpha-2.[0-8]|mips-*|vax-*|powerpc-2.[0-7]|m88k-*)
1274 libswanted=`echo $libswanted | sed 's/ dl / /'`
1275 ;;
1276 esac
1277+
1278+ # We need to force ld to export symbols on ELF platforms.
1279+ # Without this, dlopen() is crippled.
1280+ ELF=`${cc:-cc} -dM -E - </dev/null | grep __ELF__`
1281+ test -n "$ELF" && ldflags="-Wl,-E $ldflags"
1282 ;;
1283 esac
1284
1285EOPATCH
1286 }
1287 }
1288 if ($major < 4) {
1289 my $bad;
1290 # Need changes from commit a6e633defa583ad5.
1291 # Commits c07a80fdfe3926b5 and f82b3d4130164d5f changed the same part
1292 # of perl.h
1293
1294 if (extract_from_file('perl.h',
1295 qr/^#ifdef HAS_GETPGRP2$/)) {
1296 $bad = <<'EOBAD';
1297***************
1298*** 57,71 ****
1299 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
1300 #define TAINT_ENV() if (tainting) taint_env()
1301
1302! #ifdef HAS_GETPGRP2
1303! # ifndef HAS_GETPGRP
1304! # define HAS_GETPGRP
1305! # endif
1306! #endif
1307!
1308! #ifdef HAS_SETPGRP2
1309! # ifndef HAS_SETPGRP
1310! # define HAS_SETPGRP
1311! # endif
1312 #endif
1313
1314EOBAD
1315 } elsif (extract_from_file('perl.h',
1316 qr/Gack, you have one but not both of getpgrp2/)) {
1317 $bad = <<'EOBAD';
1318***************
1319*** 56,76 ****
1320 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
1321 #define TAINT_ENV() if (tainting) taint_env()
1322
1323! #if defined(HAS_GETPGRP2) && defined(HAS_SETPGRP2)
1324! # define getpgrp getpgrp2
1325! # define setpgrp setpgrp2
1326! # ifndef HAS_GETPGRP
1327! # define HAS_GETPGRP
1328! # endif
1329! # ifndef HAS_SETPGRP
1330! # define HAS_SETPGRP
1331! # endif
1332! # ifndef USE_BSDPGRP
1333! # define USE_BSDPGRP
1334! # endif
1335! #else
1336! # if defined(HAS_GETPGRP2) || defined(HAS_SETPGRP2)
1337! #include "Gack, you have one but not both of getpgrp2() and setpgrp2()."
1338! # endif
1339 #endif
1340
1341EOBAD
1342 } elsif (extract_from_file('perl.h',
1343 qr/^#ifdef USE_BSDPGRP$/)) {
1344 $bad = <<'EOBAD'
1345***************
1346*** 91,116 ****
1347 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
1348 #define TAINT_ENV() if (tainting) taint_env()
1349
1350! #ifdef USE_BSDPGRP
1351! # ifdef HAS_GETPGRP
1352! # define BSD_GETPGRP(pid) getpgrp((pid))
1353! # endif
1354! # ifdef HAS_SETPGRP
1355! # define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
1356! # endif
1357! #else
1358! # ifdef HAS_GETPGRP2
1359! # define BSD_GETPGRP(pid) getpgrp2((pid))
1360! # ifndef HAS_GETPGRP
1361! # define HAS_GETPGRP
1362! # endif
1363! # endif
1364! # ifdef HAS_SETPGRP2
1365! # define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
1366! # ifndef HAS_SETPGRP
1367! # define HAS_SETPGRP
1368! # endif
1369! # endif
1370 #endif
1371
1372 #ifndef _TYPES_ /* If types.h defines this it's easy. */
1373EOBAD
1374 }
1375 if ($bad) {
1376 apply_patch(<<"EOPATCH");
1377*** a/perl.h 2011-10-21 09:46:12.000000000 +0200
1378--- b/perl.h 2011-10-21 09:46:12.000000000 +0200
1379$bad--- 91,144 ----
1380 #define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s)
1381 #define TAINT_ENV() if (tainting) taint_env()
1382
1383! /* XXX All process group stuff is handled in pp_sys.c. Should these
1384! defines move there? If so, I could simplify this a lot. --AD 9/96.
1385! */
1386! /* Process group stuff changed from traditional BSD to POSIX.
1387! perlfunc.pod documents the traditional BSD-style syntax, so we'll
1388! try to preserve that, if possible.
1389! */
1390! #ifdef HAS_SETPGID
1391! # define BSD_SETPGRP(pid, pgrp) setpgid((pid), (pgrp))
1392! #else
1393! # if defined(HAS_SETPGRP) && defined(USE_BSD_SETPGRP)
1394! # define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp))
1395! # else
1396! # ifdef HAS_SETPGRP2 /* DG/UX */
1397! # define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp))
1398! # endif
1399! # endif
1400! #endif
1401! #if defined(BSD_SETPGRP) && !defined(HAS_SETPGRP)
1402! # define HAS_SETPGRP /* Well, effectively it does . . . */
1403! #endif
1404!
1405! /* getpgid isn't POSIX, but at least Solaris and Linux have it, and it makes
1406! our life easier :-) so we'll try it.
1407! */
1408! #ifdef HAS_GETPGID
1409! # define BSD_GETPGRP(pid) getpgid((pid))
1410! #else
1411! # if defined(HAS_GETPGRP) && defined(USE_BSD_GETPGRP)
1412! # define BSD_GETPGRP(pid) getpgrp((pid))
1413! # else
1414! # ifdef HAS_GETPGRP2 /* DG/UX */
1415! # define BSD_GETPGRP(pid) getpgrp2((pid))
1416! # endif
1417! # endif
1418! #endif
1419! #if defined(BSD_GETPGRP) && !defined(HAS_GETPGRP)
1420! # define HAS_GETPGRP /* Well, effectively it does . . . */
1421! #endif
1422!
1423! /* These are not exact synonyms, since setpgrp() and getpgrp() may
1424! have different behaviors, but perl.h used to define USE_BSDPGRP
1425! (prior to 5.003_05) so some extension might depend on it.
1426! */
1427! #if defined(USE_BSD_SETPGRP) || defined(USE_BSD_GETPGRP)
1428! # ifndef USE_BSDPGRP
1429! # define USE_BSDPGRP
1430! # endif
1431 #endif
1432
1433 #ifndef _TYPES_ /* If types.h defines this it's easy. */
1434EOPATCH
1435 }
1436 }
1437 if ($major < 3 && !extract_from_file('pp_sys.c', qr/BSD_GETPGRP/)) {
1438 # Part of commit c3293030fd1b7489
1439 apply_patch(<<'EOPATCH');
1440diff --git a/pp_sys.c b/pp_sys.c
1441index 4608a2a..f0c9d1d 100644
1442--- a/pp_sys.c
1443+++ b/pp_sys.c
1444@@ -2903,8 +2903,8 @@ PP(pp_getpgrp)
1445 pid = 0;
1446 else
1447 pid = SvIVx(POPs);
1448-#ifdef USE_BSDPGRP
1449- value = (I32)getpgrp(pid);
1450+#ifdef BSD_GETPGRP
1451+ value = (I32)BSD_GETPGRP(pid);
1452 #else
1453 if (pid != 0)
1454 DIE("POSIX getpgrp can't take an argument");
1455@@ -2933,8 +2933,8 @@ PP(pp_setpgrp)
1456 }
1457
1458 TAINT_PROPER("setpgrp");
1459-#ifdef USE_BSDPGRP
1460- SETi( setpgrp(pid, pgrp) >= 0 );
1461+#ifdef BSD_SETPGRP
1462+ SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
1463 #else
1464 if ((pgrp != 0) || (pid != 0)) {
1465 DIE("POSIX setpgrp can't take an argument");
1466EOPATCH
1467 }
bc70704d
NC
1468} elsif ($^O eq 'linux') {
1469 if ($major < 1) {
1470 # sparc linux seems to need the -Dbool=char -DHAS_BOOL part of
1471 # perl5.000 patch.0n: [address Configure and build issues]
1472 edit_file('hints/linux.sh', sub {
1473 my $code = shift;
1474 $code =~ s!-I/usr/include/bsd!-Dbool=char -DHAS_BOOL!g;
1475 return $code;
1476 });
1477 }
1478
1479 if ($major <= 9) {
1480 if (`uname -sm` =~ qr/^Linux sparc/) {
1481 if (extract_from_file('hints/linux.sh', qr/sparc-linux/)) {
1482 # Be sure to use -fPIC not -fpic on Linux/SPARC
4e540a4e 1483 apply_commit('f6527d0ef0c13ad4');
bc70704d 1484 } elsif(!extract_from_file('hints/linux.sh', qr/^sparc-linux\)$/)) {
69bf9aba 1485 my $fh = open_or_die('hints/linux.sh', '>>');
bc70704d
NC
1486 print $fh <<'EOT' or die $!;
1487
1488case "`uname -m`" in
1489sparc*)
1490 case "$cccdlflags" in
1491 *-fpic*) cccdlflags="`echo $cccdlflags|sed 's/-fpic/-fPIC/'`" ;;
1492 *) cccdlflags="$cccdlflags -fPIC" ;;
1493 esac
1494 ;;
1495esac
1496EOT
69bf9aba 1497 close_or_die($fh);
bc70704d
NC
1498 }
1499 }
1500 }
d64af352
NC
1501}
1502
cfadff5f
NC
1503if ($major < 10) {
1504 if (!extract_from_file('ext/DB_File/DB_File.xs',
1505 qr!^#else /\* Berkeley DB Version > 2 \*/$!)) {
1506 # This DB_File.xs is really too old to patch up.
1507 # Skip DB_File, unless we're invoked with an explicit -Unoextensions
1508 if (!exists $defines{noextensions}) {
1509 $defines{noextensions} = 'DB_File';
1510 } elsif (defined $defines{noextensions}) {
1511 $defines{noextensions} .= ' DB_File';
1512 }
1513 } elsif (!extract_from_file('ext/DB_File/DB_File.xs',
1514 qr/^#ifdef AT_LEAST_DB_4_1$/)) {
1515 # This line is changed by commit 3245f0580c13b3ab
1516 my $line = extract_from_file('ext/DB_File/DB_File.xs',
1517 qr/^( status = \(?RETVAL->dbp->open\)?\(RETVAL->dbp, name, NULL, RETVAL->type, $)/);
1518 apply_patch(<<"EOPATCH");
1519diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs
1520index 489ba96..fba8ded 100644
1521--- a/ext/DB_File/DB_File.xs
1522+++ b/ext/DB_File/DB_File.xs
1523\@\@ -183,4 +187,8 \@\@
1524 #endif
1525
1526+#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
1527+# define AT_LEAST_DB_4_1
1528+#endif
1529+
1530 /* map version 2 features & constants onto their version 1 equivalent */
1531
1532\@\@ -1334,7 +1419,12 \@\@ SV * sv ;
1533 #endif
1534
1535+#ifdef AT_LEAST_DB_4_1
1536+ status = (RETVAL->dbp->open)(RETVAL->dbp, NULL, name, NULL, RETVAL->type,
1537+ Flags, mode) ;
1538+#else
1539 $line
1540 Flags, mode) ;
1541+#endif
1542 /* printf("open returned %d %s\\n", status, db_strerror(status)) ; */
1543
1544EOPATCH
1545 }
1546}
1547
6a8dbfd7
NC
1548# if Encode is not needed for the test, you can speed up the bisect by
1549# excluding it from the runs with -Dnoextensions=Encode
1550# ccache is an easy win. Remove it if it causes problems.
6a8dbfd7
NC
1551# Commit 1cfa4ec74d4933da adds ignore_versioned_solibs to Configure, and sets it
1552# to true in hints/linux.sh
1553# On dromedary, from that point on, Configure (by default) fails to find any
1554# libraries, because it scans /usr/local/lib /lib /usr/lib, which only contain
1555# versioned libraries. Without -lm, the build fails.
1556# Telling /usr/local/lib64 /lib64 /usr/lib64 works from that commit onwards,
1557# until commit faae14e6e968e1c0 adds it to the hints.
1558# However, prior to 1cfa4ec74d4933da telling Configure the truth doesn't work,
1559# because it will spot versioned libraries, pass them to the compiler, and then
1560# bail out pretty early on. Configure won't let us override libswanted, but it
1561# will let us override the entire libs list.
1562
1563unless (extract_from_file('Configure', 'ignore_versioned_solibs')) {
1564 # Before 1cfa4ec74d4933da, so force the libs list.
1565
1566 my @libs;
1567 # This is the current libswanted list from Configure, less the libs removed
1568 # by current hints/linux.sh
1569 foreach my $lib (qw(sfio socket inet nsl nm ndbm gdbm dbm db malloc dl dld
1570 ld sun m crypt sec util c cposix posix ucb BSD)) {
1571 foreach my $dir (@paths) {
1572 next unless -f "$dir/lib$lib.so";
1573 push @libs, "-l$lib";
1574 last;
1575 }
1576 }
390a69a9 1577 $defines{libs} = \@libs unless exists $defines{libs};
6a8dbfd7
NC
1578}
1579
390a69a9
NC
1580$defines{usenm} = undef
1581 if $major < 2 && !exists $defines{usenm};
0142f0ce 1582
67382a3b
NC
1583my (@missing, @created_dirs);
1584
f4800c99 1585if ($options{'force-manifest'}) {
69bf9aba 1586 my $fh = open_or_die('MANIFEST');
67382a3b
NC
1587 while (<$fh>) {
1588 next unless /^(\S+)/;
10c5443e
NC
1589 # -d is special case needed (at least) between 27332437a2ed1941 and
1590 # bf3d9ec563d25054^ inclusive, as manifest contains ext/Thread/Thread
67382a3b 1591 push @missing, $1
10c5443e 1592 unless -f $1 || -d $1;
67382a3b 1593 }
69bf9aba 1594 close_or_die($fh);
67382a3b
NC
1595
1596 foreach my $pathname (@missing) {
1597 my @parts = split '/', $pathname;
1598 my $leaf = pop @parts;
1599 my $path = '.';
1600 while (@parts) {
1601 $path .= '/' . shift @parts;
1602 next if -d $path;
1603 mkdir $path, 0700 or die "Can't create $path: $!";
1604 unshift @created_dirs, $path;
1605 }
69bf9aba
NC
1606 $fh = open_or_die($pathname, '>');
1607 close_or_die($fh);
67382a3b
NC
1608 chmod 0, $pathname or die "Can't chmod 0 $pathname: $!";
1609 }
1610}
1611
af7c500f 1612my @ARGS = '-dEs';
390a69a9
NC
1613foreach my $key (sort keys %defines) {
1614 my $val = $defines{$key};
1615 if (ref $val) {
1616 push @ARGS, "-D$key=@$val";
1617 } elsif (!defined $val) {
1618 push @ARGS, "-U$key";
1619 } elsif (!length $val) {
1620 push @ARGS, "-D$key";
1621 } else {
1622 $val = "" if $val eq "\0";
1623 push @ARGS, "-D$key=$val";
1624 }
1625}
1626push @ARGS, map {"-A$_"} @{$options{A}};
1627
6a8dbfd7
NC
1628# </dev/null because it seems that some earlier versions of Configure can
1629# call commands in a way that now has them reading from stdin (and hanging)
1630my $pid = fork;
1631die "Can't fork: $!" unless defined $pid;
1632if (!$pid) {
7c22f158
NC
1633 open STDIN, '<', '/dev/null';
1634 # If a file in MANIFEST is missing, Configure asks if you want to
1635 # continue (the default being 'n'). With stdin closed or /dev/null,
1636 # it exits immediately and the check for config.sh below will skip.
6a8dbfd7
NC
1637 exec './Configure', @ARGS;
1638 die "Failed to start Configure: $!";
1639}
1640waitpid $pid, 0
1641 or die "wait for Configure, pid $pid failed: $!";
1642
af7c500f
NC
1643# Emulate noextensions if Configure doesn't support it.
1644if (-f 'config.sh') {
1645 if ($major < 10 && $defines{noextensions}) {
1646 edit_file('config.sh', sub {
1647 my @lines = split /\n/, shift;
1648 my @ext = split /\s+/, $defines{noextensions};
1649 foreach (@lines) {
1650 next unless /^extensions=/ || /^dynamic_ext/;
1651 foreach my $ext (@ext) {
1652 s/\b$ext( )?\b/$1/;
1653 }
1654 }
1655 return join "\n", @lines;
1656 });
1657 }
dd7c3e6c
NC
1658 if ($major < 4 && !extract_from_file('config.sh', qr/^trnl=/)) {
1659 # This seems to be necessary to avoid makedepend becoming confused,
1660 # and hanging on stdin. Seems that the code after
1661 # make shlist || ...here... is never run.
1662 edit_file('makedepend.SH', sub {
1663 my $code = shift;
1664 $code =~ s/^trnl='\$trnl'$/trnl='\\n'/m;
1665 return $code;
1666 });
1667 }
1668
af7c500f
NC
1669 system './Configure -S </dev/null' and die;
1670}
1671
0afef97d
NC
1672if ($target =~ /config\.s?h/) {
1673 match_and_exit($target) if $match && -f $target;
30a13282
NC
1674 report_and_exit(!-f $target, 'could build', 'could not build', $target)
1675 if $options{'test-build'};
1676
1677 my $ret = system @ARGV;
1678 report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
dd4e46d7
NC
1679} elsif (!-f 'config.sh') {
1680 # Skip if something went wrong with Configure
1681
1682 skip('could not build config.sh');
1683}
6a8dbfd7 1684
67382a3b
NC
1685# This is probably way too paranoid:
1686if (@missing) {
1687 my @errors;
eb4906f4 1688 require Fcntl;
67382a3b
NC
1689 foreach my $file (@missing) {
1690 my (undef, undef, $mode, undef, undef, undef, undef, $size)
1691 = stat $file;
1692 if (!defined $mode) {
1693 push @errors, "Added file $file has been deleted by Configure";
1694 next;
1695 }
eb4906f4 1696 if (Fcntl::S_IMODE($mode) != 0) {
67382a3b
NC
1697 push @errors,
1698 sprintf 'Added file %s had mode changed by Configure to %03o',
1699 $file, $mode;
1700 }
1701 if ($size != 0) {
1702 push @errors,
1703 "Added file $file had sized changed by Configure to $size";
1704 }
1705 unlink $file or die "Can't unlink $file: $!";
1706 }
1707 foreach my $dir (@created_dirs) {
1708 rmdir $dir or die "Can't rmdir $dir: $!";
1709 }
6c0925a0
NC
1710 skip("@errors")
1711 if @errors;
67382a3b
NC
1712}
1713
6a8dbfd7
NC
1714# Correct makefile for newer GNU gcc
1715# Only really needed if you comment out the use of blead's makedepend.SH
1716{
1717 local $^I = "";
1718 local @ARGV = qw(makefile x2p/makefile);
1719 while (<>) {
1720 print unless /<(?:built-in|command|stdin)/;
1721 }
1722}
6a8dbfd7 1723
0142f0ce
NC
1724if ($major == 2 && extract_from_file('perl.c', qr/^ fclose\(e_fp\);$/)) {
1725 # need to patch perl.c to avoid calling fclose() twice on e_fp when using -e
1726 # This diff is part of commit ab821d7fdc14a438. The second close was
1727 # introduced with perl-5.002, commit a5f75d667838e8e7
1728 # Might want a6c477ed8d4864e6 too, for the corresponding change to pp_ctl.c
1729 # (likely without this, eval will have "fun")
1730 apply_patch(<<'EOPATCH');
1731diff --git a/perl.c b/perl.c
1732index 03c4d48..3c814a2 100644
1733--- a/perl.c
1734+++ b/perl.c
1735@@ -252,6 +252,7 @@ setuid perl scripts securely.\n");
1736 #ifndef VMS /* VMS doesn't have environ array */
1737 origenviron = environ;
1738 #endif
1739+ e_tmpname = Nullch;
1740
1741 if (do_undump) {
1742
1743@@ -405,6 +406,7 @@ setuid perl scripts securely.\n");
1744 if (e_fp) {
1745 if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
1746 croak("Can't write to temp file for -e: %s", Strerror(errno));
1747+ e_fp = Nullfp;
1748 argc++,argv--;
1749 scriptname = e_tmpname;
1750 }
1751@@ -470,10 +472,10 @@ setuid perl scripts securely.\n");
1752 curcop->cop_line = 0;
1753 curstash = defstash;
1754 preprocess = FALSE;
1755- if (e_fp) {
1756- fclose(e_fp);
1757- e_fp = Nullfp;
1758+ if (e_tmpname) {
1759 (void)UNLINK(e_tmpname);
1760+ Safefree(e_tmpname);
1761+ e_tmpname = Nullch;
1762 }
1763
1764 /* now that script is parsed, we can modify record separator */
1765@@ -1369,7 +1371,7 @@ SV *sv;
1766 scriptname = xfound;
1767 }
1768
1769- origfilename = savepv(e_fp ? "-e" : scriptname);
1770+ origfilename = savepv(e_tmpname ? "-e" : scriptname);
1771 curcop->cop_filegv = gv_fetchfile(origfilename);
1772 if (strEQ(origfilename,"-"))
1773 scriptname = "";
1774
1775EOPATCH
1776}
1777
cf5fabc1
NC
1778if (($major >= 7 || $major <= 9) && $^O eq 'openbsd'
1779 && `uname -m` eq "sparc64\n"
1780 # added in 2000 by commit cb434fcc98ac25f5:
1781 && extract_from_file('regexec.c',
1782 qr!/\* No need to save/restore up to this paren \*/!)
1783 # re-indented in 2006 by commit 95b2444054382532:
1784 && extract_from_file('regexec.c', qr/^\t\tCURCUR cc;$/)) {
1785 # Need to work around a bug in (at least) OpenBSD's 4.6's sparc64 compiler
1786 # ["gcc (GCC) 3.3.5 (propolice)"]. Between commits 3ec562b0bffb8b8b (2002)
1787 # and 1a4fad37125bac3e^ (2005) the darling thing fails to compile any code
1788 # for the statement cc.oldcc = PL_regcc;
1789 # If you refactor the code to "fix" that, or force the issue using set in
1790 # the debugger, the stack smashing detection code fires on return from
1791 # S_regmatch(). Turns out that the compiler doesn't allocate any (or at
1792 # least enough) space for cc.
1793 # Restore the "uninitialised" value for cc before function exit, and the
1794 # stack smashing code is placated.
1795 # "Fix" 3ec562b0bffb8b8b (which changes the size of auto variables used
1796 # elsewhere in S_regmatch), and the crash is visible back to
1797 # bc517b45fdfb539b (which also changes buffer sizes). "Unfix"
1798 # 1a4fad37125bac3e and the crash is visible until 5b47454deb66294b.
1799 # Problem goes away if you compile with -O, or hack the code as below.
1800 #
1801 # Hence this turns out to be a bug in (old) gcc. Not a security bug we
1802 # still need to fix.
1803 apply_patch(<<'EOPATCH');
1804diff --git a/regexec.c b/regexec.c
1805index 900b491..6251a0b 100644
1806--- a/regexec.c
1807+++ b/regexec.c
1808@@ -2958,7 +2958,11 @@ S_regmatch(pTHX_ regnode *prog)
1809 I,I
1810 *******************************************************************/
1811 case CURLYX: {
1812- CURCUR cc;
1813+ union {
1814+ CURCUR hack_cc;
1815+ char hack_buff[sizeof(CURCUR) + 1];
1816+ } hack;
1817+#define cc hack.hack_cc
1818 CHECKPOINT cp = PL_savestack_ix;
1819 /* No need to save/restore up to this paren */
1820 I32 parenfloor = scan->flags;
1821@@ -2983,6 +2987,7 @@ S_regmatch(pTHX_ regnode *prog)
1822 n = regmatch(PREVOPER(next)); /* start on the WHILEM */
1823 regcpblow(cp);
1824 PL_regcc = cc.oldcc;
1825+#undef cc
1826 saySAME(n);
1827 }
1828 /* NOT REACHED */
1829EOPATCH
1830}
1831
6f8c21fa
NC
1832if ($major < 8 && $^O eq 'openbsd'
1833 && !extract_from_file('perl.h', qr/include <unistd\.h>/)) {
1834 # This is part of commit 3f270f98f9305540, applied at a slightly different
1835 # location in perl.h, where the context is stable back to 5.000
1836 apply_patch(<<'EOPATCH');
1837diff --git a/perl.h b/perl.h
1838index 9418b52..b8b1a7c 100644
1839--- a/perl.h
1840+++ b/perl.h
1841@@ -496,6 +496,10 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
1842 # include <sys/param.h>
1843 #endif
1844
1845+/* If this causes problems, set i_unistd=undef in the hint file. */
1846+#ifdef I_UNISTD
1847+# include <unistd.h>
1848+#endif
1849
1850 /* Use all the "standard" definitions? */
1851 #if defined(STANDARD_C) && defined(I_STDLIB)
1852EOPATCH
1853}
1854
f50dca98
NC
1855if ($major == 4 && extract_from_file('scope.c', qr/\(SV\*\)SSPOPINT/)) {
1856 # [PATCH] 5.004_04 +MAINT_TRIAL_1 broken when sizeof(int) != sizeof(void)
1857 # Fixes a bug introduced in 161b7d1635bc830b
4e540a4e 1858 apply_commit('9002cb76ec83ef7f');
f50dca98
NC
1859}
1860
1861if ($major == 4 && extract_from_file('av.c', qr/AvARRAY\(av\) = 0;/)) {
1862 # Fixes a bug introduced in 1393e20655efb4bc
4e540a4e 1863 apply_commit('e1c148c28bf3335b', 'av.c');
f50dca98
NC
1864}
1865
1866if ($major == 4 && $^O eq 'linux') {
1867 # Whilst this is fixed properly in f0784f6a4c3e45e1 which provides the
1868 # Configure probe, it's easier to back out the problematic changes made in
1869 # these previous commits:
1870 if (extract_from_file('doio.c',
1871 qr!^/\* XXX REALLY need metaconfig test \*/$!)) {
4e540a4e 1872 revert_commit('4682965a1447ea44', 'doio.c');
f50dca98
NC
1873 }
1874 if (my $token = extract_from_file('doio.c',
1875 qr!^#if (defined\(__sun(?:__)?\)) && defined\(__svr4__\) /\* XXX Need metaconfig test \*/$!)) {
1876 my $patch = `git show -R 9b599b2a63d2324d doio.c`;
1877 $patch =~ s/defined\(__sun__\)/$token/g;
1878 apply_patch($patch);
1879 }
1880 if (extract_from_file('doio.c',
1881 qr!^/\* linux \(and Solaris2\?\) uses :$!)) {
4e540a4e 1882 revert_commit('8490252049bf42d3', 'doio.c');
f50dca98
NC
1883 }
1884 if (extract_from_file('doio.c',
1885 qr/^ unsemds.buf = &semds;$/)) {
4e540a4e 1886 revert_commit('8e591e46b4c6543e');
f50dca98
NC
1887 }
1888 if (extract_from_file('doio.c',
1889 qr!^#ifdef __linux__ /\* XXX Need metaconfig test \*/$!)) {
4e540a4e 1890 # Reverts part of commit 3e3baf6d63945cb6
f50dca98
NC
1891 apply_patch(<<'EOPATCH');
1892diff --git b/doio.c a/doio.c
1893index 62b7de9..0d57425 100644
1894--- b/doio.c
1895+++ a/doio.c
1896@@ -1333,9 +1331,6 @@ SV **sp;
1897 char *a;
1898 I32 id, n, cmd, infosize, getinfo;
1899 I32 ret = -1;
1900-#ifdef __linux__ /* XXX Need metaconfig test */
1901- union semun unsemds;
1902-#endif
1903
1904 id = SvIVx(*++mark);
1905 n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0;
1906@@ -1364,29 +1359,11 @@ SV **sp;
1907 infosize = sizeof(struct semid_ds);
1908 else if (cmd == GETALL || cmd == SETALL)
1909 {
1910-#ifdef __linux__ /* XXX Need metaconfig test */
1911-/* linux uses :
1912- int semctl (int semid, int semnun, int cmd, union semun arg)
1913-
1914- union semun {
1915- int val;
1916- struct semid_ds *buf;
1917- ushort *array;
1918- };
1919-*/
1920- union semun semds;
1921- if (semctl(id, 0, IPC_STAT, semds) == -1)
1922-#else
1923 struct semid_ds semds;
1924 if (semctl(id, 0, IPC_STAT, &semds) == -1)
1925-#endif
1926 return -1;
1927 getinfo = (cmd == GETALL);
1928-#ifdef __linux__ /* XXX Need metaconfig test */
1929- infosize = semds.buf->sem_nsems * sizeof(short);
1930-#else
1931 infosize = semds.sem_nsems * sizeof(short);
1932-#endif
1933 /* "short" is technically wrong but much more portable
1934 than guessing about u_?short(_t)? */
1935 }
1936@@ -1429,12 +1406,7 @@ SV **sp;
1937 #endif
1938 #ifdef HAS_SEM
1939 case OP_SEMCTL:
1940-#ifdef __linux__ /* XXX Need metaconfig test */
1941- unsemds.buf = (struct semid_ds *)a;
1942- ret = semctl(id, n, cmd, unsemds);
1943-#else
1944 ret = semctl(id, n, cmd, (struct semid_ds *)a);
1945-#endif
1946 break;
1947 #endif
1948 #ifdef HAS_SHM
1949EOPATCH
1950 }
1951 # Incorrect prototype added as part of 8ac853655d9b7447, fixed as part of
1952 # commit dc45a647708b6c54, with at least one intermediate modification.
1953 # Correct prototype for gethostbyaddr has socklen_t second. Linux has
1954 # uint32_t first for getnetbyaddr.
1955 # Easiest just to remove, instead of attempting more complex patching.
1956 # Something similar may be needed on other platforms.
1957 edit_file('pp_sys.c', sub {
1958 my $code = shift;
1959 $code =~ s/^ struct hostent \*(?:PerlSock_)?gethostbyaddr\([^)]+\);$//m;
1960 $code =~ s/^ struct netent \*getnetbyaddr\([^)]+\);$//m;
1961 return $code;
1962 });
1963}
1964
c59e8fd6
NC
1965if ($major < 10 and -f 'ext/IPC/SysV/SysV.xs') {
1966 edit_file('ext/IPC/SysV/SysV.xs', sub {
1967 my $xs = shift;
1968 my $fixed = <<'EOFIX';
1969
1970#include <sys/types.h>
1971#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
1972#ifndef HAS_SEM
1973# include <sys/ipc.h>
1974#endif
1975# ifdef HAS_MSG
1976# include <sys/msg.h>
1977# endif
1978# ifdef HAS_SHM
1979# if defined(PERL_SCO) || defined(PERL_ISC)
1980# include <sys/sysmacros.h> /* SHMLBA */
1981# endif
1982# include <sys/shm.h>
1983# ifndef HAS_SHMAT_PROTOTYPE
1984 extern Shmat_t shmat (int, char *, int);
1985# endif
1986# if defined(HAS_SYSCONF) && defined(_SC_PAGESIZE)
1987# undef SHMLBA /* not static: determined at boot time */
1988# define SHMLBA sysconf(_SC_PAGESIZE)
1989# elif defined(HAS_GETPAGESIZE)
1990# undef SHMLBA /* not static: determined at boot time */
1991# define SHMLBA getpagesize()
1992# endif
1993# endif
1994#endif
1995EOFIX
1996 $xs =~ s!
1997#include <sys/types\.h>
1998.*
1999(#ifdef newCONSTSUB|/\* Required)!$fixed$1!ms;
2000 return $xs;
2001 });
2002}
2003
686af304
NC
2004if (-f 'ext/POSIX/Makefile.PL'
2005 && extract_from_file('ext/POSIX/Makefile.PL',
2006 qr/Explicitly avoid including/)) {
2007 # commit 6695a346c41138df, which effectively reverts 170888cff5e2ffb7
2008
2009 # PERL5LIB is populated by make_ext.pl with paths to the modules we need
2010 # to run, don't override this with "../../lib" since that may not have
2011 # been populated yet in a parallel build.
4e540a4e 2012 apply_commit('6695a346c41138df');
686af304
NC
2013}
2014
9a999a97 2015# Parallel build for miniperl is safe
9da8cb0a 2016system "make $j miniperl </dev/null";
9a999a97 2017
2526f4b8
NC
2018my $expected = $target =~ /^test/ ? 't/perl'
2019 : $target eq 'Fcntl' ? "lib/auto/Fcntl/Fcntl.$Config{so}"
2020 : $target;
2021my $real_target = $target eq 'Fcntl' ? $expected : $target;
2022
9a999a97
NC
2023if ($target ne 'miniperl') {
2024 # Nearly all parallel build issues fixed by 5.10.0. Untrustworthy before that.
372ba1f9 2025 $j = '' if $major < 10;
9a999a97 2026
2526f4b8 2027 if ($real_target eq 'test_prep') {
9a999a97
NC
2028 if ($major < 8) {
2029 # test-prep was added in 5.004_01, 3e3baf6d63945cb6.
2030 # renamed to test_prep in 2001 in 5fe84fd29acaf55c.
2031 # earlier than that, just make test. It will be fast enough.
2526f4b8
NC
2032 $real_target = extract_from_file('Makefile.SH',
2033 qr/^(test[-_]prep):/,
2034 'test');
9a999a97 2035 }
6a8dbfd7 2036 }
6a8dbfd7 2037
9da8cb0a 2038 system "make $j $real_target </dev/null";
9a999a97 2039}
6a8dbfd7 2040
67382a3b
NC
2041my $missing_target = $expected =~ /perl$/ ? !-x $expected : !-r $expected;
2042
f4800c99 2043if ($options{'test-build'}) {
2526f4b8
NC
2044 report_and_exit($missing_target, 'could build', 'could not build',
2045 $real_target);
67382a3b 2046} elsif ($missing_target) {
2526f4b8 2047 skip("could not build $real_target");
67382a3b 2048}
6a8dbfd7 2049
2526f4b8 2050match_and_exit($real_target) if $match;
0afef97d
NC
2051
2052if (defined $options{'one-liner'}) {
2526f4b8 2053 my $exe = $target =~ /^(?:perl$|test)/ ? 'perl' : 'miniperl';
0afef97d
NC
2054 unshift @ARGV, "./$exe", '-Ilib', '-e', $options{'one-liner'};
2055}
2056
6a8dbfd7 2057# This is what we came here to run:
915f531b
NC
2058
2059if (exists $Config{ldlibpthname}) {
2060 require Cwd;
2061 my $varname = $Config{ldlibpthname};
2062 my $cwd = Cwd::getcwd();
2063 if (defined $ENV{$varname}) {
2064 $ENV{$varname} = $cwd . $Config{path_sep} . $ENV{$varname};
2065 } else {
2066 $ENV{$varname} = $cwd;
2067 }
2068}
2069
6a8dbfd7
NC
2070my $ret = system @ARGV;
2071
f1050811 2072report_and_exit($ret, 'zero exit from', 'non-zero exit from', "@ARGV");
9a999a97
NC
2073
2074# Local variables:
2075# cperl-indent-level: 4
2076# indent-tabs-mode: nil
2077# End:
2078#
2079# ex: set ts=8 sts=4 sw=4 et: