perl-openpkg/perl-openpkg.pl

Tue, 28 Aug 2012 18:33:30 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 28 Aug 2012 18:33:30 +0200
changeset 558
d05aa91cd793
permissions
-rw-r--r--

Modernize packaging and use newely appeared versioned tarball URI.

michael@360 1 #!@l_prefix@/bin/perl -w
michael@360 2 ##
michael@360 3 ## perl-openpkg -- OpenPKG Perl Module Build Utility
michael@360 4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/>
michael@360 5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/>
michael@360 6 ##
michael@360 7 ## Permission to use, copy, modify, and distribute this software for
michael@360 8 ## any purpose with or without fee is hereby granted, provided that
michael@360 9 ## the above copyright notice and this permission notice appear in all
michael@360 10 ## copies.
michael@360 11 ##
michael@360 12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
michael@360 13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
michael@360 14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
michael@360 15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
michael@360 16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@360 17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@360 18 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
michael@360 19 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@360 20 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@360 21 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@360 22 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@360 23 ## SUCH DAMAGE.
michael@360 24 ##
michael@360 25
michael@360 26 require 5;
michael@360 27 use strict;
michael@360 28 use Getopt::Long;
michael@360 29 use IO qw(Handle Seekable File Pipe Socket Dir);
michael@360 30
michael@360 31 # program information
michael@360 32 my $ME = {
michael@360 33 prog_path => $0,
michael@360 34 prog_name => "perl-openpkg",
michael@360 35 prog_vers => "2.0.1",
michael@360 36 prog_date => "03-Dec-2004"
michael@360 37 };
michael@360 38
michael@360 39 # program configuration
michael@360 40 my $CF = {
michael@360 41 path_prefix => '@l_prefix@',
michael@360 42 path_libdir => "",
michael@360 43 path_tmpdir => ($ENV{"TMPDIR"} || "/tmp"),
michael@360 44 path_wrkdir => "",
michael@360 45 path_buildroot => ($ENV{"RPM_BUILD_ROOT"} || ""),
michael@360 46 path_buildwork => ($ENV{"RPM_BUILD_DIR"} || ""),
michael@360 47 pkg_name => ($ENV{"RPM_PACKAGE_NAME"} || ""),
michael@360 48 perl_schema => "vendor",
michael@360 49 perl_args => [],
michael@360 50 perl_stdin => "/dev/null",
michael@360 51 files_file => "-",
michael@360 52 files_unquoted => 0,
michael@360 53 prog_rpm => '%path_prefix%/libexec/openpkg/rpm',
michael@360 54 prog_perl => '%path_prefix%/bin/perl',
michael@360 55 mode_quiet => 0,
michael@360 56 mode_verbose => 0,
michael@360 57 run_version => 0,
michael@360 58 run_help => 0,
michael@360 59 };
michael@360 60
michael@360 61 # cleanup support
michael@360 62 my @cleanup = ();
michael@360 63 sub cleanup_remember {
michael@360 64 my ($cmd) = @_;
michael@360 65 push(@cleanup, $cmd);
michael@360 66 }
michael@360 67 sub cleanup_perform {
michael@360 68 foreach my $cmd (reverse @cleanup) {
michael@360 69 &runcmd($cmd);
michael@360 70 }
michael@360 71 }
michael@360 72
michael@360 73 # exception handling support
michael@360 74 $SIG{__DIE__} = sub {
michael@360 75 my ($err) = @_;
michael@360 76 $err =~ s|\s+at\s+.*||s if (not $CF->{mode_verbose});
michael@360 77 print STDERR "$ME->{prog_name}:ERROR: $err ". ($! ? "($!)" : "") . "\n";
michael@360 78 &cleanup_perform() if (not $CF->{mode_verbose});
michael@360 79 exit(1);
michael@360 80 };
michael@360 81
michael@360 82 # verbose message printing
michael@360 83 sub verbose {
michael@360 84 my ($msg) = @_;
michael@360 85 print STDERR "++ $msg\n" if (not $CF->{mode_quiet});
michael@360 86 }
michael@360 87
michael@360 88 # expand into a full filesystem path
michael@360 89 sub fullpath {
michael@360 90 my ($prog) = @_;
michael@360 91 my $fullprog = '';
michael@360 92 foreach my $path (split(/:/, $ENV{PATH})) {
michael@360 93 if (-x "$path/$prog") {
michael@360 94 $fullprog = "$path/$prog";
michael@360 95 last;
michael@360 96 }
michael@360 97 }
michael@360 98 return $fullprog;
michael@360 99 }
michael@360 100
michael@360 101 # execution of external commands
michael@360 102 sub runcmd {
michael@360 103 my ($cmd) = @_;
michael@360 104 print STDERR "\$ $cmd\n" if ($CF->{mode_verbose});
michael@360 105 $cmd = "($cmd) >/dev/null 2>&1" if ($CF->{mode_quiet});
michael@360 106 return (system($cmd) == 0);
michael@360 107 }
michael@360 108
michael@360 109 # create a directory (plus its missing parent dirs)
michael@360 110 sub mkdirp {
michael@360 111 my ($dir) = @_;
michael@360 112 my $pdir = $dir;
michael@360 113 $pdir =~ s|/[^/]*$||s;
michael@360 114 if (not -d $pdir) {
michael@360 115 &mkdirp($pdir, 0755);
michael@360 116 }
michael@360 117 if (not -d $dir) {
michael@360 118 &runcmd("umask 022 && mkdir $dir");
michael@360 119 }
michael@360 120 }
michael@360 121
michael@360 122 # command line parsing
michael@360 123 Getopt::Long::Configure("bundling");
michael@360 124 my $result = GetOptions(
michael@360 125 'p|prefix=s' => \$CF->{path_prefix},
michael@360 126 'l|libdir=s' => \$CF->{path_libdir},
michael@360 127 't|tmpdir=s' => \$CF->{path_tmpdir},
michael@360 128 'd|wrkdir=s' => \$CF->{path_wrkdir},
michael@360 129 'r|buildroot=s' => \$CF->{path_buildroot},
michael@360 130 'w|buildwork=s' => \$CF->{path_buildwork},
michael@360 131 'R|rpm=s' => \$CF->{prog_rpm},
michael@360 132 'P|perl=s' => \$CF->{prog_perl},
michael@360 133 's|schema=s' => \$CF->{perl_schema},
michael@360 134 'A|args=s' => \@{$CF->{perl_args}},
michael@360 135 'I|stdin=s' => \$CF->{perl_stdin},
michael@360 136 'F|files=s' => \$CF->{files_file},
michael@360 137 'U|unquoted' => \$CF->{files_unquoted},
michael@360 138 'n|pkgname=s' => \$CF->{pkg_name},
michael@360 139 'q|quiet' => \$CF->{mode_quiet},
michael@360 140 'v|verbose' => \$CF->{mode_verbose},
michael@360 141 'V|version' => \$CF->{run_version},
michael@360 142 'h|help' => \$CF->{run_help}
michael@360 143 ) || die "option parsing failed";
michael@360 144 if ($CF->{run_help}) {
michael@360 145 print "Usage: $ME->{prog_name} [options]\n" .
michael@360 146 "Available options:\n" .
michael@360 147 "\n" .
michael@360 148 " -p, --prefix <dir-path> filesystem path to OpenPKG instance\n" .
michael@360 149 " -l, --libdir <dir-path> filesystem path to Perl lib directory\n" .
michael@360 150 " -t, --tmpdir <dir-path> filesystem path to temporary directory\n" .
michael@360 151 " -d, --wrkdir <dir-path> filesystem path to working directory\n" .
michael@360 152 " -r, --buildroot <dir-path> filesystem path to RPM build root directory\n" .
michael@360 153 " -w, --buildwork <dir-path> filesystem path to RPM build work directory\n" .
michael@360 154 " -R, --rpm <file-path> filesystem path to RPM program\n" .
michael@360 155 " -P, --perl <file-path> filesystem path to Perl program\n" .
michael@360 156 "\n" .
michael@360 157 " -s, --schema <schema> Perl INSTALLDIRS schema\n" .
michael@360 158 " -A, --args <arguments> Perl Build.PL/Makefile.PL passed through arguments\n" .
michael@360 159 " -I, --stdin <file-path> filesystem path to connect to stdin\n" .
michael@360 160 " -F, --files <file-path> filesystem path to write RPM \%files list to\n" .
michael@360 161 " -U, --unquoted output RPM \%files list in unquoted format\n" .
michael@360 162 " -n, --pkgname <package-name> name of involved RPM package\n" .
michael@360 163 "\n" .
michael@360 164 " -q, --quiet operate in quiet run-time mode\n" .
michael@360 165 " -v, --verbose operate in verbose run-time mode\n" .
michael@360 166 "\n" .
michael@360 167 " -V, --version print out program version\n" .
michael@360 168 " -h, --help print out program usage help\n";
michael@360 169 exit(0);
michael@360 170 }
michael@360 171 if ($CF->{run_version}) {
michael@360 172 print "OpenPKG $ME->{prog_name} $ME->{prog_vers} ($ME->{prog_date})\n";
michael@360 173 exit(0);
michael@360 174 }
michael@360 175
michael@360 176 # fix configuration parameters
michael@360 177 foreach my $cf (keys(%{$CF})) {
michael@360 178 $CF->{$cf} =~ s|\%([A-Za-z_][A-Za-z0-9_]*)\%|$CF->{$1}|sge;
michael@360 179 }
michael@360 180
michael@360 181 # determine operation steps
michael@360 182 my @steps_exist = qw(prepare configure build install fixate cleanup);
michael@360 183 my @steps_run = ();
michael@360 184 if (@ARGV > 0) {
michael@360 185 foreach my $step (@ARGV) {
michael@360 186 if (not grep { $_ eq $step } @steps_exist) {
michael@360 187 die "operation step \"$step\" not existing";
michael@360 188 }
michael@360 189 push(@steps_run, $step);
michael@360 190 }
michael@360 191 my $steps_exist = "-".join("-", @steps_exist)."-";
michael@360 192 my $steps_run = "-".join("-", @steps_run)."-";
michael@360 193 if ($steps_exist !~ m|^.*${steps_run}.*$|s) {
michael@360 194 die "invalid operation step order \"".join(" ", @ARGV)."\"";
michael@360 195 }
michael@360 196 }
michael@360 197 else {
michael@360 198 @steps_run = @steps_exist;
michael@360 199 }
michael@360 200
michael@360 201 # friendly header ;-)
michael@360 202 &verbose("OpenPKG $ME->{prog_name} $ME->{prog_vers} ($ME->{prog_date})");
michael@360 203
michael@360 204 # determine RPM program
michael@360 205 if (not -x $CF->{prog_rpm}) {
michael@360 206 $CF->{prog_rpm} = &fullpath($CF->{prog_rpm});
michael@360 207 }
michael@360 208 my $V = `$CF->{prog_rpm} --version 2>/dev/null`;
michael@360 209 $V =~ s/^(?:rpm \(OpenPKG RPM\)|RPM version|OpenPKG RPM|rpm\s+\(.+?\))\s+([0-9ab.]+)(\.(?:SNAPSHOT|DEVEL).*)?\s*$/$1/s ||
michael@360 210 die "program '$CF->{prog_rpm}' seems to be not RPM";
michael@360 211 &verbose("determined RPM program: $CF->{prog_rpm} ($V)");
michael@360 212
michael@360 213 # determine Perl program
michael@360 214 if (not -x $CF->{prog_perl}) {
michael@360 215 $CF->{prog_perl} = &fullpath($CF->{prog_perl});
michael@360 216 }
michael@360 217 $V = `$CF->{prog_perl} --version 2>/dev/null`;
michael@360 218 $V =~ s|^.*This is perl.+v?(5\.[\d+.]+).*$|$1|s ||
michael@360 219 die "program '$CF->{prog_perl}' seems to be not Perl";
michael@360 220 &verbose("determined Perl program: $CF->{prog_perl} ($V)");
michael@360 221
michael@360 222 # check for existing paths
michael@360 223 if ($CF->{path_buildroot} eq '') {
michael@360 224 die "RPM build root directory not known (specify one with option --buildroot)";
michael@360 225 }
michael@360 226 if ($CF->{path_buildwork} eq '') {
michael@360 227 die "RPM build work directory not known (specify one with option --buildwork)";
michael@360 228 }
michael@360 229 mkdir($CF->{path_buildroot}, 0700);
michael@360 230 mkdir($CF->{path_buildwork}, 0700);
michael@360 231
michael@360 232 ##
michael@360 233 ## OPERATION SEQUENCE
michael@360 234 ##
michael@360 235
michael@360 236 # establish standard environment
michael@360 237 umask(022);
michael@360 238
michael@360 239 # determine name of temporary directory
michael@360 240 my $tmpdir = $CF->{path_tmpdir};
michael@360 241 $tmpdir =~ s|/+$||s;
michael@360 242 my $user = (getlogin() || getpwuid($<) || $ENV{LOGNAME} || $ENV{USERNAME} || "unknown");
michael@360 243 my $program = $ME->{prog_name};
michael@360 244 my $package = ($CF->{pkg_name} || "unknown");
michael@360 245 $tmpdir .= "/$user-$program-$package";
michael@360 246
michael@360 247 # determine name of perl wrapper script
michael@360 248 my $perlwrap = "$tmpdir/perl.sh";
michael@360 249
michael@360 250 # optionally change working directory
michael@360 251 my $dir = $CF->{path_wrkdir};
michael@360 252 if ($dir ne '') {
michael@360 253 if (not -d $dir) {
michael@360 254 # be smart and guess correct directory to
michael@360 255 # reduce special cases during packaging
michael@360 256 $dir =~ s|^.+/||s;
michael@360 257 my $parent = "";
michael@360 258 my $child = $dir;
michael@360 259 $child =~ s|^(.+/)([^/]+)$|$parent = $1, $2|se;
michael@360 260 LOOP: while ($child ne '') {
michael@360 261 foreach my $dir (glob("${parent}${child}*")) {
michael@360 262 if (-d "$parent$dir") {
michael@360 263 $child = $dir;
michael@360 264 last LOOP;
michael@360 265 }
michael@360 266 }
michael@360 267 $child =~ s|\W\w+$||s || last;
michael@360 268 last if (-d "$parent$child");
michael@360 269 }
michael@360 270 $dir = "$parent$child";
michael@360 271 }
michael@360 272 chdir($dir) || die "cannot change to working directory \"$dir\"";
michael@360 273 }
michael@360 274
michael@360 275 # determine Perl configuration
michael@360 276 my $pcfg = {};
michael@360 277 my $cmd = "$CF->{prog_perl}" .
michael@360 278 " -V:installarchlib -V:installprivlib" .
michael@360 279 " -V:installsitearch -V:installsitelib -V:sitelib_stem" .
michael@360 280 " -V:installvendorarch -V:installvendorlib -V:vendorlib_stem";
michael@360 281 my $out = `$cmd 2>/dev/null || true`;
michael@360 282 $out =~ s|^(\S+)='([^'']*)';$|$pcfg->{$1} = $2, ''|mge;
michael@360 283
michael@360 284 # ==== COMPAT prolog/epilog ====
michael@360 285 if (grep { $_ eq "prolog" or $_ eq "epilog" } @steps_run) {
michael@360 286 print "This is the perl-openpkg >= 20040126 version.\n" .
michael@360 287 "It was redesigned and is incompatible to previous\n" .
michael@360 288 "versions. It does not support prolog/epilog steps.\n" .
michael@360 289 "Please upgrade the package that uses perl-openpkg\n" .
michael@360 290 "or, as a temporary workaround, downgrade perl-openpkg\n";
michael@360 291 die "package/perl-openpkg incompatiblity";
michael@360 292 }
michael@360 293
michael@360 294 # ==== STEP: 1. prepare ====
michael@360 295 if (grep { $_ eq "prepare" } @steps_run) {
michael@360 296 &verbose("step 1: prepare");
michael@360 297
michael@360 298 # establish temporary directory
michael@360 299 system("rm -rf $tmpdir >/dev/null 2>&1");
michael@360 300 mkdir($tmpdir, 0700) || die "cannot create temporary directory '$tmpdir'";
michael@360 301
michael@360 302 # create Perl executable wrapper script
michael@360 303 my $io = new IO::File ">$perlwrap"
michael@360 304 || die "unable to open \"$perlwrap\" for writing";
michael@360 305 print $io
michael@360 306 "#!/bin/sh\n" .
michael@360 307 "exec $CF->{prog_perl} \\\n" .
michael@360 308 " -I$CF->{path_buildroot}$pcfg->{installarchlib} \\\n" .
michael@360 309 " -I$CF->{path_buildroot}$pcfg->{installprivlib} \\\n" .
michael@360 310 " -I$CF->{path_buildroot}$pcfg->{installsitearch} \\\n" .
michael@360 311 " -I$CF->{path_buildroot}$pcfg->{installsitelib} \\\n" .
michael@360 312 " -I$CF->{path_buildroot}$pcfg->{installvendorarch} \\\n" .
michael@360 313 " -I$CF->{path_buildroot}$pcfg->{installvendorlib} \\\n" .
michael@360 314 " \"\$@\"\n";
michael@360 315 $io->close();
michael@360 316 &runcmd("chmod 755 $perlwrap");
michael@360 317
michael@360 318 # establish Perl module installation areas
michael@360 319 &mkdirp("$CF->{path_buildroot}$pcfg->{installarchlib}");
michael@360 320 &mkdirp("$CF->{path_buildroot}$pcfg->{installprivlib}");
michael@360 321 &mkdirp("$CF->{path_buildroot}$pcfg->{installsitearch}");
michael@360 322 &mkdirp("$CF->{path_buildroot}$pcfg->{installsitelib}");
michael@360 323 &mkdirp("$CF->{path_buildroot}$pcfg->{installvendorarch}");
michael@360 324 &mkdirp("$CF->{path_buildroot}$pcfg->{installvendorlib}");
michael@360 325 }
michael@360 326
michael@360 327 # ==== STEP: 2. configure ====
michael@360 328 if (grep { $_ eq "configure" } @steps_run) {
michael@360 329 &verbose("step 2: configure");
michael@360 330
michael@360 331 # determine build environment and basic arguments
michael@360 332 my $environment = "";
michael@360 333 my $perl_args = '';
michael@360 334 if (-f "Build.PL" and (system("$perlwrap -MModule::Build -e '1;' >/dev/null 2>&1") >> 8) == 0) {
michael@360 335 # new-style Module::Build "Build.PL"
michael@360 336 $perl_args .= " installdirs=$CF->{perl_schema}";
michael@360 337 $perl_args .= " --install_path libdoc=remove-me-later";
michael@360 338 $perl_args .= " destdir=$CF->{path_buildroot}";
michael@360 339 if ($CF->{path_prefix} ne '' and $CF->{path_prefix} ne '@l_prefix@') {
michael@360 340 $perl_args .= " install_base=$CF->{path_prefix}";
michael@360 341 }
michael@360 342 if ($CF->{path_libdir} ne '') {
michael@360 343 $perl_args .= " --install_path lib=$CF->{path_libdir}";
michael@360 344 }
michael@360 345 $environment = 'Module::Build';
michael@360 346 }
michael@360 347 elsif (-f "Makefile.PL") { # ExtUtils::MakeMaker is part of the Perl distribution
michael@360 348 # old-style ExtUtils::MakeMaker "Makefile.PL"
michael@360 349 $perl_args .= " PERL=$perlwrap FULLPERL=$perlwrap";
michael@360 350 $perl_args .= " INSTALLDIRS=$CF->{perl_schema}";
michael@360 351 $perl_args .= " INSTALLMAN3DIR=none INSTALLSITEMAN3DIR=none INSTALLVENDORMAN3DIR=none";
michael@360 352 $perl_args .= " DESTDIR=$CF->{path_buildroot}";
michael@360 353 if ($CF->{path_prefix} ne '' and $CF->{path_prefix} ne '@l_prefix@') {
michael@360 354 $perl_args .= " PREFIX=$CF->{path_prefix}";
michael@360 355 }
michael@360 356 if ($CF->{path_libdir} ne '') {
michael@360 357 $perl_args .= " LIB=$CF->{path_libdir}";
michael@360 358 }
michael@360 359 $environment = 'ExtUtils::MakeMaker';
michael@360 360 }
michael@360 361 else {
michael@360 362 die "neither usable Module::Build \"Build.PL\" nor ExtUtils::MakeMaker \"Makefile.PL\" file found";
michael@360 363 }
michael@360 364
michael@360 365 # determine build-time extra arguments
michael@360 366 # (assuming that they are either work for both Module::Build and
michael@360 367 # ExtUtils::MakeMaker or the supplier knows what is used by us)
michael@360 368 if ($#{$CF->{perl_args}} >= 0) {
michael@360 369 my $user_args = join(" ", @{$CF->{perl_args}});
michael@360 370 if ($user_args =~ m|#|) {
michael@360 371 $user_args =~ s|#| $perl_args |;
michael@360 372 $perl_args = $user_args;
michael@360 373 }
michael@360 374 else {
michael@360 375 $perl_args .= " " . $user_args;
michael@360 376 }
michael@360 377 }
michael@360 378
michael@360 379 # determine stdin
michael@360 380 if ($CF->{perl_stdin} ne "-") {
michael@360 381 $perl_args .= " <$CF->{perl_stdin}";
michael@360 382 }
michael@360 383
michael@360 384 # setup the build environment
michael@360 385 if ($environment eq 'Module::Build') {
michael@360 386 &verbose("configuring module via Module::Build environment");
michael@360 387 &runcmd("chmod u+rw Build.PL");
michael@360 388 &runcmd("cp Build.PL Build.PL.orig");
michael@360 389 &runcmd("(cat Build.PL.orig; echo '') | sed -e \"s:\\\$^X:'$perlwrap':g\" >Build.PL");
michael@360 390 &runcmd("$perlwrap ./Build.PL $perl_args")
michael@360 391 or die "failed to \"configure\"";
michael@360 392 }
michael@360 393 elsif ($environment eq 'ExtUtils::MakeMaker') {
michael@360 394 &verbose("configuring module via ExtUtils::MakeMaker environment");
michael@360 395 &runcmd("chmod u+rw Makefile.PL");
michael@360 396 &runcmd("cp Makefile.PL Makefile.PL.orig");
michael@360 397 &runcmd("(cat Makefile.PL.orig; echo '') | sed -e \"s:\\\$^X:'$perlwrap':g\" >Makefile.PL");
michael@360 398 &runcmd("$perlwrap ./Makefile.PL $perl_args")
michael@360 399 or die "failed to \"configure\"";
michael@360 400 }
michael@360 401 }
michael@360 402
michael@360 403 # ==== STEP: 3. build ====
michael@360 404 if (grep { $_ eq "build" } @steps_run) {
michael@360 405 &verbose("step 3: build");
michael@360 406
michael@360 407 if (-f "Build.PL" and -f "Build") {
michael@360 408 # execute Build script
michael@360 409 &verbose("building module via Module::Build environment");
michael@360 410 &runcmd("$perlwrap Build build")
michael@360 411 or die "failed to \"build\"";
michael@360 412 }
michael@360 413 elsif (-f "Makefile.PL" and -f "Makefile") {
michael@360 414 # execute Makefile procedure
michael@360 415 &verbose("building module via ExtUtils::MakeMaker environment");
michael@360 416 my $make = `$CF->{prog_rpm} --eval '\%{l_make} \%{l_mflags}'`;
michael@360 417 $make =~ s|\n+$||s;
michael@360 418 my $make_args = "PERL=$perlwrap FULLPERL=$perlwrap";
michael@360 419 &runcmd("$make $make_args pure_all")
michael@360 420 or die "failed to \"build\"";
michael@360 421 }
michael@360 422 else {
michael@360 423 die "neither \"Build\" nor \"Makefile\" found in working directory";
michael@360 424 }
michael@360 425 }
michael@360 426
michael@360 427 # ==== STEP: 4. install ====
michael@360 428 if (grep { $_ eq "install" } @steps_run) {
michael@360 429 &verbose("step 4: install");
michael@360 430
michael@360 431 if (-f "Build.PL" and -f "Build") {
michael@360 432 # execute Build script
michael@360 433 &verbose("installing module via Module::Build environment");
michael@360 434 &runcmd("$perlwrap Build install")
michael@360 435 or die "failed to \"install\"";
michael@360 436 &runcmd("rm -rf $CF->{path_buildroot}$CF->{path_prefix}/remove-me-later");
michael@360 437 }
michael@360 438 elsif (-f "Makefile.PL" and -f "Makefile") {
michael@360 439 # execute Makefile procedure
michael@360 440 &verbose("installing module via ExtUtils::MakeMaker environment");
michael@360 441 my $make = `$CF->{prog_rpm} --eval '\%{l_make} \%{l_mflags}'`;
michael@360 442 $make =~ s|\n+$||s;
michael@360 443 my $make_args = "PERL=$perlwrap FULLPERL=$perlwrap";
michael@360 444 &runcmd("$make $make_args pure_install")
michael@360 445 or die "failed to \"install\"";
michael@360 446 }
michael@360 447 else {
michael@360 448 die "neither \"Build\" nor \"Makefile\" found in working directory";
michael@360 449 }
michael@360 450 }
michael@360 451
michael@360 452 # ==== STEP: 5. fixate ====
michael@360 453 if (grep { $_ eq "fixate" } @steps_run) {
michael@360 454 &verbose("step 5: fixate");
michael@360 455
michael@360 456 # prune installation files
michael@360 457 my $libdir;
michael@360 458 if ($CF->{path_libdir} ne '') {
michael@360 459 $libdir = "$CF->{path_buildroot}$CF->{path_libdir}";
michael@360 460 }
michael@360 461 else {
michael@360 462 $libdir = "$CF->{path_buildroot}$CF->{path_prefix}/lib/perl";
michael@360 463 }
michael@360 464 &runcmd("find $libdir -name perllocal.pod -print | xargs rm -f");
michael@360 465 &runcmd("find $libdir -name .packlist -print | xargs rm -f");
michael@360 466 &runcmd("find $libdir -depth -type d -print | (xargs rmdir >/dev/null 2>&1 || true)");
michael@360 467
michael@360 468 # determine RPM installation file list
michael@360 469 my @files = ();
michael@360 470 if ($CF->{path_libdir} eq '') {
michael@360 471 push(@files, '%not %dir '.$CF->{path_prefix}.'/lib/perl');
michael@360 472 push(@files, '%not %dir '.$pcfg->{installarchlib}.'/auto');
michael@360 473 push(@files, '%not %dir '.$pcfg->{installarchlib});
michael@360 474 push(@files, '%not %dir '.$pcfg->{installprivlib}.'/auto');
michael@360 475 push(@files, '%not %dir '.$pcfg->{installprivlib});
michael@360 476 push(@files, '%not %dir '.$pcfg->{sitelib_stem});
michael@360 477 push(@files, '%not %dir '.$pcfg->{installsitearch}.'/auto');
michael@360 478 push(@files, '%not %dir '.$pcfg->{installsitearch});
michael@360 479 push(@files, '%not %dir '.$pcfg->{installsitelib}.'/auto');
michael@360 480 push(@files, '%not %dir '.$pcfg->{installsitelib});
michael@360 481 push(@files, '%not %dir '.$pcfg->{vendorlib_stem});
michael@360 482 push(@files, '%not %dir '.$pcfg->{installvendorarch}.'/auto');
michael@360 483 push(@files, '%not %dir '.$pcfg->{installvendorarch});
michael@360 484 push(@files, '%not %dir '.$pcfg->{installvendorlib}.'/auto');
michael@360 485 push(@files, '%not %dir '.$pcfg->{installvendorlib});
michael@360 486 }
michael@360 487 else {
michael@360 488 push(@files, $CF->{path_libdir});
michael@360 489 }
michael@360 490
michael@360 491 # output RPM installation file list
michael@360 492 my $out;
michael@360 493 if ($CF->{files_file} eq "-") {
michael@360 494 $out = new IO::Handle;
michael@360 495 $out->fdopen(fileno(STDOUT), "w");
michael@360 496 }
michael@360 497 else {
michael@360 498 $out = new IO::File ">$CF->{files_file}";
michael@360 499 }
michael@360 500 if ($CF->{files_unquoted}) {
michael@360 501 print $out join("\n", @files) . "\n";
michael@360 502 }
michael@360 503 else {
michael@360 504 print $out '"'. join('"'."\n".'"', @files).'"'."\n";
michael@360 505 }
michael@360 506 $out->close();
michael@360 507 }
michael@360 508
michael@360 509 # ==== STEP: 6. cleanup ====
michael@360 510 if (grep { $_ eq "cleanup" } @steps_run) {
michael@360 511 &verbose("step 6: cleanup");
michael@360 512
michael@360 513 # remove temporary directory and its contents
michael@360 514 &runcmd("rm -rf $tmpdir");
michael@360 515 }
michael@360 516
michael@360 517 # die gracefully...
michael@360 518 &verbose("cleaning up environment");
michael@360 519 &cleanup_perform();
michael@360 520 exit(0);
michael@360 521
michael@360 522 __END__
michael@360 523
michael@360 524 ##
michael@360 525 ## UNIX MANUAL PAGE
michael@360 526 ##
michael@360 527
michael@360 528 =pod
michael@360 529
michael@360 530 =head1 NAME
michael@360 531
michael@360 532 B<perl-openpkg> - B<OpenPKG Perl Module Build Utility>
michael@360 533
michael@360 534 =head1 SYNOPSIS
michael@360 535
michael@360 536 B<perl-openpkg>
michael@360 537 [B<-p>|B<--prefix> I<dir-path>]
michael@360 538 [B<-D>|B<--libdir> I<dir-path>]
michael@360 539 [B<-t>|B<--tmpdir> I<dir-path>]
michael@360 540 [B<-d>|B<--wrkdir> I<dir-path>]
michael@360 541 [B<-r>|B<--buildroot> I<dir-path>]
michael@360 542 [B<-w>|B<--buildwork> I<dir-path>]
michael@360 543 [B<-R>|B<--rpm> I<file-path>]
michael@360 544 [B<-P>|B<--perl> I<file-path>]
michael@360 545 [B<-s>|B<--schema> I<schema>
michael@360 546 [B<-A>|B<--args> I<arguments>]
michael@360 547 [B<-I>|B<--stdin> I<file-path>]
michael@360 548 [B<-F>|B<--files> I<file-path>]
michael@360 549 [B<-U>|B<--unquoted>]
michael@360 550 [B<-n>|B<--pkgname> I<name>]
michael@360 551 [B<-q>|B<--quiet>]
michael@360 552 [B<-v>|B<--verbose>]
michael@360 553 [I<step> ...]
michael@360 554
michael@360 555 B<perl-openpkg>
michael@360 556 [B<-v>|B<--version>]
michael@360 557 [B<-h>|B<--help>]
michael@360 558
michael@360 559 =head1 DESCRIPTION
michael@360 560
michael@360 561 The B<perl-openpkg> program is an internal B<OpenPKG> packaging utility
michael@360 562 for building C<ExtUtils::MakeMaker> based Perl modules during the build
michael@360 563 procedure of Perl module based B<OpenPKG> packages. It provides an
michael@360 564 adjustable C<ExtUtils::MakeMaker> environment.
michael@360 565
michael@360 566 =head1 OPTIONS
michael@360 567
michael@360 568 The following command line options are available:
michael@360 569
michael@360 570 =head2 Filesystem Paths
michael@360 571
michael@360 572 The following command-line options set various filesystem paths.
michael@360 573
michael@360 574 =over 4
michael@360 575
michael@360 576 =item B<-p>, B<--prefix> I<dir-path>
michael@360 577
michael@360 578 Filesystem path to OpenPKG instance. Default is C<@l_prefix@>.
michael@360 579
michael@360 580 =item B<-l>, B<--libdir> I<dir-path>
michael@360 581
michael@360 582 Filesystem path to Perl lib directory. Default is
michael@360 583 "I<prefix>C</lib/perl>".
michael@360 584
michael@360 585 =item B<-t>, B<--tmpdir> I<dir-path>
michael@360 586
michael@360 587 Filesystem path to temporary directory. Default is C<$TMPDIR>,
michael@360 588 as provided by the RPM build-time environment.
michael@360 589
michael@360 590 =item B<-d>, B<--wrkdir> I<dir-path>
michael@360 591
michael@360 592 Filesystem path to working directory. Default is current working directory
michael@360 593 as provided by the RPM build-time environment.
michael@360 594
michael@360 595 =item B<-r>, B<--buildroot> I<dir-path>
michael@360 596
michael@360 597 Filesystem path to RPM build root directory. Default is C<$RPM_BUILD_ROOT>,
michael@360 598 as provided by the RPM build-time environment.
michael@360 599
michael@360 600 =item B<-w>, B<--buildwork> I<dir-path>
michael@360 601
michael@360 602 Filesystem path to RPM build work directory. Default is C<$RPM_BUILD_DIR>,
michael@360 603 as provided by the RPM build-time environment.
michael@360 604
michael@360 605 =item B<-R>, B<--rpm> I<file-path>
michael@360 606
michael@360 607 Filesystem path to RPM program. Default is "I<prefix>C</bin/openpkg rpm>".
michael@360 608
michael@360 609 =item B<-P>, B<--perl> I<file-path>
michael@360 610
michael@360 611 Filesystem path to Perl program. Default is I<prefix>C</bin/perl>.
michael@360 612
michael@360 613 =back
michael@360 614
michael@360 615 =head2 OpenPKG Package Information
michael@360 616
michael@360 617 The following command-line options set various package information.
michael@360 618
michael@360 619 =over 4
michael@360 620
michael@360 621 =item B<-s>, B<--schema> I<schema>
michael@360 622
michael@360 623 Sets the Perl C<INSTALLDIRS> schema. Allowed values are
michael@360 624 "C<perl>", "C<site>" and "C<vendor>". The default is "C<vendor>".
michael@360 625
michael@360 626 =item B<-A>, B<--args> I<arguments>
michael@360 627
michael@360 628 Sets additional arguments which are passed through on the "C<perl
michael@360 629 Makefile.PL>" command line. This option can be specified multiple times,
michael@360 630 args are joined with a space between them. If joined args contain a '#' then
michael@360 631 it is substituted by the automatically generated args otherwise joined args
michael@360 632 are appended to automatically generated args. Default is empty.
michael@360 633
michael@360 634 =item B<-I>, B<--stdin> I<file-path>
michael@360 635
michael@360 636 Filesystem path to connect to F<stdin> on the "C<perl Makefile.PL>"
michael@360 637 command line. Default is "C</dev/null>". A value of "C<->" means reading
michael@360 638 from F<stdin>.
michael@360 639
michael@360 640 =item B<-F>, B<--files> I<file-path>
michael@360 641
michael@360 642 Filesystem path to write the RPM C<%files> entries to describing the
michael@360 643 packaging list of all installed files. The default is "C<->" meaning
michael@360 644 that the list is written to F<stdout>.
michael@360 645
michael@360 646 =item B<-U>, B<--unquoted>
michael@360 647
michael@360 648 By default the RPM <%files> list is written with each path entry
michael@360 649 enclosed in quotation marks. For raw post-processing, this option allows
michael@360 650 the list to be written without enclosing quotation marks.
michael@360 651
michael@360 652 =item B<-n>, B<--pkgname> I<name>
michael@360 653
michael@360 654 Name of involved RPM package.
michael@360 655
michael@360 656 =back
michael@360 657
michael@360 658 =head2 Run-Time Modes
michael@360 659
michael@360 660 The following command-line options set various run-time modes.
michael@360 661
michael@360 662 =over 4
michael@360 663
michael@360 664 =item B<-q>, B<--quiet>
michael@360 665
michael@360 666 Operate in quiet run-time mode.
michael@360 667
michael@360 668 =item B<-v>, B<--verbose>
michael@360 669
michael@360 670 Operate in verbose run-time mode.
michael@360 671
michael@360 672 =back
michael@360 673
michael@360 674 =head2 Stand-Alone Operations
michael@360 675
michael@360 676 The following command-line options trigger various stand-alone operations.
michael@360 677
michael@360 678 =over 4
michael@360 679
michael@360 680 =item B<-V>, B<--version>
michael@360 681
michael@360 682 Print program version only.
michael@360 683
michael@360 684 =item B<-h>, B<--help>
michael@360 685
michael@360 686 Print program usage help only.
michael@360 687
michael@360 688 =back
michael@360 689
michael@360 690 =head1 OPERATION STEPS
michael@360 691
michael@360 692 The operation procedure of B<perl-openpkg> is divided into the following
michael@360 693 six distinguished steps:
michael@360 694
michael@360 695 =over 3
michael@360 696
michael@360 697 =item B<1. prepare>
michael@360 698
michael@360 699 This prepares the build environment by optionally creating a temporary
michael@360 700 directory and establishing a Perl wrapper script.
michael@360 701 This step can be shared between the configuration, building and installation
michael@360 702 of multiple modules.
michael@360 703
michael@360 704 =item B<2. configure>
michael@360 705
michael@360 706 This configures the Perl module by performing the equivalent of
michael@360 707 the command "C<perl Makefile.PL>". This step has to be performed
michael@360 708 individually for each particular module.
michael@360 709
michael@360 710 =item B<3. build>
michael@360 711
michael@360 712 This builds the Perl module by performing the equivalent of the command
michael@360 713 "C<make all>". This step has to be performed individually for each
michael@360 714 particular module.
michael@360 715
michael@360 716 =item B<4. install>
michael@360 717
michael@360 718 This installs the Perl module by performing the equivalent of the
michael@360 719 command "C<make install>". This step has to be performed individually
michael@360 720 for each particular module.
michael@360 721
michael@360 722 =item B<5. fixate>
michael@360 723
michael@360 724 This fixates the installed files by removing unnecessary ones, fixing
michael@360 725 permissions and determining the resulting file list. This step can be
michael@360 726 shared between the configuration, building and installation of multiple
michael@360 727 modules.
michael@360 728
michael@360 729 =item B<6. cleanup>
michael@360 730
michael@360 731 This cleans up the build environment by removing all temporary files.
michael@360 732 This step can be shared between the configuration, building and
michael@360 733 installation of multiple modules.
michael@360 734
michael@360 735 =back
michael@360 736
michael@360 737 By default all operation steps are performed in sequence. Alternatively,
michael@360 738 the sequence of steps can be individually specified on the command
michael@360 739 line as one or more I<step> arguments. The given sequence of I<step>s
michael@360 740 has to be exactly a contiguous sub-sequence of the sequence listed
michael@360 741 above. As the extrem cases, it can be "C<prepare configure build install
michael@360 742 fixate cleanup>" (the same as not specifying any steps) or just perhaps
michael@360 743 "C<build>" (for executing only a particular step).
michael@360 744
michael@360 745 =head1 EXAMPLE
michael@360 746
michael@360 747 # packaging of single module
michael@360 748 perl-openpkg
michael@360 749
michael@360 750 # packaging of multiple modules
michael@360 751 perl-openpkg prepare
michael@360 752 perl-openpkg -d Foo-1 configure build install
michael@360 753 perl-openpkg -d Bar-2 configure build install
michael@360 754 perl-openpkg -d Baz-3 configure build install
michael@360 755 perl-openpkg fixate cleanup
michael@360 756
michael@360 757 =head1 HISTORY
michael@360 758
michael@360 759 The B<perl-openpkg> utility was originally implemented as a small
michael@360 760 Bourne-Shell script for use in OpenPKG 1.1. It was later rewritten from
michael@360 761 scratch in Perl for OpenPKG 2.0 and especially made more flexible to
michael@360 762 reduce the complexity in numerious packages.
michael@360 763
michael@360 764 =head1 SEE ALSO
michael@360 765
michael@360 766 perl(1), "C<perldoc ExtUtils::MakeMaker>".
michael@360 767
michael@360 768 =head1 AUTHORS
michael@360 769
michael@360 770 Ralf S. Engelschall E<lt>rse@engelschall.comE<gt>.
michael@360 771
michael@360 772 =cut
michael@360 773

mercurial