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