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