App-perlall

 view release on metacpan or  search on metacpan

script/perlall  view on Meta::CPAN

    --older=s     only older versions. glob-style as in --newer.
    --nogit       skip @ git versions
    --main|-m     same as --skip=outdated,
                  only 5.6.2 5.8.[4589] 5.10.1 5.12.4 5.14.2 5.15.5
    --reverse|-r  oldest first. default is sorted by newest first

    --quiet|-q    make perlall command quieter
    --verbose|v   make perlall command say more
    --dryrun!     do not execute commands, only print
    --nolog       skip writing log file(s)
    --debug|-d,   lots of internal debugging output
    --timeout=i   IPC::Cmd::run timeout in seconds, Default: 0
    --gittag=s    Internally set by testvm for the logfile
    --forked!     Internally set by testvm

    --list|-l     shortcut for command list
    --help|-h
    --version|-V

Specific options after the command I<(see also below)>

build and smoke only:

    --D=s           Configure option
    --A=s           Configure option
    --U=s           Configure option
    -jn             parallel make
    --link          -Dmksymlinks with blead, otherwise copy
    --install       skip Configure && make, only do make install
    --allpatches    apply also compiler and asan patches
    --patches=name  apply Compiler or Asan patches (Devel::PatchPerl::Plugin)

build and makeinstall:

  --notest|-n   skip the test suite on build and makeinstall
  --force|-f    force install

testvm: see L</testvm>

=head1 DESCRIPTION

B<perlall> is like a better L<perlbrew> with a lot of testing
features.  The perls are in the default F</usr/local/bin/>, and
F</usr/local/lib/perl5/VERSION> paths, instead of locally, and . You
need write access to the default PREFIX F</usr/local>, e.g. via
C<sudo>.  It does not use L<local::lib>, does not mangle C<PERL5LIB>
and builds and keeps sane global perl installations with special
suffices, without the need to save and restore internal states.  The
suffices are used in postprocessing scripts.

The currently used perl together with more options is stored as alias
C<p> in F<~/.perlall>, which can be sourced by your F<.profile>.

    alias p=perl5.15.4d-nt

Build and init perls:

Version numbers look like C<5.xx.x> and the perl C<suffix> can be any of:

    C<d>    DEBUGGING
    C<-nt>  non-threaded, or
    C<-m>   multi (non-threaded)
    C<@xxxxxx> git ids / branch names

You want to switch to use the "thr" suffix, then the default
is non-threaded. This behaviour is controlled via the config setting
C<usethrsuffix=1>. But be consistent to interpret the logfiles.

For older perls special patches are applied to successfully build
them. C<archname> and the archlibs are extended by C<-debug> and
special git suffices. The installed perl binary and on windows
the F<perl.dll> ditto.

Platforms

I use and support perlall on cygwin, linux (debian+centos),
freebsd, openbsd and solaris, with bash, dash and ksh.
Supporting other platforms besides VMS should not be hard.
freebsd needs sudo from ports. mingw (strawberry) and msys
(mingw cross) support is planned.

Log Files

Most commands always create a log file with the command, platform
and version, like F<log.maketest-centos5-5.10.1d-nt> or
F<log.makeinstall-osx10.6.8-5.15.4>, F<log.build-osx10.6.8-5.15.4d-nt@30cb48da>.

In the L<B::C> perl-compiler distribution there are some post-processing scripts
F<status_upd>, F<store_rpt>, F<download-reports> for such logfiles.

Windows

Note in cmd.exe you need different quoting rules.

You can try:
    perlall do -e"""print $^O"""

But easier is:
    perlall do '-e"print $^O"'

=cut


sub setup {
  $_[0]->register_commands( {-ignore_prefix => '_'} );
  $_[0]->register('install', \&build, "alias to build");
  $_[0]->register('smoke', \&build, "(NYI) smoke [ perl<version><suffix> branch ]");
  $_[0]->unregister('basename'); #imported (bug)
}

sub App::Rad::Help::usage {
  return "\nUsage: ".basename($0)." [options] command [arguments]";
}

sub pre_process {
  my $c = shift;
  my $cmd = $c->cmd;

  # config defaults: for all
  $c->config->{PERLALL_PREFIX} = '/usr/local';
  # build only
  $c->config->{PERLALL_BUILDROOT} = '/usr/src/perl';
  if ($cmd eq 'init') {
    $c->config->{cpan} = 'cpan';
    # DBD::Gofer on linux needs Clone but does not check for it
    $c->config->{'init-modules'} = 'YAML Clone DBI DBD::SQLite CPAN::SQLite Devel::Platform::Info'

script/perlall  view on Meta::CPAN

sub _patch {
  my ($c, $file) = @_;
  $c->_system("git show HEAD..blead $file | patch -N -p1")
    and warn("patch HEAD..blead $file had some errors\n");
}

# like Porting/bisect-runner.pl apply_commit
sub _apply_commit {
  my ($c, $commit, @files) = @_;
  $c->_system("git show $commit @files | patch -N -p1")
    and warn("cannot apply commit $commit".(@files ? " to @files":"")."\n");
}

sub _teardown {
  my $c = shift;
  close $c->stash->{log_fh} if $c->stash->{log_fh};
  ""
}

sub _fail {
  my $c = shift;
  if ($c->options->{verbose}) {
    warn $c->{output}," at perlall line @{[(caller(0))[2]]}\n";
  }
  die "@_\n";
}

sub _glob_git {
  my $c = shift;
  my $git = shift;
  return qw(smoke-me/scream smoke-me/taint.t ) if $c->options->{dryrun};
  my $srcdir = $c->config->{'perl-git'};
  my $cwd = Cwd::getcwd;
  chdir "$srcdir/.git/refs/heads" or die;
  # XXX expand subdirs with glob. smoke-me/s*: smoke-me/s/r => smoke-me/s
  # => File::Find
  my @git = glob $git;
  chdir "../remotes/origin" or die;
  push @git, glob $git;
  chdir "../../tags" or die;
  push @git, glob $git;
  chdir $cwd or die;
  return @git;
}

=head2 COMMANDS

=over

=item B<build> [OPTIONS] <version><suffix> [ branch|from ]

Build and install the given version of perl.

The optional 2nd argument C<from> can be a git tag/commit/branch id,
e.g. a smoke-me branch, or a file or url with the perl-*.tar.gz.
The branchname or commit-id is added to the archname and dll suffix, such as
C<@sproututf8> for C<sprout/utf8>, the binary name is taken from the
first argument. All unreleased git versions, like C<blead> or C<smoke-me>
branches get a C<@gitid> suffix. C<smoke-me/> is stripped from the
suffix. The special version "blead" denotes the latest version.
E.g. C<perlall build blead-nt> builds latest non-threaded.

If the checkout from a bit branch is not a release, the suffix will be
marked with C<@> and the sources are copied to the
builddir.

More special perl suffix rules:

  d     -DDEBUGGING
  -nt   non-threaded
  -m    multiplicity
  -clang -Dcc=clang
  -asan  clang -fsanitize=address
  -tsan  clang -fsanitize=thread
  -msan  clang -fsanitize=memory
  -ubsan clang -fsanitize=undefined
  -isan  clang -fsanitize=integer
  -dflow clang -fsanitize=dataflow
  -sstack clang -fsanitize=safestack
  -cps   clang-cps -fcps
  -cpi   clang-cps -fcpi
  -cow  -DPERL_NEW_COPY_ON_WRITE
  -mad  -Dmad

C<-Dmksymlinks> is used for blead, unless the option C<--link> is
specified.

On cygwin and windows the F<perl*.dll> also gets the suffix, because they
are stored globally.

The specified perl is taken from a perl git repo (version or tag or branch)
(specified via perl-git in ~/.perlall), or downloaded
via CPAN. (not yet)

C<man> files are not installed. This is the job for the default
/usr/local/bin/perl or /usr/bin/perl.

C<-Dusedevel -Uversiononly> is always used to install versioned executables.

Special site-specific non-default config vars are taken from
F</usr/local/bin/perl>, such as C<cf_email, perladmin, ccflags, cc,
ldflags, ld, pager, libpth, incpth, useshrplib>.

The builddir is under C<PERLALL_BUILDROOT> (Default: "/usr/src/perl")
as "build-E<lt>versionE<gt>E<lt>suffix>"
The intermediate "make install DESTDIR" as "inst-E<lt>versionE<gt>E<lt>suffixE<gt>".

Specific Options:

  -D.. -U.. -A..  pass through switches to the perl Configure script.

    perlall build perl5.10.1-nt -Dusemymalloc -Uuselargefiles

    Certain special switches are merged from F</usr/local/bin/perl> or F</usr/bin/perl>

  --as name     Install a given perl under the given name. (not yet)

    perlall build perl5.6.2 -Dusemymalloc --as perl5.6.2-mymalloc
    perlall build blead-nt smoke-me/test --as perl5.15.4-test

  -jnum         Enable parallel make and test (if supported by the target perl)

                perlall build -j5 perl5.12.3

  --link        Force -Dmksymlinks to the srcdir for blead only.
                Otherwise releases from git are copied anew.
  -n|--notest   Skip the test suite
  -f|--force    Force installation if make test fails.
  --install     skip Configure, make, make test. make install only.

=cut


sub build

script/perlall  view on Meta::CPAN

      if ($gitsuffix =~ /\*/) { #expand branch glob-style
	my $result = '';
	my @git = $c->_glob_git($gitsuffix);
	_print(0,"perlall build $p $gitsuffix => ",@git);
	for my $git (@git) {
	  my $pg = $p;
	  my $s = $git;
	  $s =~ s/^smoke-me\///;
	  # $s =~ s{/}{}g;
	  $s =~ s/\W//g; # collapse non-word chars
	  $pg = $p."@".substr($s,0,12);
	  $result .= $c->_build($pg, $git, $ps, '@'.$git, $root, $prefix, $cwd);
	}
	return $result;
      }
      my $srcdir = $cperl ? $c->config->{'cdcperl'} : $c->config->{'perl-git'};
      if ($gitsuffix =~ /^blead/ and !$dryrun and -d "$srcdir/.git") {
	$gitsuffix = substr(`GIT_DIR=$srcdir/.git git rev-parse $gitsuffix`,0,8);
      }
      unless ($p =~ /@/) {
	my $git = $gitsuffix;
	$git =~ s/^smoke-me\///;
	# $git =~ s{/}{}g;
	$git =~ s/\W//g; # collapse non-word chars
	$git = "@".substr($git,0,12);
	$p .= $git;
      }
      $gitsuffix = "@".$gitsuffix;
    }
  }
  return $c->_build($p, $from, $ps, $gitsuffix, $root, $prefix, $cwd);
}

sub _build {
  my ($c, $p, $from, $ps, $gitsuffix, $root, $prefix, $cwd) = @_;
  $c->debug("c, \$p=$p, \$from=$from, \$ps=$ps, \$gitsuffix=$gitsuffix,"
	   ." \$root=$root, \$prefix=$prefix, \$cwd=$cwd");

  my $make = $Config{make};
  my $sed = $Config{sed};
  $sed = "sed" unless $sed;
  my $cp = $Config{cp};
  $cp = "cp" unless $cp;
  my $mv = $Config{mv};
  $mv = "mv" unless $mv;
  my $rm = $Config{rm};
  $rm = "rm" unless $rm;
  my $sudo = $c->config->{sudo};
  $sudo = "" if $root =~ m!^/home!; # don't sudo if installing locally
  $sudo = "" unless $<; # already sudo
  # since when was make test parallel safe?
  my @j = ("-j".$c->options->{j}) if $c->options->{j} and !$c->_older( $ps, "5.10.0");
  my ($testerr, $archname);
  my $is_cperl = $from =~ /^cperl/;

  my $dryrun = $c->options->{dryrun};
  my $srcdir = $is_cperl ? $c->config->{'cdcperl'} : $c->config->{'perl-git'};
  my ($suffix) = $p =~ /5\.\d\d?\.\d\d?(.+)$/;
  my $debug = substr($suffix,0,1) eq 'd';
  my $multi = $suffix =~ /^d?-m[^a-z]?/;
  my $ithreads = $suffix !~ /^d?-nt[^a-z]?/;
  my ($archsuffix) = $suffix =~ /d?(?:-nt|-m[^a-z]?|thr)(.+)$/;
  my ($asan, $cc);
  if ($suffix =~ /-mad/) {
    push @{$c->options->{D}}, "mad=y";
  }
  if ($suffix =~ /-cow/) {
    push @{$c->options->{A}}, "ccflags=-DPERL_NEW_COPY_ON_WRITE";
  }
  if ($suffix =~ /-(clang|asan|tsan|msan|ubsan|isan|dflow|sstack|cps|cpi)/) {
    $cc = 'clang';
    unless (grep /cc=/, @{$c->options->{D}}) {
      push @{$c->options->{D}}, "cc=clang";
    } else {
      ($cc) = map /cc=(.*)$/, @{$c->options->{D}};
    }
    push @{$c->options->{D}}, "optimize='-fno-omit-frame-pointer -gline-tables-only'";
    if ($suffix =~ /-asan/) {
      $asan = "-fsanitize=address";
      push @{$c->options->{A}}, "ccflags=$asan";
    }
    if ($suffix =~ /-(cps|cpi)/) { # only with a levee clang yet
      my $san = $1;
      push @{$c->options->{D}}, "cc=clang-cps", "ld=clang-cps";
      push @{$c->options->{A}}, "ccflags='-f$san'",
                                "ldflags='-f$san'",
                                "lddlflags='-f$san'";
    }
    if ($suffix =~ /-(tsan|ubsan|msan|isan|dflow)/) {
      my %sanmap = (tsan => 'thread',
                    ubsan => 'undefined',
                    msan => 'memory',
                    isan => 'integer',
                    dflow => 'dataflow',
                    sstack => 'safestack',
                    # cps  => 'cps',
                    # cpi  => 'cpi'
      );
      my $san = $sanmap{$1};
      push @{$c->options->{A}}, "ccflags='-fsanitize=$san -fPIE'",
                                "ldflags='-fsanitize=$san -fpie'",
                                "lddlflags='-shared -fsanitize=$san -fpie'";
    }
  }
  $ithreads = undef if $multi;
  my $bindir = $c->config->{PERLALL_BINDIR};

  # XXX assert $p = $ps . $suffix;
  if ($c->options->{install}) {
    $c->stash->{logprefix} =~ s/^log.build-/log.build-install-/;
  }
  $c->stash->{log} = "$root/" . $c->stash->{logprefix} . $p;
  if ($c->stash->{log_fh}) {
    close $c->stash->{log_fh};
    undef $c->stash->{log_fh};
  }
  $c->_log(0,"perlall",_opts($c->options),"build",$p,$from);

  my $builddir = "build-".$p;
  if ($c->options->{install}) {
    $c->_system1( "chdir", $root.'/'.$builddir );
    $c->_check_lock();
    goto INSTALL;
  }
  # XXX maybe it already exists and is not empty
  if (-f $from or $from =~ /^https?:|ftp:|rsync:/) {
    warn "XXX build from file very very unstable.\n"
      .  "No idea how to know the resulting srcdir yet";
    if (!-f $from) {
      # try CPAN instead?
      $c->_system1( "wget","-O","perl-$ps.tgz",$from)
	and $c->_fail("downloading $from failed");
      $from = "perl-$ps.tgz";
    }
    my @tarx = (($^O eq 'solaris' ? 'gtar' : 'tar'),
		($from =~ m/\.bz2$/ ? 'xjf' : 'xzf' ));
    $c->_system1( @tarx, $from) and _fail("extracting the tarball $from failed");
    $srcdir = $root."/perl-$ps";
    if (! -d $builddir) {
      # OOPS LOOKS LIKE AN ERROR
      $c->_system("mkdir", $builddir)
	and $c->_fail("Cannot create $builddir."
		      ." Check your PERLALL_BUILDROOT in ~/.perlall");
    }
    $c->_system1( "chdir", $root.'/'.$builddir );
    $c->_check_lock();
  }
  else { # git, much better
    $c->_fail("perl-git $srcdir missing") if !-d $srcdir and !$dryrun;
    my @cmd = ("mkdir", $builddir);
    unshift @cmd, $sudo if $sudo and !-w $root;
    $c->_log(1,"mkdir $root/$builddir # PERLALL_BUILDROOT") unless -d $builddir;
    $c->_system1( @cmd) unless -d $builddir;
    $c->_fail( "invalid builddir $builddir") if !-d $builddir and !$dryrun;
    $c->_system($sudo, "chown", $<, $builddir) if $sudo eq $cmd[0];

    if ( $from eq 'blead' and $c->options->{link} ) { # mksymlink for blead only
      $c->debug("working symlinked to perl-git tree \@$gitsuffix")
	if $c->options->{link};
      $c->_system1( "chdir", $root.'/'.$builddir);
      $c->_fail( "not existing builddir $builddir")
	if basename(Cwd::getcwd()) ne $builddir and !$dryrun;
      $c->_check_lock();
      $c->_system1( "rm -rf * .config")
	if -f 'Configure' and !-l "Configure";

script/perlall  view on Meta::CPAN

  if ( $srcdir eq "." or $srcdir eq $root."/perl-$ps" ) {
    $c->_log('',"Devel::PatchPerl::patch_source($ps)");
    # TODO: monkeypatch Devel::PatchPerl to allow multiple plugins
    if ($asan or $c->options->{allpatches} or grep /^Asan$/, @{$c->options->{patches}}) {
      #require Devel::PatchPerl;
      #require Devel::PatchPerl::Plugin::General;
      #Devel::PatchPerl::General->patch_source($ps) unless $dryrun;
      $c->_log('',"Devel::PatchPerl::patch_source($ps) Asan");
      local $ENV{PERL5_PATCHPERL_PLUGIN} = 'Devel::PatchPerl::Plugin::Asan';
      Devel::PatchPerl::patch_source($ps) unless $dryrun;
      #require Devel::PatchPerl::Plugin::Asan;
      #Devel::PatchPerl::Plugin::Asan->patch_source($ps) unless $dryrun;
    }
    elsif ($c->options->{allpatches} or grep /^Compiler$/, @{$c->options->{patches}}) {
      #require Devel::PatchPerl;
      #require Devel::PatchPerl::Plugin::General;
      #Devel::PatchPerl::Plugin::General->patch_source($ps) unless $dryrun;
      local $ENV{PERL5_PATCHPERL_PLUGIN} = 'Devel::PatchPerl::Plugin::Compiler';
      $c->_log('',"Devel::PatchPerl::patch_source($ps) Compiler");
      Devel::PatchPerl::patch_source($ps) unless $dryrun;
      #require Devel::PatchPerl::Plugin::Compiler;
      #Devel::PatchPerl::Plugin::Compiler->patch_source($ps) unless $dryrun;
    }
    else {
      Devel::PatchPerl::patch_source($ps) unless $dryrun;
    }
    if ($ps =~ /^5\.19\.[3456789]/ and $debug) {
      local $ENV{PERL5_PATCHPERL_PLUGIN} = 'Devel::PatchPerl::Plugin::General';
      $c->_log('',"Devel::PatchPerl::patch_source($ps) General");
      Devel::PatchPerl::patch_source($ps) unless $dryrun;
    }
    if ($ps =~ /^5\.6\.2/) {
      $c->_log('',"patch to use 5.8.0 lib/File/Find.pm");
      $c->_system("git diff HEAD..perl-5.8.0 lib/File/Find.pm | patch -N -p1")
	and warn("patch HEAD..perl-5.8.0 lib/File/Find.pm had some errors\n");
    }
  } elsif (!$dryrun) {
    warn "Warning: Building -Dmksymlink with no Devel::PatchPerl patches applied.\n"
      ."Use --no-link if this fails.\n";
  }

  # on versions rf .git now
  if ( !$gitsuffix and -d ".git" and !$c->options->{debug}) {
    $c->_system1( $rm,"-rf",".git");
  }
  # $c->_system( $make, @j, "clean") if -f "Makefile" and -f 'miniperl';
  $c->_system( $rm, "config.h") if -f "config.h";
  $c->_system( $rm, "Policy.sh") if -f "Policy.sh";
  $c->_system( $rm, "-rf", "UU") if -d "UU";
  $c->_system( $rm, "-rf", ".config") if -d ".config";

  # prepare configure options, dependent on options and $p
  my @conf = ("sh","$srcdir/Configure","-de","-Dusedevel",
	      "-Uversiononly",
	      "-Dinstallman1dir=none","-Dinstallman3dir=none",
	      "-Dinstallsiteman1dir=none","-Dinstallsiteman3dir=none");
  # we cannot force archname, because we don't know the resulting name yet
  # we fix that post-configure
  my ($libperl);
  if ($c->config->{usethrsuffix} and !$multi) {
    $ithreads = $suffix =~ /^d?thr/; # perl5.14.2dthr
  }
  push @conf, "-Dmksymlinks" if $srcdir ne ".";
  push @conf, "-DEBUGGING" if $debug;
  push @conf, "-Doptimize='-g3'"
    if $debug and $Config{gccversion} and !grep(/^optimize=/, @{$c->options->{D}});
  push @conf, "-Dusemultiplicity" if $multi;
  if ($^O eq 'cygwin') { # fixed with 5.15.8 [perl #109968]
    push @conf, ($ithreads ? "-D" :"-U") . "usethreads";
  } else {
    push @conf, ($ithreads ? "-D" :"-U") . "useithreads";
  }
  push @conf, "-Uuseshrplib" # darwin cannot gdb step into shared libs, only lldb
    if $^O eq 'darwin' and $debug;
  push @conf, "-D'".$_."'" for @{$c->options->{D}};
  push @conf, "-A'".$_."'" for @{$c->options->{A}};
  push @conf, "-U'".$_."'" for @{$c->options->{U}};
  push @conf, "-Dprefix='$prefix'" if $prefix ne '/usr/local';
  # special *perl<xxx>.dll if non-default
  if ($^O =~ /cygwin|msys/ and $suffix) {
    if ($^O eq 'cygwin') {
      $libperl = $ps;
      $libperl =~ s/\./_/g;
      $libperl = 'cygperl'.$libperl.$suffix.'.dll';
      push @conf, "-Dlibperl=$libperl";
    } else {
      $libperl = $ps;
      $libperl =~ s/\.//g;
      $libperl = 'perl'.$libperl.$suffix.'.dll';
      push @conf, "-Dlibperl=$libperl";
    }
  }
  # ensure ldflags and lddflags -faddress-sanitizer on ccflags=-faddress-sanitizer
  # XXX this should go into darwin and linux hints somewhen
  if (grep /-[DA]'ccflags=.*-fsanitize=address/, @conf) {
    my $f = 'ldflags';
    if (!(grep /-[DA]'$f=.*-fsanitize=address/, @conf)) {
      push @conf, "-A'$f=$asan" . ($^O eq 'darwin' ? "\\ -Wl,-no_pie'" : "'");
    }
    $f = 'lddlflags';
    if (!(grep /-[DA]'$f=.*-fsanitize=address/, @conf)
	and !(grep /-U'?useshrplib/, @conf)) {
      push @conf,
        ($^O eq 'darwin' ? "-A'$f=-bundle\\ $asan\\ -Wl,-no_pie'"
	                 : "-A'$f=-shared\\ $asan'"),
	"-Duseshrplib";
    }
  }
  
  $c->_system( $rm, "config.sh") if -f "config.sh";
  $c->debug("config_args: ".join(" ",@conf));
  for my $tryperl ("$bindir/perl", "/usr/local/bin/perl", "/usr/bin/perl") {
    if (-e $tryperl) { # use tryperl as template and merge options
      # same overrides as with tryperl
      my $tryargs = `$tryperl -V:config_args`;
      $c->debug("old args: $tryargs");
      for my $f (qw(cc ld ccflags ldflags libpth incpth pager
		    cf_email perladmin))
      {
	next if grep /^$f[= ]/, @{$c->options->{D}}
	     or grep /^$f[= ]/, @{$c->options->{A}}
	     or grep /^$f[= ]/, @{$c->options->{U}};
	# -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -D
	my ($d,$v) = $tryargs =~ m/-([AUD])$f=(.+?) (?:-[ADU]|;)/; # Not until -L
	# check the
	if ($f =~ /^use/ and !$v) {
	  my ($u) = $tryargs =~ /-([DU])$f /;
	  $c->debug("-$u$f") if $u;
	  push @conf, "-$u$f" if $u;
	} elsif ($v and $d) {
	  $v =~ s/([^\\]) /$1\\ /g;

script/perlall  view on Meta::CPAN

    push @conf, "-Dd_Gconvert=sprintf";
  }
  # darwin: if -m32 or -m64 use -flat_namespace to avoid 2level
  if ($^O eq 'darwin') {
    my $conf = join(" ",@conf);
    # XXX change @conf, not add
    push @conf, "-Aldflags=-flat_namespace"
      if $conf =~ /ccflags='?-m64/ or $conf =~ /ccflags='?-m32/;
    # clang: use ld also
    # XXX: done automatically on linux. bother only for darwin
    push @conf, "-Dld=$cc" if $cc =~ /clang/;
    if ($c->_older($p,'5.6.2')) { # need to use 5.6.2 hints/darwin.sh
      #open F,">hints/darwin.sh";
      #close F;
    }
  }
  if ($^O eq 'msys') { # msys: mingw bootstrapping
    push @conf, "-Dlibc=/usr/lib.libmsys-1.0.dll.a", "-Dusenm=no";
  }
  if ($cc =~ /clang/) { # our macros are just too bad
    #if (grep /^-[DA]ccflags/, @conf) {
    push @conf, "-Accflags=-Wno-unused-value"; # this belongs into Configure and cflags.SH
    #}
  }

  if ($^O ne 'MSWin32') {
    $c->_system1( @conf);
    $c->_fail("Configure failed") unless -f 'config.sh' or $dryrun;
  } else {
    my ($w64, $config);
    my $aperl = $make eq 'nmake';
    $c->_system1("chdir","win32");
    # XXX check which config and makefile we will need
    my $makefile = $aperl ? 'Makefile' : 'makefile.mk';
    # XXX copy and tune config.h and Makefile (INST_DRV, INST_TOP)
    if ($ENV{WIN64}) { # XXX check if our compiler can do 64bit, else unset WIN64
      $w64++;
      warn "WIN64 not yet tested";
    }
    if ($w64) { $config = $aperl ? 'config.vc64' : 'config.gc64'; }
    else {$config = $aperl ? 'config.vc' : 'config.gc';}
    $c->_log(1,"win32 configure $config $make");
    $c->_system1($cp, $config, 'config.h');
    $dryrun = 1; # hack to skip post-configure patchups
  }
  $c->_log(1,"post-configure fixes");

  # fix libs on debug and git-stuff
  $archname = $dryrun ? "fake-arch"
    : $c->_grep("/^archname='(.+?)'\$/ and print \$1", "config.sh");
  my $new = $archname;
  for my $d (@{$c->options->{D}}) {
    if ($d =~ /^archname/) {
      $new = $d;
      $new =~ s/^archname=//;
      $new =~ s/'//g;
    }
  }
  if (($new ne $archname) or $archsuffix or $debug) {
    if ($new eq $archname) {
      if ($archname =~ /-thread-multi/ and !$c->_older($ps,"5.10.0")) {
        $new =~ s/-thread-multi/-thread/;
      }
      $new .= "-debug" if $debug and $archname !~ /-debug/;
      $new .= $archsuffix if $archsuffix and $archname !~ /$archsuffix$/;
      if (!$ithreads and $new =~ /-thread/) {
	$new =~ s/-thread//;
      } elsif ($ithreads and $new !~ /-thread/) {
	$new .= "-thread";
      }
    }
    $c->debug("post-configure archname fixes: $archname => $new");
    $c->_fail("archname not detected in config.sh") unless $archname;
    # This was very fragile: e.g. archname=darwin or mach
    # FIXME libpth was changed to /usr/lib/x86_64-linux-debug-gnu
    if ($archname and $archname ne $new) { # Time to make this stable
      $new =~ s/([\$\%\@])/\\$1/g;
      # which keys exactly? only those keys.
      # maybe redo the whole Configure step again
      $c->_grep("-i s|(\\d)/$archname'|\\1/$new'|;"
		. " s|(\\d)/$archname\"|\\1/$new\"|;"
		. " s|/$archname/CORE|/$new/CORE|;"
		. " s|define ARCHNAME \"$archname\"|define ARCHNAME \"$new\"|;"
		. " s|archname=$archname,|archname=$new,|;"
		. " s|archname='$archname'|archname='$new'|; print",
		qw(config.h config.sh Policy.sh myconfig));
    }
  }
  if (!$dryrun and $c->_older($p,'5.14')) { #seems to be <=5.6.2 only
    # remove archs from inc_version_list
    if ($c->_grep('m|inc_version_list.+(\d\.\d\d?\.\d\d?)/'.$archname.' | and print $1',
		  "config.sh")) {
      $c->debug("post-configure remove archlibs from inc_version_list");
      $c->_grep('-i s|(\d\.\d\d?\.\d\d?)/'.$archname.' ||;'
		. ' s|"(\d\.\d\d?\.\d\d?)/'.$archname.'",||;'
		. " print",
		qw(config.h config.sh));
    }
  }
  if ($archname and $archname ne $new) {
    $archname = $new;
  }

  if ($^O =~ /cygwin|msys/) {
    $c->debug("post-configure perl.dll fixes");
    # libperl really is libperl.a. Should be libperl.dll.a at least. we use the dll.
    my $dll = $dryrun ? "fake.dll"
      : $c->_grep("/^libperl='(.+?)'\$/ and print \$1", "config.sh");
    if ($libperl eq $dll) {
      $c->_log('',"configure did keep our libperl, good");
    } elsif ($libperl and $dll) {
      $libperl =~ s/([\.\$\%\@])/\\$1/g;
      $c->_grep("-i s,$dll,$libperl,; print",
		qw(config.sh config.h Makefile GNUmakefile myconfig));
      if ($^O eq 'cygwin') {
	$c->_grep("-i s,libperl='libperl\.a',libperl='$libperl',; print",
		  qw(config.sh));
	$c->_grep("-i s,libperl=libperl\.a,libperl=$libperl,; print",
		  qw(myconfig));
      }
    }
    if ($^O eq 'cygwin' and !$dryrun) {
      my $cygmk = 'cygwin/Makefile.SHs';
      my $dll = substr($libperl,0,-4);
      if ($c->_older($p,'5.8.9')) {
	if (-e $cygmk and $c->_grep("/^linklibperl=(-l)/ and print \$1", $cygmk)) {
	  $c->debug("post-configure LLIBPERL llibperl fixes");
	  $c->_grep("-i s/^LLIBPERL= \$linklibperl/DLLNAME= $dll/; print", $cygmk);
	  $c->_grep('-i s/^-o $(LIBPERL)$(DLSUFFIX)/-o $(DLLNAME)$(DLSUFFIX)/; print', $cygmk);



( run in 0.633 second using v1.01-cache-2.11-cpan-39bf76dae61 )