1*0Sstevel@tonic-gate#!/usr/perl5/5.8.4/bin/perl -T 2*0Sstevel@tonic-gate# 3*0Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc. All rights reserved. 4*0Sstevel@tonic-gate# Use is subject to license terms. 5*0Sstevel@tonic-gate# 6*0Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate# 8*0Sstevel@tonic-gate# This script builds and installs perl into the same location as when shipped 9*0Sstevel@tonic-gate# with ON. 10*0Sstevel@tonic-gate# This script should be run from within a perl source directory, 11*0Sstevel@tonic-gate# and needs to be setuid-root. 12*0Sstevel@tonic-gate# 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gateuse strict; 15*0Sstevel@tonic-gateuse warnings; 16*0Sstevel@tonic-gateuse POSIX qw(uname setuid); 17*0Sstevel@tonic-gateuse Cwd qw(abs_path); 18*0Sstevel@tonic-gateuse File::Find; 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate# Global config variables. 21*0Sstevel@tonic-gateour ($PerlPfx, $PerlArch, $PerlRel, $SolRel, $SolVer, $SolArch); 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate# Globals for File::Find callbacks below. 24*0Sstevel@tonic-gateour ($Start, $Fh); 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate# 27*0Sstevel@tonic-gate# File::Find callback for finding files touched after Start 28*0Sstevel@tonic-gate# and saving them in Fh. Uses globals $Start and $Fh. 29*0Sstevel@tonic-gate# 30*0Sstevel@tonic-gatesub touched 31*0Sstevel@tonic-gate{ 32*0Sstevel@tonic-gate my ($p, $f) = ($File::Find::dir, $_); 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate # Ignore directories and object files. 35*0Sstevel@tonic-gate return if (-d $f || $f =~ m{\.(?:a|o|so)$}); 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate $p =~ s{^\./?}{}; 38*0Sstevel@tonic-gate my $pf = $p eq '' ? $f : "$p/$f"; 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate # atime, mtime, ctime. 41*0Sstevel@tonic-gate my ($a, $m, $c) = (lstat($f))[8, 9, 10]; 42*0Sstevel@tonic-gate $a = $m if ($m > $a); 43*0Sstevel@tonic-gate $a = $c if ($c > $a); 44*0Sstevel@tonic-gate print $Fh ("$pf\n") if ($a >= $Start); 45*0Sstevel@tonic-gate} 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate# 48*0Sstevel@tonic-gate# File::Find callback for finding all .packlist files and saving their 49*0Sstevel@tonic-gate# contents in $Fh. Uses global $Fh. 50*0Sstevel@tonic-gate# 51*0Sstevel@tonic-gatesub cat_packlists 52*0Sstevel@tonic-gate{ 53*0Sstevel@tonic-gate my ($p, $f) = ($File::Find::dir, $_); 54*0Sstevel@tonic-gate # Ignore everything except .packlist files. 55*0Sstevel@tonic-gate return unless ($f eq '.packlist'); 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate $p =~ s{^\./?}{}; 58*0Sstevel@tonic-gate my $pf = $p eq '' ? $f : "$p/$f"; 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate # Open .packlist, save into $Fh. 61*0Sstevel@tonic-gate my $fh; 62*0Sstevel@tonic-gate open($fh, '<', $f) || die("Can't open $pf: $!\n"); 63*0Sstevel@tonic-gate while (defined(my $line = <$fh>)) { 64*0Sstevel@tonic-gate # Files only. 65*0Sstevel@tonic-gate next unless ($line =~ s/\s+type=file.*$//); 66*0Sstevel@tonic-gate $line =~ s{$PerlPfx/$PerlRel/}{}; 67*0Sstevel@tonic-gate print $Fh ($line) 68*0Sstevel@tonic-gate } 69*0Sstevel@tonic-gate close($fh); 70*0Sstevel@tonic-gate} 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate# 73*0Sstevel@tonic-gate# Main. 74*0Sstevel@tonic-gate# 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gatemy $config_only = @ARGV && $ARGV[0] eq '-c' ? 1 : 0; 77*0Sstevel@tonic-gatemy $fh; 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate# This is all rather dangerous... 80*0Sstevel@tonic-gatemy ($ruid, $euid, $rgid, $egid) = ($<, $>, $(, $)); 81*0Sstevel@tonic-gate$ENV{PATH} =~ s{:/usr/dist[^:]*}{}g; 82*0Sstevel@tonic-gate($ENV{PATH}) = $ENV{PATH} =~ /^(.*)$/; 83*0Sstevel@tonic-gatedelete($ENV{ENV}); 84*0Sstevel@tonic-gateif (! $config_only) { 85*0Sstevel@tonic-gate $) = $rgid; 86*0Sstevel@tonic-gate $> = $ruid; 87*0Sstevel@tonic-gate} 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate# Basic environment check. 90*0Sstevel@tonic-gatedie("Not a perl build directory\n") 91*0Sstevel@tonic-gate unless (-f 'Configure' && -f 'MANIFEST' && -f 'perl.c'); 92*0Sstevel@tonic-gatedie("Needs to be run as root or setuid root\n") 93*0Sstevel@tonic-gate unless ($config_only || $euid == 0); 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate# Prefix for perl installation. 96*0Sstevel@tonic-gate$PerlPfx = '/usr/perl5'; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate# Perl architecture. 99*0Sstevel@tonic-gate$PerlArch=qx{arch}; 100*0Sstevel@tonic-gate($PerlArch) = $PerlArch =~ /^(.*)\n$/; 101*0Sstevel@tonic-gate$PerlArch="${PerlArch}-solaris-64int"; 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate# Perl release. 104*0Sstevel@tonic-gatemy ($r, $v, $s); 105*0Sstevel@tonic-gateopen($fh, '<', 'patchlevel.h') || die("Can't open patchlevel.h: $!\n"); 106*0Sstevel@tonic-gatewhile (defined(my $line = <$fh>)) { 107*0Sstevel@tonic-gate ($line =~ /\bPERL_REVISION\s+(\d+)/) && ($r = $1); 108*0Sstevel@tonic-gate ($line =~ /\bPERL_VERSION\s+(\d+)/) && ($v = $1); 109*0Sstevel@tonic-gate ($line =~ /\bPERL_SUBVERSION\s+(\d+)/) && ($s = $1); 110*0Sstevel@tonic-gate last if (defined($r) && defined($v) && defined($s)); 111*0Sstevel@tonic-gate} 112*0Sstevel@tonic-gate$PerlRel = "$r.$v.$s"; 113*0Sstevel@tonic-gateundef($r); 114*0Sstevel@tonic-gateundef($v); 115*0Sstevel@tonic-gateundef($s); 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate# Solaris config. 118*0Sstevel@tonic-gate$SolRel = (uname())[2]; # Solaris Release. 119*0Sstevel@tonic-gate$SolVer = '2.' . substr($SolRel, 2); # Solaris Version. 120*0Sstevel@tonic-gate$SolArch = qx{uname -p}; # Solaris architecture. 121*0Sstevel@tonic-gatechomp($SolArch); 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate# Compiler and flags. 124*0Sstevel@tonic-gatemy $compiler1 = qx{exec ksh -e whence cc}; 125*0Sstevel@tonic-gatechomp($compiler1); 126*0Sstevel@tonic-gate$compiler1 =~ s{/bin/cc}{}; 127*0Sstevel@tonic-gatemy $compiler2 = abs_path($compiler1); 128*0Sstevel@tonic-gate$compiler1 = ' *' . $compiler1 . '[^ ]* *'; 129*0Sstevel@tonic-gate$compiler2 = ' *' . $compiler2 . '[^ ]* *'; 130*0Sstevel@tonic-gatemy $optimize='-xO3 -xspace -xildoff'; 131*0Sstevel@tonic-gatemy ($ccextraflags, $myuname); 132*0Sstevel@tonic-gateif ($SolArch eq 'sparc') { 133*0Sstevel@tonic-gate $ccextraflags='-xarch=v8'; 134*0Sstevel@tonic-gate $myuname="sunos localhost $SolRel sun4u sparc SUNW,Ultra-2"; 135*0Sstevel@tonic-gate} else { 136*0Sstevel@tonic-gate $ccextraflags=''; 137*0Sstevel@tonic-gate $myuname="sunos localhost $SolRel i86pc i386 i86pc"; 138*0Sstevel@tonic-gate} 139*0Sstevel@tonic-gate$ccextraflags .= " -D_TS_ERRNO"; 140*0Sstevel@tonic-gate$ccextraflags =~ s/\s\s+/ /g; 141*0Sstevel@tonic-gate$ccextraflags =~ s/^\s+//; 142*0Sstevel@tonic-gate$ccextraflags =~ s/\s+$//; 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate# Dmake parallelism. 145*0Sstevel@tonic-gatemy $DmakeJobs = 4; 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate# Clean up, delete any old configuration files. 148*0Sstevel@tonic-gatesystem('make realclean') if (-f 'Makefile'); 149*0Sstevel@tonic-gateunlink('config.sh') if (-f 'config.sh'); 150*0Sstevel@tonic-gateunlink('Policy.sh') if (-f 'Policy.sh'); 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate# Create the config.over file to override some common settings. 153*0Sstevel@tonic-gateopen($fh, '>', 'config.over') || die("Can't open config.over: $!\n"); 154*0Sstevel@tonic-gateprint $fh <<"EOF"; 155*0Sstevel@tonic-gateccflags=`echo \$ccflags | sed -e 's! *-I/usr/local/include *! !'` 156*0Sstevel@tonic-gateccflags="\$ccflags $ccextraflags" 157*0Sstevel@tonic-gateccversion='Sun WorkShop' 158*0Sstevel@tonic-gatecf_by='perl-bugs' 159*0Sstevel@tonic-gatecf_email='perl-bugs\@sun.com' 160*0Sstevel@tonic-gatecf_time='' 161*0Sstevel@tonic-gatecppflags='' 162*0Sstevel@tonic-gateinc_version_list='' 163*0Sstevel@tonic-gateinc_version_list_init='0' 164*0Sstevel@tonic-gateinstallusrbinperl='undef' 165*0Sstevel@tonic-gatelddlflags='-G' 166*0Sstevel@tonic-gateldflags='' 167*0Sstevel@tonic-gatelibpth='/lib /usr/lib /usr/ccs/lib' 168*0Sstevel@tonic-gatelibsdirs=`echo \$libsdirs | sed -e 's!$compiler1! !' -e 's!$compiler2! !'` 169*0Sstevel@tonic-gatelibsfound=`echo \$libsfound | sed -e 's!$compiler1! !' -e 's!$compiler2! !'` 170*0Sstevel@tonic-gatelibspath='/lib /usr/lib /usr/ccs/lib' 171*0Sstevel@tonic-gatelocincpth="/usr/sfw/include /opt/sfw/include \$locincpth" 172*0Sstevel@tonic-gateloclibpth=`echo \$loclibpth | sed -e 's!$compiler1! !' -e 's!$compiler2! !'` 173*0Sstevel@tonic-gateloclibpth="/usr/sfw/lib /opt/sfw/lib \$loclibpth" 174*0Sstevel@tonic-gatemake_set_make='#' 175*0Sstevel@tonic-gatemydomain='.sun.com' 176*0Sstevel@tonic-gatemyhostname='localhost' 177*0Sstevel@tonic-gatemyuname='$myuname' 178*0Sstevel@tonic-gateosvers='$SolVer' 179*0Sstevel@tonic-gatepager='/usr/bin/more' 180*0Sstevel@tonic-gateperl5='/bin/perl' 181*0Sstevel@tonic-gateperladmin='perl-bugs\@sun.com' 182*0Sstevel@tonic-gateEOF 183*0Sstevel@tonic-gateclose($fh); 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate# 186*0Sstevel@tonic-gate# Run Configure with the correct flags to give the required config files, 187*0Sstevel@tonic-gate# then remove the record of the Configure command-line and extra whitespace. 188*0Sstevel@tonic-gate# Finally, expand config.sh into the generated files used during the build. 189*0Sstevel@tonic-gate# Note: due to the fact that '-D' options confuse Configure, ccflags are 190*0Sstevel@tonic-gate# handled in config.over, above. 191*0Sstevel@tonic-gate# 192*0Sstevel@tonic-gatesystem <<"EOF"; 193*0Sstevel@tonic-gate./Configure -dsOE \\ 194*0Sstevel@tonic-gate -Duseshrplib -Uusemymalloc -Duse64bitint -Doptimize="$optimize" \\ 195*0Sstevel@tonic-gate -Dcc=cc \\ 196*0Sstevel@tonic-gate -Dprefix=$PerlPfx/$PerlRel \\ 197*0Sstevel@tonic-gate -Dprivlib=$PerlPfx/$PerlRel/lib \\ 198*0Sstevel@tonic-gate -Darchlib=$PerlPfx/$PerlRel/lib/$PerlArch \\ 199*0Sstevel@tonic-gate -Dsiteprefix=$PerlPfx/$PerlRel \\ 200*0Sstevel@tonic-gate -Dsitelib=$PerlPfx/site_perl/$PerlRel \\ 201*0Sstevel@tonic-gate -Dsitearch=$PerlPfx/site_perl/$PerlRel/$PerlArch \\ 202*0Sstevel@tonic-gate -Dvendorprefix=$PerlPfx/$PerlRel \\ 203*0Sstevel@tonic-gate -Dvendorlib=$PerlPfx/vendor_perl/$PerlRel \\ 204*0Sstevel@tonic-gate -Dvendorarch=$PerlPfx/vendor_perl/$PerlRel/$PerlArch \\ 205*0Sstevel@tonic-gate -Dman1dir=$PerlPfx/$PerlRel/man/man1 \\ 206*0Sstevel@tonic-gate -Dman3dir=$PerlPfx/$PerlRel/man/man3 \\ 207*0Sstevel@tonic-gate | 2>&1 tee configure.log 208*0Sstevel@tonic-gatesed -e "s/^config_args=.*/config_args=''/" \\ 209*0Sstevel@tonic-gate -e "s/^config_argc=.*/config_argc=0/" \\ 210*0Sstevel@tonic-gate -e "/^config_arg[1-9][0-9]*=/d" \\ 211*0Sstevel@tonic-gate -e "s/ threads threads\\/shared//" \\ 212*0Sstevel@tonic-gate -e "s/' */'/g" \\ 213*0Sstevel@tonic-gate -e "s/ *'/'/g" \\ 214*0Sstevel@tonic-gate config.sh > config.new 215*0Sstevel@tonic-gatemv config.new config.sh 216*0Sstevel@tonic-gateEOF 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate# Get the start time of the build. 219*0Sstevel@tonic-gate$Start = time(); 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate# Expand the configure-generated files. 222*0Sstevel@tonic-gatesystem <<"EOF" || die("Build failed\n"); 223*0Sstevel@tonic-gate./Configure -S | 2>&1 tee -a configure.log 224*0Sstevel@tonic-gateEOF 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate# Stop here if just configuring. 227*0Sstevel@tonic-gateexit(0) if ($config_only); 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate# Make and test perl. 230*0Sstevel@tonic-gatesystem <<"EOF" || die("Build failed\n"); 231*0Sstevel@tonic-gatedmake -j $DmakeJobs | 2>&1 tee make.log 232*0Sstevel@tonic-gate/usr/ccs/bin/make test | 2>&1 tee test.log 233*0Sstevel@tonic-gateEOF 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate# Find all files touched by the build & save in build.touched 236*0Sstevel@tonic-gateopen($Fh, '>', 'build.touched') || die("Can't open build.touched: $!\n"); 237*0Sstevel@tonic-gatefind({ wanted => \&touched, untaint => 1 }, '.'); 238*0Sstevel@tonic-gateclose($Fh); 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate# Install perl (needs to be root!) 241*0Sstevel@tonic-gate$( = $) = $egid; $< = $> = $euid; 242*0Sstevel@tonic-gatesystem <<"EOF"; 243*0Sstevel@tonic-gate/bin/rm -rf $PerlPfx/$PerlRel 244*0Sstevel@tonic-gate/usr/ccs/bin/make install 245*0Sstevel@tonic-gateEOF 246*0Sstevel@tonic-gate$) = $rgid; $> = $ruid; 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate# 249*0Sstevel@tonic-gate# Find all the .packlist files, cat them together 250*0Sstevel@tonic-gate# and save them in install.packlist 251*0Sstevel@tonic-gate# 252*0Sstevel@tonic-gateopen($Fh, '>', 'install.packlist') || die("Can't open install.packlist: $!\n"); 253*0Sstevel@tonic-gateprint $Fh ("PREFIX: $PerlPfx/$PerlRel\n"); 254*0Sstevel@tonic-gatefind({ wanted => \&cat_packlists, untaint => 1 }, "$PerlPfx/$PerlRel"); 255*0Sstevel@tonic-gateclose($Fh); 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gateexit(0); 258