Tue, 28 Aug 2012 18:28:40 +0200
Import package vendor original specs for necessary manipulations.
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 |