1N/A#!/usr/perl5/5.8.4/bin/perl -T
1N/A#
1N/A# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
1N/A#
1N/A# This script builds and installs perl into the same location as when shipped
1N/A# with ON.
1N/A# This script should be run from within a perl source directory,
1N/A# and needs to be setuid-root.
1N/A#
1N/A
1N/Ause strict;
1N/Ause warnings;
1N/Ause POSIX qw(uname setuid);
1N/Ause Cwd qw(abs_path);
1N/Ause File::Find;
1N/A
1N/A# Global config variables.
1N/Aour ($PerlPfx, $PerlArch, $PerlRel, $SolRel, $SolVer, $SolArch);
1N/A
1N/A# Globals for File::Find callbacks below.
1N/Aour ($Start, $Fh);
1N/A
1N/A#
1N/A# File::Find callback for finding files touched after Start
1N/A# and saving them in Fh. Uses globals $Start and $Fh.
1N/A#
1N/Asub touched
1N/A{
1N/A my ($p, $f) = ($File::Find::dir, $_);
1N/A
1N/A # Ignore directories and object files.
1N/A return if (-d $f || $f =~ m{\.(?:a|o|so)$});
1N/A
1N/A $p =~ s{^\./?}{};
1N/A my $pf = $p eq '' ? $f : "$p/$f";
1N/A
1N/A # atime, mtime, ctime.
1N/A my ($a, $m, $c) = (lstat($f))[8, 9, 10];
1N/A $a = $m if ($m > $a);
1N/A $a = $c if ($c > $a);
1N/A print $Fh ("$pf\n") if ($a >= $Start);
1N/A}
1N/A
1N/A#
1N/A# File::Find callback for finding all .packlist files and saving their
1N/A# contents in $Fh. Uses global $Fh.
1N/A#
1N/Asub cat_packlists
1N/A{
1N/A my ($p, $f) = ($File::Find::dir, $_);
1N/A # Ignore everything except .packlist files.
1N/A return unless ($f eq '.packlist');
1N/A
1N/A $p =~ s{^\./?}{};
1N/A my $pf = $p eq '' ? $f : "$p/$f";
1N/A
1N/A # Open .packlist, save into $Fh.
1N/A my $fh;
1N/A open($fh, '<', $f) || die("Can't open $pf: $!\n");
1N/A while (defined(my $line = <$fh>)) {
1N/A # Files only.
1N/A next unless ($line =~ s/\s+type=file.*$//);
1N/A $line =~ s{$PerlPfx/$PerlRel/}{};
1N/A print $Fh ($line)
1N/A }
1N/A close($fh);
1N/A}
1N/A
1N/A#
1N/A# Main.
1N/A#
1N/A
1N/Amy $config_only = @ARGV && $ARGV[0] eq '-c' ? 1 : 0;
1N/Amy $fh;
1N/A
1N/A# This is all rather dangerous...
1N/Amy ($ruid, $euid, $rgid, $egid) = ($<, $>, $(, $));
1N/A$ENV{PATH} =~ s{:/usr/dist[^:]*}{}g;
1N/A($ENV{PATH}) = $ENV{PATH} =~ /^(.*)$/;
1N/Adelete($ENV{ENV});
1N/Aif (! $config_only) {
1N/A $) = $rgid;
1N/A $> = $ruid;
1N/A}
1N/A
1N/A# Basic environment check.
1N/Adie("Not a perl build directory\n")
1N/A unless (-f 'Configure' && -f 'MANIFEST' && -f 'perl.c');
1N/Adie("Needs to be run as root or setuid root\n")
1N/A unless ($config_only || $euid == 0);
1N/A
1N/A# Prefix for perl installation.
1N/A$PerlPfx = '/usr/perl5';
1N/A
1N/A# Perl architecture.
1N/A$PerlArch=qx{arch};
1N/A($PerlArch) = $PerlArch =~ /^(.*)\n$/;
1N/A$PerlArch="${PerlArch}-solaris-64int";
1N/A
1N/A# Perl release.
1N/Amy ($r, $v, $s);
1N/Aopen($fh, '<', 'patchlevel.h') || die("Can't open patchlevel.h: $!\n");
1N/Awhile (defined(my $line = <$fh>)) {
1N/A ($line =~ /\bPERL_REVISION\s+(\d+)/) && ($r = $1);
1N/A ($line =~ /\bPERL_VERSION\s+(\d+)/) && ($v = $1);
1N/A ($line =~ /\bPERL_SUBVERSION\s+(\d+)/) && ($s = $1);
1N/A last if (defined($r) && defined($v) && defined($s));
1N/A}
1N/A$PerlRel = "$r.$v.$s";
1N/Aundef($r);
1N/Aundef($v);
1N/Aundef($s);
1N/A
1N/A# Solaris config.
1N/A$SolRel = (uname())[2]; # Solaris Release.
1N/A$SolVer = '2.' . substr($SolRel, 2); # Solaris Version.
1N/A$SolArch = qx{uname -p}; # Solaris architecture.
1N/Achomp($SolArch);
1N/A
1N/A# Compiler and flags.
1N/Amy $compiler1 = qx{exec ksh -e whence cc};
1N/Achomp($compiler1);
1N/A$compiler1 =~ s{/bin/cc}{};
1N/Amy $compiler2 = abs_path($compiler1);
1N/A$compiler1 = ' *' . $compiler1 . '[^ ]* *';
1N/A$compiler2 = ' *' . $compiler2 . '[^ ]* *';
1N/Amy $optimize='-xO3 -xspace -xildoff';
1N/Amy ($ccextraflags, $myuname);
1N/Aif ($SolArch eq 'sparc') {
1N/A $ccextraflags='-xarch=v8';
1N/A $myuname="sunos localhost $SolRel sun4u sparc SUNW,Ultra-2";
1N/A} else {
1N/A $ccextraflags='';
1N/A $myuname="sunos localhost $SolRel i86pc i386 i86pc";
1N/A}
1N/A$ccextraflags .= " -D_TS_ERRNO";
1N/A$ccextraflags =~ s/\s\s+/ /g;
1N/A$ccextraflags =~ s/^\s+//;
1N/A$ccextraflags =~ s/\s+$//;
1N/A
1N/A# Dmake parallelism.
1N/Amy $DmakeJobs = 4;
1N/A
1N/A# Clean up, delete any old configuration files.
1N/Asystem('make realclean') if (-f 'Makefile');
1N/Aunlink('config.sh') if (-f 'config.sh');
1N/Aunlink('Policy.sh') if (-f 'Policy.sh');
1N/A
1N/A# Create the config.over file to override some common settings.
1N/Aopen($fh, '>', 'config.over') || die("Can't open config.over: $!\n");
1N/Aprint $fh <<"EOF";
1N/Accflags=`echo \$ccflags | sed -e 's! *-I/usr/local/include *! !'`
1N/Accflags="\$ccflags $ccextraflags"
1N/Accversion='Sun WorkShop'
1N/Acf_by='perl-bugs'
1N/Acf_email='perl-bugs\@sun.com'
1N/Acf_time=''
1N/Acppflags=''
1N/Ainc_version_list=''
1N/Ainc_version_list_init='0'
1N/Ainstallusrbinperl='undef'
1N/Alddlflags='-G'
1N/Aldflags=''
1N/Alibpth='/lib /usr/lib'
1N/Alibsdirs=`echo \$libsdirs | sed -e 's!$compiler1! !' -e 's!$compiler2! !'`
1N/Alibsfound=`echo \$libsfound | sed -e 's!$compiler1! !' -e 's!$compiler2! !'`
1N/Alibspath='/lib /usr/lib'
1N/Alocincpth="/usr/sfw/include /opt/sfw/include \$locincpth"
1N/Aloclibpth=`echo \$loclibpth | sed -e 's!$compiler1! !' -e 's!$compiler2! !'`
1N/Aloclibpth="/usr/sfw/lib /opt/sfw/lib \$loclibpth"
1N/Amake_set_make='#'
1N/Amydomain='.sun.com'
1N/Amyhostname='localhost'
1N/Amyuname='$myuname'
1N/Aosvers='$SolVer'
1N/Apager='/usr/bin/more'
1N/Aperl5='/bin/perl'
1N/Aperladmin='perl-bugs\@sun.com'
1N/AEOF
1N/Aclose($fh);
1N/A
1N/A#
1N/A# Run Configure with the correct flags to give the required config files,
1N/A# then remove the record of the Configure command-line and extra whitespace.
1N/A# Finally, expand config.sh into the generated files used during the build.
1N/A# Note: due to the fact that '-D' options confuse Configure, ccflags are
1N/A# handled in config.over, above.
1N/A#
1N/Asystem <<"EOF";
1N/A./Configure -dsOE \\
1N/A -Duseshrplib -Uusemymalloc -Duse64bitint -Doptimize="$optimize" \\
1N/A -Dcc=cc \\
1N/A -Dprefix=$PerlPfx/$PerlRel \\
1N/A -Dprivlib=$PerlPfx/$PerlRel/lib \\
1N/A -Darchlib=$PerlPfx/$PerlRel/lib/$PerlArch \\
1N/A -Dsiteprefix=$PerlPfx/$PerlRel \\
1N/A -Dsitelib=$PerlPfx/site_perl/$PerlRel \\
1N/A -Dsitearch=$PerlPfx/site_perl/$PerlRel/$PerlArch \\
1N/A -Dvendorprefix=$PerlPfx/$PerlRel \\
1N/A -Dvendorlib=$PerlPfx/vendor_perl/$PerlRel \\
1N/A -Dvendorarch=$PerlPfx/vendor_perl/$PerlRel/$PerlArch \\
1N/A -Dman1dir=$PerlPfx/$PerlRel/man/man1 \\
1N/A -Dman3dir=$PerlPfx/$PerlRel/man/man3 \\
1N/A | 2>&1 tee configure.log
1N/Ased -e "s/^config_args=.*/config_args=''/" \\
1N/A -e "s/^config_argc=.*/config_argc=0/" \\
1N/A -e "/^config_arg[1-9][0-9]*=/d" \\
1N/A -e "s/ threads threads\\/shared//" \\
1N/A -e "s/' */'/g" \\
1N/A -e "s/ *'/'/g" \\
1N/A config.sh > config.new
1N/Amv config.new config.sh
1N/AEOF
1N/A
1N/A# Get the start time of the build.
1N/A$Start = time();
1N/A
1N/A# Expand the configure-generated files.
1N/Asystem <<"EOF" || die("Build failed\n");
1N/A./Configure -S | 2>&1 tee -a configure.log
1N/AEOF
1N/A
1N/A# Stop here if just configuring.
1N/Aexit(0) if ($config_only);
1N/A
1N/A# Make and test perl.
1N/Asystem <<"EOF" || die("Build failed\n");
1N/Admake -j $DmakeJobs | 2>&1 tee make.log
1N/A/usr/bin/make test | 2>&1 tee test.log
1N/AEOF
1N/A
1N/A# Find all files touched by the build & save in build.touched
1N/Aopen($Fh, '>', 'build.touched') || die("Can't open build.touched: $!\n");
1N/Afind({ wanted => \&touched, untaint => 1 }, '.');
1N/Aclose($Fh);
1N/A
1N/A# Install perl (needs to be root!)
1N/A$( = $) = $egid; $< = $> = $euid;
1N/Asystem <<"EOF";
1N/A/bin/rm -rf $PerlPfx/$PerlRel
1N/A/usr/bin/make install
1N/AEOF
1N/A$) = $rgid; $> = $ruid;
1N/A
1N/A#
1N/A# Find all the .packlist files, cat them together
1N/A# and save them in install.packlist
1N/A#
1N/Aopen($Fh, '>', 'install.packlist') || die("Can't open install.packlist: $!\n");
1N/Aprint $Fh ("PREFIX: $PerlPfx/$PerlRel\n");
1N/Afind({ wanted => \&cat_packlists, untaint => 1 }, "$PerlPfx/$PerlRel");
1N/Aclose($Fh);
1N/A
1N/Aexit(0);