1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/perl-openpkg/perl-openpkg.pl Thu Sep 15 19:31:49 2011 +0200 1.3 @@ -0,0 +1,773 @@ 1.4 +#!@l_prefix@/bin/perl -w 1.5 +## 1.6 +## perl-openpkg -- OpenPKG Perl Module Build Utility 1.7 +## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/> 1.8 +## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/> 1.9 +## 1.10 +## Permission to use, copy, modify, and distribute this software for 1.11 +## any purpose with or without fee is hereby granted, provided that 1.12 +## the above copyright notice and this permission notice appear in all 1.13 +## copies. 1.14 +## 1.15 +## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 1.16 +## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1.17 +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.18 +## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR 1.19 +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.20 +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.21 +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 1.22 +## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1.23 +## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 1.24 +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 1.25 +## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.26 +## SUCH DAMAGE. 1.27 +## 1.28 + 1.29 +require 5; 1.30 +use strict; 1.31 +use Getopt::Long; 1.32 +use IO qw(Handle Seekable File Pipe Socket Dir); 1.33 + 1.34 +# program information 1.35 +my $ME = { 1.36 + prog_path => $0, 1.37 + prog_name => "perl-openpkg", 1.38 + prog_vers => "2.0.1", 1.39 + prog_date => "03-Dec-2004" 1.40 +}; 1.41 + 1.42 +# program configuration 1.43 +my $CF = { 1.44 + path_prefix => '@l_prefix@', 1.45 + path_libdir => "", 1.46 + path_tmpdir => ($ENV{"TMPDIR"} || "/tmp"), 1.47 + path_wrkdir => "", 1.48 + path_buildroot => ($ENV{"RPM_BUILD_ROOT"} || ""), 1.49 + path_buildwork => ($ENV{"RPM_BUILD_DIR"} || ""), 1.50 + pkg_name => ($ENV{"RPM_PACKAGE_NAME"} || ""), 1.51 + perl_schema => "vendor", 1.52 + perl_args => [], 1.53 + perl_stdin => "/dev/null", 1.54 + files_file => "-", 1.55 + files_unquoted => 0, 1.56 + prog_rpm => '%path_prefix%/libexec/openpkg/rpm', 1.57 + prog_perl => '%path_prefix%/bin/perl', 1.58 + mode_quiet => 0, 1.59 + mode_verbose => 0, 1.60 + run_version => 0, 1.61 + run_help => 0, 1.62 +}; 1.63 + 1.64 +# cleanup support 1.65 +my @cleanup = (); 1.66 +sub cleanup_remember { 1.67 + my ($cmd) = @_; 1.68 + push(@cleanup, $cmd); 1.69 +} 1.70 +sub cleanup_perform { 1.71 + foreach my $cmd (reverse @cleanup) { 1.72 + &runcmd($cmd); 1.73 + } 1.74 +} 1.75 + 1.76 +# exception handling support 1.77 +$SIG{__DIE__} = sub { 1.78 + my ($err) = @_; 1.79 + $err =~ s|\s+at\s+.*||s if (not $CF->{mode_verbose}); 1.80 + print STDERR "$ME->{prog_name}:ERROR: $err ". ($! ? "($!)" : "") . "\n"; 1.81 + &cleanup_perform() if (not $CF->{mode_verbose}); 1.82 + exit(1); 1.83 +}; 1.84 + 1.85 +# verbose message printing 1.86 +sub verbose { 1.87 + my ($msg) = @_; 1.88 + print STDERR "++ $msg\n" if (not $CF->{mode_quiet}); 1.89 +} 1.90 + 1.91 +# expand into a full filesystem path 1.92 +sub fullpath { 1.93 + my ($prog) = @_; 1.94 + my $fullprog = ''; 1.95 + foreach my $path (split(/:/, $ENV{PATH})) { 1.96 + if (-x "$path/$prog") { 1.97 + $fullprog = "$path/$prog"; 1.98 + last; 1.99 + } 1.100 + } 1.101 + return $fullprog; 1.102 +} 1.103 + 1.104 +# execution of external commands 1.105 +sub runcmd { 1.106 + my ($cmd) = @_; 1.107 + print STDERR "\$ $cmd\n" if ($CF->{mode_verbose}); 1.108 + $cmd = "($cmd) >/dev/null 2>&1" if ($CF->{mode_quiet}); 1.109 + return (system($cmd) == 0); 1.110 +} 1.111 + 1.112 +# create a directory (plus its missing parent dirs) 1.113 +sub mkdirp { 1.114 + my ($dir) = @_; 1.115 + my $pdir = $dir; 1.116 + $pdir =~ s|/[^/]*$||s; 1.117 + if (not -d $pdir) { 1.118 + &mkdirp($pdir, 0755); 1.119 + } 1.120 + if (not -d $dir) { 1.121 + &runcmd("umask 022 && mkdir $dir"); 1.122 + } 1.123 +} 1.124 + 1.125 +# command line parsing 1.126 +Getopt::Long::Configure("bundling"); 1.127 +my $result = GetOptions( 1.128 + 'p|prefix=s' => \$CF->{path_prefix}, 1.129 + 'l|libdir=s' => \$CF->{path_libdir}, 1.130 + 't|tmpdir=s' => \$CF->{path_tmpdir}, 1.131 + 'd|wrkdir=s' => \$CF->{path_wrkdir}, 1.132 + 'r|buildroot=s' => \$CF->{path_buildroot}, 1.133 + 'w|buildwork=s' => \$CF->{path_buildwork}, 1.134 + 'R|rpm=s' => \$CF->{prog_rpm}, 1.135 + 'P|perl=s' => \$CF->{prog_perl}, 1.136 + 's|schema=s' => \$CF->{perl_schema}, 1.137 + 'A|args=s' => \@{$CF->{perl_args}}, 1.138 + 'I|stdin=s' => \$CF->{perl_stdin}, 1.139 + 'F|files=s' => \$CF->{files_file}, 1.140 + 'U|unquoted' => \$CF->{files_unquoted}, 1.141 + 'n|pkgname=s' => \$CF->{pkg_name}, 1.142 + 'q|quiet' => \$CF->{mode_quiet}, 1.143 + 'v|verbose' => \$CF->{mode_verbose}, 1.144 + 'V|version' => \$CF->{run_version}, 1.145 + 'h|help' => \$CF->{run_help} 1.146 +) || die "option parsing failed"; 1.147 +if ($CF->{run_help}) { 1.148 + print "Usage: $ME->{prog_name} [options]\n" . 1.149 + "Available options:\n" . 1.150 + "\n" . 1.151 + " -p, --prefix <dir-path> filesystem path to OpenPKG instance\n" . 1.152 + " -l, --libdir <dir-path> filesystem path to Perl lib directory\n" . 1.153 + " -t, --tmpdir <dir-path> filesystem path to temporary directory\n" . 1.154 + " -d, --wrkdir <dir-path> filesystem path to working directory\n" . 1.155 + " -r, --buildroot <dir-path> filesystem path to RPM build root directory\n" . 1.156 + " -w, --buildwork <dir-path> filesystem path to RPM build work directory\n" . 1.157 + " -R, --rpm <file-path> filesystem path to RPM program\n" . 1.158 + " -P, --perl <file-path> filesystem path to Perl program\n" . 1.159 + "\n" . 1.160 + " -s, --schema <schema> Perl INSTALLDIRS schema\n" . 1.161 + " -A, --args <arguments> Perl Build.PL/Makefile.PL passed through arguments\n" . 1.162 + " -I, --stdin <file-path> filesystem path to connect to stdin\n" . 1.163 + " -F, --files <file-path> filesystem path to write RPM \%files list to\n" . 1.164 + " -U, --unquoted output RPM \%files list in unquoted format\n" . 1.165 + " -n, --pkgname <package-name> name of involved RPM package\n" . 1.166 + "\n" . 1.167 + " -q, --quiet operate in quiet run-time mode\n" . 1.168 + " -v, --verbose operate in verbose run-time mode\n" . 1.169 + "\n" . 1.170 + " -V, --version print out program version\n" . 1.171 + " -h, --help print out program usage help\n"; 1.172 + exit(0); 1.173 +} 1.174 +if ($CF->{run_version}) { 1.175 + print "OpenPKG $ME->{prog_name} $ME->{prog_vers} ($ME->{prog_date})\n"; 1.176 + exit(0); 1.177 +} 1.178 + 1.179 +# fix configuration parameters 1.180 +foreach my $cf (keys(%{$CF})) { 1.181 + $CF->{$cf} =~ s|\%([A-Za-z_][A-Za-z0-9_]*)\%|$CF->{$1}|sge; 1.182 +} 1.183 + 1.184 +# determine operation steps 1.185 +my @steps_exist = qw(prepare configure build install fixate cleanup); 1.186 +my @steps_run = (); 1.187 +if (@ARGV > 0) { 1.188 + foreach my $step (@ARGV) { 1.189 + if (not grep { $_ eq $step } @steps_exist) { 1.190 + die "operation step \"$step\" not existing"; 1.191 + } 1.192 + push(@steps_run, $step); 1.193 + } 1.194 + my $steps_exist = "-".join("-", @steps_exist)."-"; 1.195 + my $steps_run = "-".join("-", @steps_run)."-"; 1.196 + if ($steps_exist !~ m|^.*${steps_run}.*$|s) { 1.197 + die "invalid operation step order \"".join(" ", @ARGV)."\""; 1.198 + } 1.199 +} 1.200 +else { 1.201 + @steps_run = @steps_exist; 1.202 +} 1.203 + 1.204 +# friendly header ;-) 1.205 +&verbose("OpenPKG $ME->{prog_name} $ME->{prog_vers} ($ME->{prog_date})"); 1.206 + 1.207 +# determine RPM program 1.208 +if (not -x $CF->{prog_rpm}) { 1.209 + $CF->{prog_rpm} = &fullpath($CF->{prog_rpm}); 1.210 +} 1.211 +my $V = `$CF->{prog_rpm} --version 2>/dev/null`; 1.212 +$V =~ s/^(?:rpm \(OpenPKG RPM\)|RPM version|OpenPKG RPM|rpm\s+\(.+?\))\s+([0-9ab.]+)(\.(?:SNAPSHOT|DEVEL).*)?\s*$/$1/s || 1.213 + die "program '$CF->{prog_rpm}' seems to be not RPM"; 1.214 +&verbose("determined RPM program: $CF->{prog_rpm} ($V)"); 1.215 + 1.216 +# determine Perl program 1.217 +if (not -x $CF->{prog_perl}) { 1.218 + $CF->{prog_perl} = &fullpath($CF->{prog_perl}); 1.219 +} 1.220 +$V = `$CF->{prog_perl} --version 2>/dev/null`; 1.221 +$V =~ s|^.*This is perl.+v?(5\.[\d+.]+).*$|$1|s || 1.222 + die "program '$CF->{prog_perl}' seems to be not Perl"; 1.223 +&verbose("determined Perl program: $CF->{prog_perl} ($V)"); 1.224 + 1.225 +# check for existing paths 1.226 +if ($CF->{path_buildroot} eq '') { 1.227 + die "RPM build root directory not known (specify one with option --buildroot)"; 1.228 +} 1.229 +if ($CF->{path_buildwork} eq '') { 1.230 + die "RPM build work directory not known (specify one with option --buildwork)"; 1.231 +} 1.232 +mkdir($CF->{path_buildroot}, 0700); 1.233 +mkdir($CF->{path_buildwork}, 0700); 1.234 + 1.235 +## 1.236 +## OPERATION SEQUENCE 1.237 +## 1.238 + 1.239 +# establish standard environment 1.240 +umask(022); 1.241 + 1.242 +# determine name of temporary directory 1.243 +my $tmpdir = $CF->{path_tmpdir}; 1.244 +$tmpdir =~ s|/+$||s; 1.245 +my $user = (getlogin() || getpwuid($<) || $ENV{LOGNAME} || $ENV{USERNAME} || "unknown"); 1.246 +my $program = $ME->{prog_name}; 1.247 +my $package = ($CF->{pkg_name} || "unknown"); 1.248 +$tmpdir .= "/$user-$program-$package"; 1.249 + 1.250 +# determine name of perl wrapper script 1.251 +my $perlwrap = "$tmpdir/perl.sh"; 1.252 + 1.253 +# optionally change working directory 1.254 +my $dir = $CF->{path_wrkdir}; 1.255 +if ($dir ne '') { 1.256 + if (not -d $dir) { 1.257 + # be smart and guess correct directory to 1.258 + # reduce special cases during packaging 1.259 + $dir =~ s|^.+/||s; 1.260 + my $parent = ""; 1.261 + my $child = $dir; 1.262 + $child =~ s|^(.+/)([^/]+)$|$parent = $1, $2|se; 1.263 + LOOP: while ($child ne '') { 1.264 + foreach my $dir (glob("${parent}${child}*")) { 1.265 + if (-d "$parent$dir") { 1.266 + $child = $dir; 1.267 + last LOOP; 1.268 + } 1.269 + } 1.270 + $child =~ s|\W\w+$||s || last; 1.271 + last if (-d "$parent$child"); 1.272 + } 1.273 + $dir = "$parent$child"; 1.274 + } 1.275 + chdir($dir) || die "cannot change to working directory \"$dir\""; 1.276 +} 1.277 + 1.278 +# determine Perl configuration 1.279 +my $pcfg = {}; 1.280 +my $cmd = "$CF->{prog_perl}" . 1.281 + " -V:installarchlib -V:installprivlib" . 1.282 + " -V:installsitearch -V:installsitelib -V:sitelib_stem" . 1.283 + " -V:installvendorarch -V:installvendorlib -V:vendorlib_stem"; 1.284 +my $out = `$cmd 2>/dev/null || true`; 1.285 +$out =~ s|^(\S+)='([^'']*)';$|$pcfg->{$1} = $2, ''|mge; 1.286 + 1.287 +# ==== COMPAT prolog/epilog ==== 1.288 +if (grep { $_ eq "prolog" or $_ eq "epilog" } @steps_run) { 1.289 + print "This is the perl-openpkg >= 20040126 version.\n" . 1.290 + "It was redesigned and is incompatible to previous\n" . 1.291 + "versions. It does not support prolog/epilog steps.\n" . 1.292 + "Please upgrade the package that uses perl-openpkg\n" . 1.293 + "or, as a temporary workaround, downgrade perl-openpkg\n"; 1.294 + die "package/perl-openpkg incompatiblity"; 1.295 +} 1.296 + 1.297 +# ==== STEP: 1. prepare ==== 1.298 +if (grep { $_ eq "prepare" } @steps_run) { 1.299 + &verbose("step 1: prepare"); 1.300 + 1.301 + # establish temporary directory 1.302 + system("rm -rf $tmpdir >/dev/null 2>&1"); 1.303 + mkdir($tmpdir, 0700) || die "cannot create temporary directory '$tmpdir'"; 1.304 + 1.305 + # create Perl executable wrapper script 1.306 + my $io = new IO::File ">$perlwrap" 1.307 + || die "unable to open \"$perlwrap\" for writing"; 1.308 + print $io 1.309 + "#!/bin/sh\n" . 1.310 + "exec $CF->{prog_perl} \\\n" . 1.311 + " -I$CF->{path_buildroot}$pcfg->{installarchlib} \\\n" . 1.312 + " -I$CF->{path_buildroot}$pcfg->{installprivlib} \\\n" . 1.313 + " -I$CF->{path_buildroot}$pcfg->{installsitearch} \\\n" . 1.314 + " -I$CF->{path_buildroot}$pcfg->{installsitelib} \\\n" . 1.315 + " -I$CF->{path_buildroot}$pcfg->{installvendorarch} \\\n" . 1.316 + " -I$CF->{path_buildroot}$pcfg->{installvendorlib} \\\n" . 1.317 + " \"\$@\"\n"; 1.318 + $io->close(); 1.319 + &runcmd("chmod 755 $perlwrap"); 1.320 + 1.321 + # establish Perl module installation areas 1.322 + &mkdirp("$CF->{path_buildroot}$pcfg->{installarchlib}"); 1.323 + &mkdirp("$CF->{path_buildroot}$pcfg->{installprivlib}"); 1.324 + &mkdirp("$CF->{path_buildroot}$pcfg->{installsitearch}"); 1.325 + &mkdirp("$CF->{path_buildroot}$pcfg->{installsitelib}"); 1.326 + &mkdirp("$CF->{path_buildroot}$pcfg->{installvendorarch}"); 1.327 + &mkdirp("$CF->{path_buildroot}$pcfg->{installvendorlib}"); 1.328 +} 1.329 + 1.330 +# ==== STEP: 2. configure ==== 1.331 +if (grep { $_ eq "configure" } @steps_run) { 1.332 + &verbose("step 2: configure"); 1.333 + 1.334 + # determine build environment and basic arguments 1.335 + my $environment = ""; 1.336 + my $perl_args = ''; 1.337 + if (-f "Build.PL" and (system("$perlwrap -MModule::Build -e '1;' >/dev/null 2>&1") >> 8) == 0) { 1.338 + # new-style Module::Build "Build.PL" 1.339 + $perl_args .= " installdirs=$CF->{perl_schema}"; 1.340 + $perl_args .= " --install_path libdoc=remove-me-later"; 1.341 + $perl_args .= " destdir=$CF->{path_buildroot}"; 1.342 + if ($CF->{path_prefix} ne '' and $CF->{path_prefix} ne '@l_prefix@') { 1.343 + $perl_args .= " install_base=$CF->{path_prefix}"; 1.344 + } 1.345 + if ($CF->{path_libdir} ne '') { 1.346 + $perl_args .= " --install_path lib=$CF->{path_libdir}"; 1.347 + } 1.348 + $environment = 'Module::Build'; 1.349 + } 1.350 + elsif (-f "Makefile.PL") { # ExtUtils::MakeMaker is part of the Perl distribution 1.351 + # old-style ExtUtils::MakeMaker "Makefile.PL" 1.352 + $perl_args .= " PERL=$perlwrap FULLPERL=$perlwrap"; 1.353 + $perl_args .= " INSTALLDIRS=$CF->{perl_schema}"; 1.354 + $perl_args .= " INSTALLMAN3DIR=none INSTALLSITEMAN3DIR=none INSTALLVENDORMAN3DIR=none"; 1.355 + $perl_args .= " DESTDIR=$CF->{path_buildroot}"; 1.356 + if ($CF->{path_prefix} ne '' and $CF->{path_prefix} ne '@l_prefix@') { 1.357 + $perl_args .= " PREFIX=$CF->{path_prefix}"; 1.358 + } 1.359 + if ($CF->{path_libdir} ne '') { 1.360 + $perl_args .= " LIB=$CF->{path_libdir}"; 1.361 + } 1.362 + $environment = 'ExtUtils::MakeMaker'; 1.363 + } 1.364 + else { 1.365 + die "neither usable Module::Build \"Build.PL\" nor ExtUtils::MakeMaker \"Makefile.PL\" file found"; 1.366 + } 1.367 + 1.368 + # determine build-time extra arguments 1.369 + # (assuming that they are either work for both Module::Build and 1.370 + # ExtUtils::MakeMaker or the supplier knows what is used by us) 1.371 + if ($#{$CF->{perl_args}} >= 0) { 1.372 + my $user_args = join(" ", @{$CF->{perl_args}}); 1.373 + if ($user_args =~ m|#|) { 1.374 + $user_args =~ s|#| $perl_args |; 1.375 + $perl_args = $user_args; 1.376 + } 1.377 + else { 1.378 + $perl_args .= " " . $user_args; 1.379 + } 1.380 + } 1.381 + 1.382 + # determine stdin 1.383 + if ($CF->{perl_stdin} ne "-") { 1.384 + $perl_args .= " <$CF->{perl_stdin}"; 1.385 + } 1.386 + 1.387 + # setup the build environment 1.388 + if ($environment eq 'Module::Build') { 1.389 + &verbose("configuring module via Module::Build environment"); 1.390 + &runcmd("chmod u+rw Build.PL"); 1.391 + &runcmd("cp Build.PL Build.PL.orig"); 1.392 + &runcmd("(cat Build.PL.orig; echo '') | sed -e \"s:\\\$^X:'$perlwrap':g\" >Build.PL"); 1.393 + &runcmd("$perlwrap ./Build.PL $perl_args") 1.394 + or die "failed to \"configure\""; 1.395 + } 1.396 + elsif ($environment eq 'ExtUtils::MakeMaker') { 1.397 + &verbose("configuring module via ExtUtils::MakeMaker environment"); 1.398 + &runcmd("chmod u+rw Makefile.PL"); 1.399 + &runcmd("cp Makefile.PL Makefile.PL.orig"); 1.400 + &runcmd("(cat Makefile.PL.orig; echo '') | sed -e \"s:\\\$^X:'$perlwrap':g\" >Makefile.PL"); 1.401 + &runcmd("$perlwrap ./Makefile.PL $perl_args") 1.402 + or die "failed to \"configure\""; 1.403 + } 1.404 +} 1.405 + 1.406 +# ==== STEP: 3. build ==== 1.407 +if (grep { $_ eq "build" } @steps_run) { 1.408 + &verbose("step 3: build"); 1.409 + 1.410 + if (-f "Build.PL" and -f "Build") { 1.411 + # execute Build script 1.412 + &verbose("building module via Module::Build environment"); 1.413 + &runcmd("$perlwrap Build build") 1.414 + or die "failed to \"build\""; 1.415 + } 1.416 + elsif (-f "Makefile.PL" and -f "Makefile") { 1.417 + # execute Makefile procedure 1.418 + &verbose("building module via ExtUtils::MakeMaker environment"); 1.419 + my $make = `$CF->{prog_rpm} --eval '\%{l_make} \%{l_mflags}'`; 1.420 + $make =~ s|\n+$||s; 1.421 + my $make_args = "PERL=$perlwrap FULLPERL=$perlwrap"; 1.422 + &runcmd("$make $make_args pure_all") 1.423 + or die "failed to \"build\""; 1.424 + } 1.425 + else { 1.426 + die "neither \"Build\" nor \"Makefile\" found in working directory"; 1.427 + } 1.428 +} 1.429 + 1.430 +# ==== STEP: 4. install ==== 1.431 +if (grep { $_ eq "install" } @steps_run) { 1.432 + &verbose("step 4: install"); 1.433 + 1.434 + if (-f "Build.PL" and -f "Build") { 1.435 + # execute Build script 1.436 + &verbose("installing module via Module::Build environment"); 1.437 + &runcmd("$perlwrap Build install") 1.438 + or die "failed to \"install\""; 1.439 + &runcmd("rm -rf $CF->{path_buildroot}$CF->{path_prefix}/remove-me-later"); 1.440 + } 1.441 + elsif (-f "Makefile.PL" and -f "Makefile") { 1.442 + # execute Makefile procedure 1.443 + &verbose("installing module via ExtUtils::MakeMaker environment"); 1.444 + my $make = `$CF->{prog_rpm} --eval '\%{l_make} \%{l_mflags}'`; 1.445 + $make =~ s|\n+$||s; 1.446 + my $make_args = "PERL=$perlwrap FULLPERL=$perlwrap"; 1.447 + &runcmd("$make $make_args pure_install") 1.448 + or die "failed to \"install\""; 1.449 + } 1.450 + else { 1.451 + die "neither \"Build\" nor \"Makefile\" found in working directory"; 1.452 + } 1.453 +} 1.454 + 1.455 +# ==== STEP: 5. fixate ==== 1.456 +if (grep { $_ eq "fixate" } @steps_run) { 1.457 + &verbose("step 5: fixate"); 1.458 + 1.459 + # prune installation files 1.460 + my $libdir; 1.461 + if ($CF->{path_libdir} ne '') { 1.462 + $libdir = "$CF->{path_buildroot}$CF->{path_libdir}"; 1.463 + } 1.464 + else { 1.465 + $libdir = "$CF->{path_buildroot}$CF->{path_prefix}/lib/perl"; 1.466 + } 1.467 + &runcmd("find $libdir -name perllocal.pod -print | xargs rm -f"); 1.468 + &runcmd("find $libdir -name .packlist -print | xargs rm -f"); 1.469 + &runcmd("find $libdir -depth -type d -print | (xargs rmdir >/dev/null 2>&1 || true)"); 1.470 + 1.471 + # determine RPM installation file list 1.472 + my @files = (); 1.473 + if ($CF->{path_libdir} eq '') { 1.474 + push(@files, '%not %dir '.$CF->{path_prefix}.'/lib/perl'); 1.475 + push(@files, '%not %dir '.$pcfg->{installarchlib}.'/auto'); 1.476 + push(@files, '%not %dir '.$pcfg->{installarchlib}); 1.477 + push(@files, '%not %dir '.$pcfg->{installprivlib}.'/auto'); 1.478 + push(@files, '%not %dir '.$pcfg->{installprivlib}); 1.479 + push(@files, '%not %dir '.$pcfg->{sitelib_stem}); 1.480 + push(@files, '%not %dir '.$pcfg->{installsitearch}.'/auto'); 1.481 + push(@files, '%not %dir '.$pcfg->{installsitearch}); 1.482 + push(@files, '%not %dir '.$pcfg->{installsitelib}.'/auto'); 1.483 + push(@files, '%not %dir '.$pcfg->{installsitelib}); 1.484 + push(@files, '%not %dir '.$pcfg->{vendorlib_stem}); 1.485 + push(@files, '%not %dir '.$pcfg->{installvendorarch}.'/auto'); 1.486 + push(@files, '%not %dir '.$pcfg->{installvendorarch}); 1.487 + push(@files, '%not %dir '.$pcfg->{installvendorlib}.'/auto'); 1.488 + push(@files, '%not %dir '.$pcfg->{installvendorlib}); 1.489 + } 1.490 + else { 1.491 + push(@files, $CF->{path_libdir}); 1.492 + } 1.493 + 1.494 + # output RPM installation file list 1.495 + my $out; 1.496 + if ($CF->{files_file} eq "-") { 1.497 + $out = new IO::Handle; 1.498 + $out->fdopen(fileno(STDOUT), "w"); 1.499 + } 1.500 + else { 1.501 + $out = new IO::File ">$CF->{files_file}"; 1.502 + } 1.503 + if ($CF->{files_unquoted}) { 1.504 + print $out join("\n", @files) . "\n"; 1.505 + } 1.506 + else { 1.507 + print $out '"'. join('"'."\n".'"', @files).'"'."\n"; 1.508 + } 1.509 + $out->close(); 1.510 +} 1.511 + 1.512 +# ==== STEP: 6. cleanup ==== 1.513 +if (grep { $_ eq "cleanup" } @steps_run) { 1.514 + &verbose("step 6: cleanup"); 1.515 + 1.516 + # remove temporary directory and its contents 1.517 + &runcmd("rm -rf $tmpdir"); 1.518 +} 1.519 + 1.520 +# die gracefully... 1.521 +&verbose("cleaning up environment"); 1.522 +&cleanup_perform(); 1.523 +exit(0); 1.524 + 1.525 +__END__ 1.526 + 1.527 +## 1.528 +## UNIX MANUAL PAGE 1.529 +## 1.530 + 1.531 +=pod 1.532 + 1.533 +=head1 NAME 1.534 + 1.535 +B<perl-openpkg> - B<OpenPKG Perl Module Build Utility> 1.536 + 1.537 +=head1 SYNOPSIS 1.538 + 1.539 +B<perl-openpkg> 1.540 +[B<-p>|B<--prefix> I<dir-path>] 1.541 +[B<-D>|B<--libdir> I<dir-path>] 1.542 +[B<-t>|B<--tmpdir> I<dir-path>] 1.543 +[B<-d>|B<--wrkdir> I<dir-path>] 1.544 +[B<-r>|B<--buildroot> I<dir-path>] 1.545 +[B<-w>|B<--buildwork> I<dir-path>] 1.546 +[B<-R>|B<--rpm> I<file-path>] 1.547 +[B<-P>|B<--perl> I<file-path>] 1.548 +[B<-s>|B<--schema> I<schema> 1.549 +[B<-A>|B<--args> I<arguments>] 1.550 +[B<-I>|B<--stdin> I<file-path>] 1.551 +[B<-F>|B<--files> I<file-path>] 1.552 +[B<-U>|B<--unquoted>] 1.553 +[B<-n>|B<--pkgname> I<name>] 1.554 +[B<-q>|B<--quiet>] 1.555 +[B<-v>|B<--verbose>] 1.556 +[I<step> ...] 1.557 + 1.558 +B<perl-openpkg> 1.559 +[B<-v>|B<--version>] 1.560 +[B<-h>|B<--help>] 1.561 + 1.562 +=head1 DESCRIPTION 1.563 + 1.564 +The B<perl-openpkg> program is an internal B<OpenPKG> packaging utility 1.565 +for building C<ExtUtils::MakeMaker> based Perl modules during the build 1.566 +procedure of Perl module based B<OpenPKG> packages. It provides an 1.567 +adjustable C<ExtUtils::MakeMaker> environment. 1.568 + 1.569 +=head1 OPTIONS 1.570 + 1.571 +The following command line options are available: 1.572 + 1.573 +=head2 Filesystem Paths 1.574 + 1.575 +The following command-line options set various filesystem paths. 1.576 + 1.577 +=over 4 1.578 + 1.579 +=item B<-p>, B<--prefix> I<dir-path> 1.580 + 1.581 +Filesystem path to OpenPKG instance. Default is C<@l_prefix@>. 1.582 + 1.583 +=item B<-l>, B<--libdir> I<dir-path> 1.584 + 1.585 +Filesystem path to Perl lib directory. Default is 1.586 +"I<prefix>C</lib/perl>". 1.587 + 1.588 +=item B<-t>, B<--tmpdir> I<dir-path> 1.589 + 1.590 +Filesystem path to temporary directory. Default is C<$TMPDIR>, 1.591 +as provided by the RPM build-time environment. 1.592 + 1.593 +=item B<-d>, B<--wrkdir> I<dir-path> 1.594 + 1.595 +Filesystem path to working directory. Default is current working directory 1.596 +as provided by the RPM build-time environment. 1.597 + 1.598 +=item B<-r>, B<--buildroot> I<dir-path> 1.599 + 1.600 +Filesystem path to RPM build root directory. Default is C<$RPM_BUILD_ROOT>, 1.601 +as provided by the RPM build-time environment. 1.602 + 1.603 +=item B<-w>, B<--buildwork> I<dir-path> 1.604 + 1.605 +Filesystem path to RPM build work directory. Default is C<$RPM_BUILD_DIR>, 1.606 +as provided by the RPM build-time environment. 1.607 + 1.608 +=item B<-R>, B<--rpm> I<file-path> 1.609 + 1.610 +Filesystem path to RPM program. Default is "I<prefix>C</bin/openpkg rpm>". 1.611 + 1.612 +=item B<-P>, B<--perl> I<file-path> 1.613 + 1.614 +Filesystem path to Perl program. Default is I<prefix>C</bin/perl>. 1.615 + 1.616 +=back 1.617 + 1.618 +=head2 OpenPKG Package Information 1.619 + 1.620 +The following command-line options set various package information. 1.621 + 1.622 +=over 4 1.623 + 1.624 +=item B<-s>, B<--schema> I<schema> 1.625 + 1.626 +Sets the Perl C<INSTALLDIRS> schema. Allowed values are 1.627 +"C<perl>", "C<site>" and "C<vendor>". The default is "C<vendor>". 1.628 + 1.629 +=item B<-A>, B<--args> I<arguments> 1.630 + 1.631 +Sets additional arguments which are passed through on the "C<perl 1.632 +Makefile.PL>" command line. This option can be specified multiple times, 1.633 +args are joined with a space between them. If joined args contain a '#' then 1.634 +it is substituted by the automatically generated args otherwise joined args 1.635 +are appended to automatically generated args. Default is empty. 1.636 + 1.637 +=item B<-I>, B<--stdin> I<file-path> 1.638 + 1.639 +Filesystem path to connect to F<stdin> on the "C<perl Makefile.PL>" 1.640 +command line. Default is "C</dev/null>". A value of "C<->" means reading 1.641 +from F<stdin>. 1.642 + 1.643 +=item B<-F>, B<--files> I<file-path> 1.644 + 1.645 +Filesystem path to write the RPM C<%files> entries to describing the 1.646 +packaging list of all installed files. The default is "C<->" meaning 1.647 +that the list is written to F<stdout>. 1.648 + 1.649 +=item B<-U>, B<--unquoted> 1.650 + 1.651 +By default the RPM <%files> list is written with each path entry 1.652 +enclosed in quotation marks. For raw post-processing, this option allows 1.653 +the list to be written without enclosing quotation marks. 1.654 + 1.655 +=item B<-n>, B<--pkgname> I<name> 1.656 + 1.657 +Name of involved RPM package. 1.658 + 1.659 +=back 1.660 + 1.661 +=head2 Run-Time Modes 1.662 + 1.663 +The following command-line options set various run-time modes. 1.664 + 1.665 +=over 4 1.666 + 1.667 +=item B<-q>, B<--quiet> 1.668 + 1.669 +Operate in quiet run-time mode. 1.670 + 1.671 +=item B<-v>, B<--verbose> 1.672 + 1.673 +Operate in verbose run-time mode. 1.674 + 1.675 +=back 1.676 + 1.677 +=head2 Stand-Alone Operations 1.678 + 1.679 +The following command-line options trigger various stand-alone operations. 1.680 + 1.681 +=over 4 1.682 + 1.683 +=item B<-V>, B<--version> 1.684 + 1.685 +Print program version only. 1.686 + 1.687 +=item B<-h>, B<--help> 1.688 + 1.689 +Print program usage help only. 1.690 + 1.691 +=back 1.692 + 1.693 +=head1 OPERATION STEPS 1.694 + 1.695 +The operation procedure of B<perl-openpkg> is divided into the following 1.696 +six distinguished steps: 1.697 + 1.698 +=over 3 1.699 + 1.700 +=item B<1. prepare> 1.701 + 1.702 +This prepares the build environment by optionally creating a temporary 1.703 +directory and establishing a Perl wrapper script. 1.704 +This step can be shared between the configuration, building and installation 1.705 +of multiple modules. 1.706 + 1.707 +=item B<2. configure> 1.708 + 1.709 +This configures the Perl module by performing the equivalent of 1.710 +the command "C<perl Makefile.PL>". This step has to be performed 1.711 +individually for each particular module. 1.712 + 1.713 +=item B<3. build> 1.714 + 1.715 +This builds the Perl module by performing the equivalent of the command 1.716 +"C<make all>". This step has to be performed individually for each 1.717 +particular module. 1.718 + 1.719 +=item B<4. install> 1.720 + 1.721 +This installs the Perl module by performing the equivalent of the 1.722 +command "C<make install>". This step has to be performed individually 1.723 +for each particular module. 1.724 + 1.725 +=item B<5. fixate> 1.726 + 1.727 +This fixates the installed files by removing unnecessary ones, fixing 1.728 +permissions and determining the resulting file list. This step can be 1.729 +shared between the configuration, building and installation of multiple 1.730 +modules. 1.731 + 1.732 +=item B<6. cleanup> 1.733 + 1.734 +This cleans up the build environment by removing all temporary files. 1.735 +This step can be shared between the configuration, building and 1.736 +installation of multiple modules. 1.737 + 1.738 +=back 1.739 + 1.740 +By default all operation steps are performed in sequence. Alternatively, 1.741 +the sequence of steps can be individually specified on the command 1.742 +line as one or more I<step> arguments. The given sequence of I<step>s 1.743 +has to be exactly a contiguous sub-sequence of the sequence listed 1.744 +above. As the extrem cases, it can be "C<prepare configure build install 1.745 +fixate cleanup>" (the same as not specifying any steps) or just perhaps 1.746 +"C<build>" (for executing only a particular step). 1.747 + 1.748 +=head1 EXAMPLE 1.749 + 1.750 + # packaging of single module 1.751 + perl-openpkg 1.752 + 1.753 + # packaging of multiple modules 1.754 + perl-openpkg prepare 1.755 + perl-openpkg -d Foo-1 configure build install 1.756 + perl-openpkg -d Bar-2 configure build install 1.757 + perl-openpkg -d Baz-3 configure build install 1.758 + perl-openpkg fixate cleanup 1.759 + 1.760 +=head1 HISTORY 1.761 + 1.762 +The B<perl-openpkg> utility was originally implemented as a small 1.763 +Bourne-Shell script for use in OpenPKG 1.1. It was later rewritten from 1.764 +scratch in Perl for OpenPKG 2.0 and especially made more flexible to 1.765 +reduce the complexity in numerious packages. 1.766 + 1.767 +=head1 SEE ALSO 1.768 + 1.769 +perl(1), "C<perldoc ExtUtils::MakeMaker>". 1.770 + 1.771 +=head1 AUTHORS 1.772 + 1.773 +Ralf S. Engelschall E<lt>rse@engelschall.comE<gt>. 1.774 + 1.775 +=cut 1.776 +