perl-openpkg.pl 25 KB

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