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