(
usedevel => '',
optimize => '-g',
- cc => 'ccache cc',
+ cc => (`ccache --version`, $?) ? 'cc' : 'ccache cc',
ld => 'cc',
($linux64 ? (libpth => \@paths) : ()),
);
'target=s', 'jobs|j=i', 'expect-pass=i',
'expect-fail' => sub { $options{'expect-pass'} = 0; },
'clean!', 'one-liner|e=s', 'match=s', 'force-manifest',
- 'force-regen', 'test-build', 'check-args', 'A=s@',
- 'usage|help|?',
+ 'force-regen', 'test-build', 'A=s@', 'l', 'w',
+ 'check-args', 'check-shebang!', 'usage|help|?',
'D=s@' => sub {
my (undef, $val) = @_;
if ($val =~ /\A([^=]+)=(.*)/s) {
pod2usage(exitval => 255, verbose => 1) if $options{usage};
pod2usage(exitval => 255, verbose => 1)
unless @ARGV || $match || $options{'test-build'} || defined $options{'one-liner'};
+pod2usage(exitval => 255, verbose => 1)
+ if !$options{'one-liner'} && ($options{l} || $options{w});
+
+check_shebang($ARGV[0]) if $options{'check-shebang'} && @ARGV;
exit 0 if $options{'check-args'};
=item *
+-l
+
+Add C<-l> to the command line with C<-e>
+
+This will automatically append a newline to every output line of your testcase.
+Note that you can't specify an argument to F<perl>'s C<-l> with this, as it's
+not feasible to emulate F<perl>'s somewhat quirky switch parsing with
+L<Getopt::Long>. If you need the full flexibility of C<-l>, you need to write
+a full test case, instead of using C<bisect.pl>'s C<-e> shortcut.
+
+=item *
+
+-w
+
+Add C<-w> to the command line with C<-e>
+
+It's not valid to pass C<-l> or C<-w> to C<bisect.pl> unless you are also
+using C<-e>
+
+=item *
+
--expect-fail
The test case should fail for the I<start> revision, and pass for the I<end>
--validate
-Test that all stable revisions can be built. Attempts to build I<blead>,
-I<v5.14.0> .. I<perl-5.002>. Stops at the first failure, without cleaning
-the checkout. Ignores I<--start> and I<--end>. Useful for validating a new
+Test that all stable revisions can be built. By default, attempts to build
+I<blead>, I<v5.14.0> .. I<perl-5.002>. Stops at the first failure, without
+cleaning the checkout. Use I<--start> to specify the earliest revision to
+test, I<--end> to specify the most recent. Useful for validating a new
OS/CPU/compiler combination. For example
- ../perl/Porting/bisect.pl --validate -e'print "Hello from $]\n"'
+ ../perl/Porting/bisect.pl --validate -le 'print "Hello from $]"'
+
+If no testcase is specified, the default is to use F<t/TEST> to run
+F<t/base/*.t>
=item *
=item *
+--check-shebang
+
+Validate that the test case isn't an executable file with a
+C<#!/usr/bin/perl> line (or similar). As F<bisect-runner.pl> does B<not>
+prepend C<./perl> to the test case, a I<#!> line specifying an external
+F<perl> binary will cause the test case to always run with I<that> F<perl>,
+not the F<perl> built by the bisect runner. Likely this is not what you
+wanted. If your test case is actually a wrapper script to run other
+commands, you should run it with an explicit interpreter, to be clear. For
+example, instead of C<../perl/Porting/bisect.pl ~/test/testcase.pl> you'd
+run C<../perl/Porting/bisect.pl /usr/bin/perl ~/test/testcase.pl>
+
+=item *
+
--usage
=item *
and die "Could not extract $file at revision $commit";
}
+sub check_shebang {
+ my $file = shift;
+ return unless -e $file;
+ if (!-x $file) {
+ die "$file is not executable.
+system($file, ...) is always going to fail.
+
+Bailing out";
+ }
+ my $fh = open_or_die($file);
+ my $line = <$fh>;
+ return unless $line =~ m{\A#!(/\S+/perl\S*)\s};
+ die "$file will always be run by $1
+It won't be tested by the ./perl we build.
+If you intended to run it with that perl binary, please change your
+test case to
+
+ $1 @ARGV
+
+If you intended to test it with the ./perl we build, please change your
+test case to
+
+ ./perl -Ilib @ARGV
+
+[You may also need to add -- before ./perl to prevent that -Ilib as being
+parsed as an argument to bisect.pl]
+
+Bailing out";
+}
+
sub clean {
if ($options{clean}) {
# Needed, because files that are build products in this checked out
if (defined $options{'one-liner'}) {
my $exe = $target =~ /^(?:perl$|test)/ ? 'perl' : 'miniperl';
- unshift @ARGV, "./$exe", '-Ilib', '-e', $options{'one-liner'};
+ unshift @ARGV, '-e', $options{'one-liner'};
+ unshift @ARGV, '-l' if $options{l};
+ unshift @ARGV, '-w' if $options{w};
+ unshift @ARGV, "./$exe", '-Ilib';
}
# This is what we came here to run:
EOPATCH
}
+
+ if ($major == 11) {
+ if (extract_from_file('patchlevel.h',
+ qr/^#include "unpushed\.h"/)) {
+ # I had thought it easier to detect when building one of the 52
+ # commits with the original method of incorporating the git
+ # revision and drop parallel make flags. Commits shown by
+ # git log 46807d8e809cc127^..dcff826f70bf3f64^ ^d4fb0a1f15d1a1c4
+ # However, it's not actually possible to make miniperl for that
+ # configuration as-is, because the file .patchnum is only made
+ # as a side effect of target 'all'
+ # I also don't think that it's "safe" to simply run
+ # make_patchnum.sh before the build. We need the proper
+ # dependency rules in the Makefile to *stop* it being run again
+ # at the wrong time.
+ # This range is important because contains the commit that
+ # merges Schwern's y2038 work.
+ apply_patch(<<'EOPATCH');
+diff --git a/Makefile.SH b/Makefile.SH
+index 9ad8b6f..106e721 100644
+--- a/Makefile.SH
++++ b/Makefile.SH
+@@ -540,9 +544,14 @@ sperl.i: perl.c $(h)
+
+ .PHONY: all translators utilities make_patchnum
+
+-make_patchnum:
++make_patchnum: lib/Config_git.pl
++
++lib/Config_git.pl: make_patchnum.sh
+ sh $(shellflags) make_patchnum.sh
+
++# .patchnum, unpushed.h and lib/Config_git.pl are built by make_patchnum.sh
++unpushed.h .patchnum: lib/Config_git.pl
++
+ # make sure that we recompile perl.c if .patchnum changes
+ perl$(OBJ_EXT): .patchnum unpushed.h
+
+EOPATCH
+ } elsif (-f '.gitignore'
+ && extract_from_file('.gitignore', qr/^\.patchnum$/)) {
+ # 8565263ab8a47cda to 46807d8e809cc127^ inclusive.
+ edit_file('Makefile.SH', sub {
+ my $code = shift;
+ $code =~ s/^make_patchnum:\n/make_patchnum: .patchnum
+
+.sha1: .patchnum
+
+.patchnum: make_patchnum.sh
+/m;
+ return $code;
+ });
+ } elsif (-f 'lib/.gitignore'
+ && extract_from_file('lib/.gitignore',
+ qr!^/Config_git.pl!)
+ && !extract_from_file('Makefile.SH',
+ qr/^uudmap\.h.*:bitcount.h$/)) {
+ # Between commits and dcff826f70bf3f64 and 0f13ebd5d71f8177^
+ edit_file('Makefile.SH', sub {
+ my $code = shift;
+ # Bug introduced by 344af494c35a9f0f
+ # fixed in 0f13ebd5d71f8177
+ $code =~ s{^(pod/perlapi\.pod) (pod/perlintern\.pod): }
+ {$1: $2\n\n$2: }m;
+ # Bug introduced by efa50c51e3301a2c
+ # fixed in 0f13ebd5d71f8177
+ $code =~ s{^(uudmap\.h) (bitcount\.h): }
+ {$1: $2\n\n$2: }m;
+
+ # The rats nest of getting git_version.h correct
+
+ if ($code =~ s{git_version\.h: stock_git_version\.h
+\tcp stock_git_version\.h git_version\.h}
+ {}m) {
+ # before 486cd780047ff224
+
+ # We probably can't build between
+ # 953f6acfa20ec275^ and 8565263ab8a47cda
+ # inclusive, but all commits in that range
+ # relate to getting make_patchnum.sh working,
+ # so it is extremely unlikely to be an
+ # interesting bisect target. They will skip.
+
+ # No, don't spawn a submake if
+ # make_patchnum.sh or make_patchnum.pl fails
+ $code =~ s{\|\| \$\(MAKE\) miniperl.*}
+ {}m;
+ $code =~ s{^\t(sh.*make_patchnum\.sh.*)}
+ {\t-$1}m;
+
+ # Use an external perl to run make_patchnum.pl
+ # because miniperl still depends on
+ # git_version.h
+ $code =~ s{^\t.*make_patchnum\.pl}
+ {\t-$^X make_patchnum.pl}m;
+
+
+ # "Truth in advertising" - running
+ # make_patchnum generates 2 files.
+ $code =~ s{^make_patchnum:.*}{
+make_patchnum: lib/Config_git.pl
+
+git_version.h: lib/Config_git.pl
+
+perlmini\$(OBJ_EXT): git_version.h
+
+lib/Config_git.pl:}m;
+ }
+ return $code;
+ });
+ }
+ }
+
if ($major < 14) {
# Commits dc0655f797469c47 and d11a62fe01f2ecb2
edit_file('Makefile.SH', sub {
apply_commit('e1c148c28bf3335b', 'av.c');
}
- if ($major == 4 && !extract_from_file('perl.c', qr/delimcpy.*,$/)) {
- # bug introduced in 2a92aaa05aa1acbf, fixed in 8490252049bf42d3
- apply_patch(<<'EOPATCH');
+ if ($major == 4) {
+ my $rest = extract_from_file('perl.c', qr/delimcpy(.*)/);
+ if (defined $rest and $rest !~ /,$/) {
+ # delimcpy added in fc36a67e8855d031, perl.c refactored to use it.
+ # bug introduced in 2a92aaa05aa1acbf, fixed in 8490252049bf42d3
+ # code then moved to util.c in commit 491527d0220de34e
+ apply_patch(<<'EOPATCH');
diff --git a/perl.c b/perl.c
index 4eb69e3..54bbb00 100644
--- a/perl.c
&len);
#endif /* ! (atarist || DOSISH) */
EOPATCH
+ }
}
if ($major == 4 && $^O eq 'linux') {