From 479d2113ccb2226821ef75027b9186d1d0e367e9 Mon Sep 17 00:00:00 2001 From: "Michael G. Schwern" Date: Sun, 30 Mar 2003 18:42:58 -0800 Subject: [PATCH] ExtUtils::MakeMaker 6.03 -> 6.06_05ish Message-ID: <20030331104257.GB15327@windhund.schwern.org> p4raw-id: //depot/perl@19099 --- MANIFEST | 14 + lib/ExtUtils/Changes | 262 ++++- lib/ExtUtils/Command.pm | 88 +- lib/ExtUtils/Command/MM.pm | 208 +++- lib/ExtUtils/Install.pm | 396 ++++--- lib/ExtUtils/Liblist.pm | 15 +- lib/ExtUtils/Liblist/Kid.pm | 19 +- lib/ExtUtils/MANIFEST.SKIP | 13 +- lib/ExtUtils/MM_Any.pm | 676 +++++++++++- lib/ExtUtils/MM_BeOS.pm | 18 +- lib/ExtUtils/MM_Cygwin.pm | 125 +-- lib/ExtUtils/MM_DOS.pm | 3 + lib/ExtUtils/MM_MacOS.pm | 381 ++++--- lib/ExtUtils/MM_NW5.pm | 226 +--- lib/ExtUtils/MM_OS2.pm | 51 +- lib/ExtUtils/MM_UWIN.pm | 2 + lib/ExtUtils/MM_Unix.pm | 2003 ++++++++++++++++++----------------- lib/ExtUtils/MM_VMS.pm | 1284 +++++++++++----------- lib/ExtUtils/MM_Win32.pm | 689 ++++-------- lib/ExtUtils/MM_Win95.pm | 172 ++- lib/ExtUtils/MakeMaker.pm | 394 ++++--- lib/ExtUtils/MakeMaker/FAQ.pod | 199 ++++ lib/ExtUtils/MakeMaker/Tutorial.pod | 124 +++ lib/ExtUtils/MakeMaker/vmsish.pm | 40 + lib/ExtUtils/Manifest.pm | 263 +++-- lib/ExtUtils/NOTES | 102 ++ lib/ExtUtils/PATCHING | 155 +++ lib/ExtUtils/README | 28 + lib/ExtUtils/TODO | 49 + lib/ExtUtils/t/00compile.t | 53 + lib/ExtUtils/t/00setup_dummy.t | 10 +- lib/ExtUtils/t/Command.t | 239 +++-- lib/ExtUtils/t/INST.t | 2 +- lib/ExtUtils/t/INST_PREFIX.t | 80 +- lib/ExtUtils/t/Install.t | 68 ++ lib/ExtUtils/t/Liblist.t | 35 + lib/ExtUtils/t/MM_BeOS.t | 15 +- lib/ExtUtils/t/MM_Cygwin.t | 75 +- lib/ExtUtils/t/MM_NW5.t | 25 +- lib/ExtUtils/t/MM_OS2.t | 23 +- lib/ExtUtils/t/MM_Unix.t | 29 +- lib/ExtUtils/t/MM_VMS.t | 3 +- lib/ExtUtils/t/MM_Win32.t | 107 +- lib/ExtUtils/t/Manifest.t | 25 +- lib/ExtUtils/t/basic.t | 99 +- lib/ExtUtils/t/hints.t | 8 +- lib/ExtUtils/t/oneliner.t | 51 + lib/ExtUtils/t/prefixify.t | 10 +- lib/ExtUtils/t/prompt.t | 56 + lib/ExtUtils/t/split_command.t | 66 ++ t/lib/TieIn.pm | 23 + 51 files changed, 5754 insertions(+), 3347 deletions(-) create mode 100644 lib/ExtUtils/MakeMaker/FAQ.pod create mode 100644 lib/ExtUtils/MakeMaker/Tutorial.pod create mode 100644 lib/ExtUtils/MakeMaker/vmsish.pm create mode 100644 lib/ExtUtils/NOTES create mode 100644 lib/ExtUtils/PATCHING create mode 100644 lib/ExtUtils/README create mode 100644 lib/ExtUtils/TODO create mode 100644 lib/ExtUtils/t/00compile.t create mode 100644 lib/ExtUtils/t/Install.t create mode 100644 lib/ExtUtils/t/Liblist.t create mode 100644 lib/ExtUtils/t/oneliner.t create mode 100644 lib/ExtUtils/t/prompt.t create mode 100644 lib/ExtUtils/t/split_command.t create mode 100644 t/lib/TieIn.pm diff --git a/MANIFEST b/MANIFEST index 5205f16..91b9a41 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1074,6 +1074,9 @@ lib/ExtUtils/instmodsh Give information about installed extensions lib/ExtUtils/Liblist.pm Locates libraries lib/ExtUtils/Liblist/Kid.pm Does the real work of the above lib/ExtUtils/MakeMaker.pm Write Makefiles for extensions +lib/ExtUtils/MakeMaker/FAQ.pod MakeMaker FAQ +lib/ExtUtils/MakeMaker/Tutorial.pod Writing a module with MakeMaker +lib/ExtUtils/MakeMaker/vmsish.pm Platform agnostic vmsish.pm lib/ExtUtils/Manifest.pm Utilities to write MANIFEST files lib/ExtUtils/MANIFEST.SKIP The default MANIFEST.SKIP lib/ExtUtils/Mkbootstrap.pm Writes a bootstrap file (see MakeMaker) @@ -1092,7 +1095,11 @@ lib/ExtUtils/MM_VMS.pm MakeMaker methods for VMS lib/ExtUtils/MM_Win32.pm MakeMaker methods for Win32 lib/ExtUtils/MM_Win95.pm MakeMaker methods for Win95 lib/ExtUtils/MY.pm MakeMaker user override class +lib/ExtUtils/NOTES Notes about MakeMaker internals +lib/ExtUtils/PATCHING Suggestions for patching MakeMaker +lib/ExtUtils/README MakeMaker README lib/ExtUtils/Packlist.pm Manipulates .packlist files +lib/ExtUtils/t/00compile.t See if MakeMaker modules compile lib/ExtUtils/t/00setup_dummy.t Setup MakeMaker test module lib/ExtUtils/t/backwards.t Check MakeMaker's backwards compatibility lib/ExtUtils/t/basic.t See if MakeMaker can build a module @@ -1101,8 +1108,10 @@ lib/ExtUtils/t/Constant.t See if ExtUtils::Constant works lib/ExtUtils/t/Embed.t See if ExtUtils::Embed and embedding works lib/ExtUtils/t/hints.t See if hint files are honored. lib/ExtUtils/t/INST.t Check MakeMaker INST_* macros +lib/ExtUtils/t/Install.t See if ExtUtils::Install works lib/ExtUtils/t/Installed.t See if ExtUtils::Installed works lib/ExtUtils/t/INST_PREFIX.t See if MakeMaker can apply PREFIXs +lib/ExtUtils/t/Liblist.t See if ExtUtils::Liblist works lib/ExtUtils/t/Manifest.t See if ExtUtils::Manifest works lib/ExtUtils/t/Mkbootstrap.t See if ExtUtils::Mkbootstrap works lib/ExtUtils/t/MM_BeOS.t See if ExtUtils::MM_BeOS works @@ -1112,14 +1121,18 @@ lib/ExtUtils/t/MM_OS2.t See if ExtUtils::MM_OS2 works lib/ExtUtils/t/MM_Unix.t See if ExtUtils::MM_UNIX works lib/ExtUtils/t/MM_VMS.t See if ExtUtils::MM_VMS works lib/ExtUtils/t/MM_Win32.t See if ExtUtils::MM_Win32 works +lib/ExtUtils/t/oneliner.t See if MM can generate perl one-liners lib/ExtUtils/t/Packlist.t See if Packlist works lib/ExtUtils/t/prefixify.t See if MakeMaker can apply a PREFIX lib/ExtUtils/t/problems.t How MakeMaker reacts to build problems +lib/ExtUtils/t/prompt.t See if E::MM::prompt() works +lib/ExtUtils/t/split_command.t See if MM's xargs-like function works lib/ExtUtils/t/testlib.t See if ExtUtils::testlib works lib/ExtUtils/t/VERSION_FROM.t See if MakeMaker's VERSION_FROM works lib/ExtUtils/t/writemakefile_args.t See if WriteMakefile works lib/ExtUtils/t/zz_cleanup_dummy.t Cleanup MakeMaker test module lib/ExtUtils/testlib.pm Fixes up @INC to use just-built extension +lib/ExtUtils/TODO Things TODO in MakeMaker lib/ExtUtils/typemap Extension interface types lib/ExtUtils/xsubpp External subroutine preprocessor lib/fastcwd.pl a faster but more dangerous getcwd @@ -2502,6 +2515,7 @@ t/lib/Test/Simple/sample_tests/require.plx for exit.t t/lib/Test/Simple/sample_tests/success.plx for exit.t t/lib/Test/Simple/sample_tests/too_few.plx for exit.t t/lib/Test/Simple/sample_tests/two_fail.plx for exit.t +t/lib/TieIn.pm Testing library for dummy input handles t/lib/TieOut.pm Testing library to capture prints t/lib/warnings/1global Tests of global warnings for warnings.t t/lib/warnings/2use Tests for "use warnings" for warnings.t diff --git a/lib/ExtUtils/Changes b/lib/ExtUtils/Changes index 39bd0c8..879f55d 100644 --- a/lib/ExtUtils/Changes +++ b/lib/ExtUtils/Changes @@ -1,3 +1,263 @@ +6.06_05 + - Syncing into bleadperl. Minor nits revealed... + - AutoSplit open filehandle bug was fixed in bleadperl. Averted a + warning because of this. + - hint files were only being loaded if . happened to be in @INC. + A bug/feature of File::Spec was stripping off the current dir from + the front of hintfile paths causing Perl to look for them in @INC. + Worked around. + - Now checking $! for errors if a hint file returns undef + - compile test was testing all of perl! Scaling back to just ExtUtils/ + +6.06_04 Sun Mar 30 20:34:39 PST 2003 + - Now looking for ExtUtils::xsubpp through @INC rather than just + the perl core directories. This helps ExtUtils::ParseXS. + - Systems which don't put their libraries under their $Config{prefix} + (OS X, Debian) weren't putting their libraries in the spot declared + in Config. It was going under $Config{prefix}. + - Prerequisites check now deals better with X.Y_Z style alpha versions + - ExtUtils::Liblist->ext() was using $Config{perllibs} which is a 5.6.1 + thing. Falling back to $Config{libs} if perllibs isn't there. + - ExtUtils::Command::MM now reads from @ARGV if called with no + args. Makes the one liner a bit simpler. + * Restored ExtUtils::Liblist::ext() for backwards compatibility. + Missing since 5.6.1. + - Switching to relative dirs for self-building to shorten + command line lengths. + - Fixing minor test warning on VMS when compiling ExtUtils::Manifest + - Skipping STDIN read prompt() tests on 5.5.3. Can't test due to + eof() not honor tied handles. + - Config.pm on 5.5.3 doesn't have any concept of vendor*. This was + causing warnings when generating the Makefile. + +6.06_03 Sat Mar 29 19:44:53 PST 2003 + - Added AUTHOR and ABSTRACT_FROM info for ppd generation. + - Added echo() method to portably echo text to a file. + - Worked around 5.8.0 eval 'require Foo::Bar' bug causing MakeMaker + to think modules weren't installed. + - Modernized VMS doc_*_install targets + - Changed some $(PERL) -e "print ..." code to use $(ECHO). + - Replaced uses of Delete/NoLog/NoConfirm with $(RM_F) in MM_VMS + - Fixed some duplicate macros making MMS happy. + - Fixed $ExtUtils::MM_VMS::Revision. It was just the $VERSION before. + - Fixed ExtUtils::Command::MM::perllocal_install(), uninstall(), + warn_if_old_packlist(). + * Pulling File::Spec::VMS::fixpath() and eliminate_macros() into MM_VMS + as the new cannonical location. They never should have been in F::S + in the first place. + * ExtUtils::Command::eqtime() would truncate the file being equalized! + Holdover from exclusive .exists usage. + - Cleaned up hard coded 'echo' and '@' to $(ECHO) and $(NOECHO) + - $(SAY) is now $(ECHO) on VMS + - Moved rogue initializations from tools_other() to init_others() + - Normalized MM_VMS's tools_other() to mostly use its superclass. + - split_command() was off-by-one when calculating max command line + lengths causing it to run over on VMS + - made split_command() a bit smarter, taking into account some macro + expansion + - Fixed initialization of OBJECT, DISTNAME and LDFROM on VMS + - Fixed *_install target uses of File::Spec. + - Added ExtUtils::MakeMaker::vmsish wrapper around vmsish so MM_VMS + can be compiled on non-VMS machines. For testing. + * Added ExtUtils::MakeMaker::Tutorial about writing modules with + MakeMaker. + - Removed "always use h2xs" dogma. + - Added compile & POD test + * 'make distdir' now generates META.yml module meta-data file. + Proof of concept. Have to syncronize with Module::Build. + * Added maniadd() to ExtUtils::Manifest to add entries to the MANIFEST + * ExtUtils::Command::chmod was not interpreting file permissions as + octal. Also, docs & tests slightly wrong (thanks Stas Bekman). + - ExtUtils::Install was hard coding blib/lib and blib/arch, unportable + [perl #21526] + +6.06_02 Mon Dec 23 20:39:57 PST 2002 + * Lots of Win32 fixes busted between 6.05 and 6.06_01. + * split_command() tests still not happy on Win32. Problems with + shell vs Makefile escaping makes testing difficult. + * VMS still broken. Need to convert File::Spec method calls back to + object method calls so the weird FS::VMS->eliminate_macros() and + fixpath() work again. + +6.06_01 Thu Dec 19 00:14:49 PST 2002 + - Andreas found that when building the core it is desirable for + MakeMaker to use a relative path to perl. + - File::Spec->catfile() has a bug where the resulting file may not be + canonicalized. This was causing problems when generating manpaths. + MakeMaker now uses its own fixed override for catfile(). + - Fixed the POD recognition regex to properly catch /=head\d/ tags. + * Added a PATCHING guideline document. + - Updated the class hierarchy in NOTES. + - Installed.t now cleans up after itself better. + - Steve Purkis rewrote the manifypods system to use Pod::Man + rather than pod2man. Its now portable and manifypods() moved from + MM_Unix to MM_Any. As a result, lots of icky and redudant code went + away. This also removes the POD2MAN macro, but noone should be + using that. + - "make manifypods" now works on Win32 + - "make manifypods" is now be faster + - Made MM_Unix->find_perl more portable. Eliminated MM_Win32->find_perl + override. MM_VMS->find_perl remains. + * find_perl() can now handle filenames with spaces in them (RT448) + * find_perl() on Win32 no longer produces spurious "File Creation error" + messages (perlbug ID 20020709.001) + - Removed unfinished and unused maybe_command_in_dirs() + - Removed dead SelfLoader cruft from MM_Unix. + - Fixed PPD generation when the ppd contains quotes (RT1473) + - Fixed PPD generation on VMS + - Moved Win9x specific subdir_x() code from MM_Unix to MM_Win95 + * Craig Berry fixed hint files on VMS + - Added the perl_onliner() method to generate portable, safe one-liners + - Changing hardcoded $self->{MAKEFILE} to $(FIRST_MAKEFILE). + * Rafael Garcia-Suarez made MakeMaker ignore Subversion control files + by default. + - Added MAKEFILE_OLD macro. + * No longer generating man pages by default on VMS. + - Improved DISTNAME docs + * Documented DISTVNAME and VERSION_SYM + * Documented dist() + - Seperated dist_core() into dist, tardist, uutardist, tarfile, + zipdist, zipfile and shdist_target methods. Allows elimination + of redundant code in MM_VMS. + - Replaced WARN_IF_OLD_PACKLIST, DOC_INSTALL and UNINSTALL + one-liners with ExtUtils::Command::MM functions + - Replaced VMS hand-rolled perl code for TOUCH, CHMOD, RM_F and RM_RF + with ExtUtils::Command functions. Added TEST_F. + - Adding clean_subdirs target and clean_subdirs_target() method to + generate same. This allows easier overriding of an unportable part + of the clean target. + - Defined DEV_NULL for MacOS + - Removed ROOTEXT from MM_MacOS, apparently unused + - Added $(DIRFILESEP) macro and init_DIRFILESEP to avoid + hardcoding / or \. Reduces code duplication in the MM_* modules. + - Added init_platform() and platform_constants() for OS specific + macros. Moved OS specific macros from constants() overrides there. + - Added init_VERSION() to setup various *VERSION* macros. + - Added default wraplist() to make porting easier. + - Added makemakerdflt_target() to guarantee 'all' is the default + target. + - Added special_targets() to handle things like .PHONY and make sure + they come first. + - Added init_linker() to initialize linker relatied macros. + - MM_MacOS constants() disolves + Moved MACPERL_SRC, MACPERL_LIB, MACPERL_INC from init_main() to + init_platform(). + Moved DEFINE and INC tweaking from constants() to init_main() + Moved DEFINE_VERSION & XS_DEFINE_VERSION from constants() to + init_VERSION(). + Eliminated MODULES. Unused and its the same as TO_INST_PM + Moved .INCLUDE from constants() to special_targets() + + - MM_NW5 constants() & init_others() disolves + Moved LIBPTH, BASE_IMPORT, NLM_VERSION, MPKTOOL, TOOLPATH from + init_others() to init_platform() + Moved INCLUDE and PATH definitions from constants() to + init_platform() + Moved BOOT_SYMBOL, NLM_SHORT_NAME, PATH and INCLUDE from + constants() to init_platform() + + - MM_Unix constants() goes on a diet + Moved all macro definitions to init_* methods. + Added MM_REVISION for completeness + Using wraplist() instead of manual joining + Moved .NO_CONFIG_REC, .SUFFIXES and .PHONY to special_targets() + Moved makemakerdflt: to makemakerdeflt_target() + Moved INST_{STATIC,DYNAMIC,BOOT} to init_INST() + Moved EXPORT_LIST, PERL_ARCHIVE & PERL_ARCHIVE_AFTER to init_linker(). + Moved PERL_MALLOC_DEF to init_platform() + + - MM_VMS constants() goes on a diet + Moved DEFINE from constants() to init_main() + Moved OBJECT & LDFROM from constants() to init_others() + Moved MM_VMS_REVISION and PERL_VMS to init_platform + Added MM_VMS_VERSION + Moved DEFINE_VERSION, XS_DEFINE_VERSION and MAKEMAKER changes to + init_VERSION + Moved .SUFFIXES changes to special_targets() override. + Eliminated $self->{PM_TO_BLIB}. Its redundant with $self->{PM}. + constants() now consists only of fixpath() calls. + + - MM_Win32 constants() goes away + Moved .USESHELL to special_targets() override. + Everything else was redundant. + + - Added $(VERSION_FROM) to $(MAKEFILE) dependencies. Helpful for + XS builds where the version number is very sensitive. + - export_list(), perl_archive() and perl_archive_after() consolodated + into init_linker(). + - Added MM_NW5_VERSION, MM_Unix_VERSION, MM_Win32_VERSION, + MM_VMS_VERSION. + - Eliminated duplicate code in constants() overrides + - Added all_target() for easier customization of what's run by default + - Eliminated duplicate top_targets() overrides + - Made tool_autosplit() method portable. Moved to MM_Any. Eliminated + overrides. + - Adding realclean_subdirs target and realclean_subdirs_target() + method to generate same. This allows easier overriding of an + unportable part of the realclean target. + - Added oneliner() to create portable perl one-liners. + - Craig Berry found some typos in ExtUtils::Liblist::Kid's VMS part + * ExtUtils::Install did not work on MacPerl due to a hardcoded '.' + * prompt() will now read from STDIN. + - Craig Berry made sure extliblist() is always called even if LIBS + is explicitly set to empty. + * Added DESTDIR to make repacking easier. + * $(*PREFIX) are returned to the INSTALL* variables. + * Split $(PREFIX) into $(PERLPREFIX) and $(PREFIX). The former + holds the location of the core libraries. The latter is the + optional override prefix supplied by the user. + * PREFIX overrides all other *PREFIXes when set in the Makefile.PL. + This restores "make install PREFIX=foo". + - Added quote_literal() to handle some shell quoting. + - ExtUtils::MM_VMS now compilable on non-VMS platforms. + - J. D. Laub made MakeMaker honor $Config{installstyle} + - Renaming on OS/2 requires the target file to be removed. + Partially fixed by Ilya, should be applied universally later. + - Default MANIFEST.SKIP not catching files in subdirs. Fixed by Ilya. + - Ilya fixed ExtUtils::Liblist->ext when called outside MakeMaker. + - realclean was duplicating work already done by clean + - Adding an explicit LICENSE + - Cleaning up ExtUtils::Install docs. + - ExtUtils::Install::uninstall() now has default verbose and + dont_execute arguments. + - Added some basic ExtUtils::Install tests + - Fixed ExtUtils::Install::install() for relative dirs + - Added split_command() and max_exec_len() to deal with long + commands. + - Seperated escape_newlines() from quote_literal(). This may + be pointless. + - pm_to_blib() now generated with split_command(). 3x speedup. + - added init_dist() to initialize distribution constants + - ExtUtils::Install::pm_to_blib() working around open filehandle + bug in AutoSplit for systems with mandatory file locking. + +6.05 Tue Aug 27 16:09:51 PDT 2002 + - Output format of the hint file verbose diagnostic is now in + a format native to the OS, so it broke a test on non-Unixen. + +6.04 Mon Aug 26 18:31:11 PDT 2002 + - Little fix for pre-5.8 Cygwin test to get the shared library names + right. + * disttest on Win9X broken because of forgotten tabs + * WriteMakefile argument verification should now be accurate + - Documented the LD flag. + * Documented prompt() + * vendor install was not adding to packlist or updating perllocal. + - Supporting $Config{vendorarchexp} and $Config{vendorlibexp}. + - Fixed conflict on VMS between logical names and directories + (bleadperl 17488) + - Fixed space-vs-tab bug on Netware (bleadperl 17579) + - Mysterious NetWare fix from Ananth (bleadperl 17376) + - Support OPTIMIZE in MacOS (bleadperl 17347) + - Support hints in MacOS (mutation of bleadperl 17347) + * Default man installation directories were using $(MAN*EXT) to + generate the directory name. This turned out to be wrong more + often than right, so we'll use man1 and man3 hard-coded. + - Debian folks fixed the doc_install targets so the Appending + diagnostic gives the correct directory for perllocal.pod + * Added ExtUtils::MakeMaker::FAQ + - Quieted some warnings on MacOS (bleadperl 17669) + 6.03 Wed Jun 19 17:06:14 EDT 2002 - Documented that we're clamping down on cargo-cult MakeMaker programming. @@ -289,7 +549,7 @@ 5.50_01 Mon Mar 4 23:44:48 EST 2002 [[ API Changes ]] - htmlifypods and all HTML targets have been removed. It didn't + - htmlifypods and all HTML targets have been removed. It didn't work properly. A target for HTMLifying of docs will be added sometime in the future (read: send a patch). - Deprecated ROOTEXT variable removed (its been deprecated for diff --git a/lib/ExtUtils/Command.pm b/lib/ExtUtils/Command.pm index 829de16..b06430d 100644 --- a/lib/ExtUtils/Command.pm +++ b/lib/ExtUtils/Command.pm @@ -21,16 +21,16 @@ ExtUtils::Command - utilities to replace common UNIX commands in Makefiles etc. =head1 SYNOPSIS - perl -MExtUtils::Command -e cat files... > destination - perl -MExtUtils::Command -e mv source... destination - perl -MExtUtils::Command -e cp source... destination - perl -MExtUtils::Command -e touch files... - perl -MExtUtils::Command -e rm_f file... - perl -MExtUtils::Command -e rm_rf directories... - perl -MExtUtils::Command -e mkpath directories... - perl -MExtUtils::Command -e eqtime source destination - perl -MExtUtils::Command -e chmod mode files... - perl -MExtUtils::Command -e test_f file + perl -MExtUtils::Command -e cat files... > destination + perl -MExtUtils::Command -e mv source... destination + perl -MExtUtils::Command -e cp source... destination + perl -MExtUtils::Command -e touch files... + perl -MExtUtils::Command -e rm_f files... + perl -MExtUtils::Command -e rm_rf directories... + perl -MExtUtils::Command -e mkpath directories... + perl -MExtUtils::Command -e eqtime source destination + perl -MExtUtils::Command -e test_f file + perl -MExtUtils::Command=chmod -e chmod mode files... =head1 DESCRIPTION @@ -57,6 +57,7 @@ sub expand_wildcards @ARGV = map(/[$wild_regex]/o ? glob($_) : $_,@ARGV); } + =item cat Concatenates all files mentioned on command line to STDOUT. @@ -78,8 +79,7 @@ Sets modified time of dst to that of src sub eqtime { my ($src,$dst) = @ARGV; - open(F,">>$dst"); - close(F); + local @ARGV = ($dst); touch(); # in case $dst doesn't exist utime((stat($src))[8,9],$dst); } @@ -120,17 +120,14 @@ Makes files exist, with current timestamp =cut -sub touch -{ - my $t = time; - expand_wildcards(); - while (@ARGV) - { - my $file = shift(@ARGV); - open(FILE,">>$file") || die "Cannot write $file:$!"; - close(FILE); - utime($t,$t,$file); - } +sub touch { + my $t = time; + expand_wildcards(); + foreach my $file (@ARGV) { + open(FILE,">>$file") || die "Cannot write $file:$!"; + close(FILE); + utime($t,$t,$file); + } } =item mv source... destination @@ -140,16 +137,13 @@ Multiple sources are allowed if destination is an existing directory. =cut -sub mv -{ - my $dst = pop(@ARGV); - expand_wildcards(); - croak("Too many arguments") if (@ARGV > 1 && ! -d $dst); - while (@ARGV) - { - my $src = shift(@ARGV); - move($src,$dst); - } +sub mv { + my $dst = pop(@ARGV); + expand_wildcards(); + croak("Too many arguments") if (@ARGV > 1 && ! -d $dst); + foreach my $src (@ARGV) { + move($src,$dst); + } } =item cp source... destination @@ -159,29 +153,25 @@ Multiple sources are allowed if destination is an existing directory. =cut -sub cp -{ - my $dst = pop(@ARGV); - expand_wildcards(); - croak("Too many arguments") if (@ARGV > 1 && ! -d $dst); - while (@ARGV) - { - my $src = shift(@ARGV); - copy($src,$dst); - } +sub cp { + my $dst = pop(@ARGV); + expand_wildcards(); + croak("Too many arguments") if (@ARGV > 1 && ! -d $dst); + foreach my $src (@ARGV) { + copy($src,$dst); + } } =item chmod mode files... -Sets UNIX like permissions 'mode' on all the files. +Sets UNIX like permissions 'mode' on all the files. e.g. 0666 =cut -sub chmod -{ - my $mode = shift(@ARGV); - expand_wildcards(); - chmod($mode,@ARGV) || die "Cannot chmod ".join(' ',$mode,@ARGV).":$!"; +sub chmod { + my $mode = shift(@ARGV); + expand_wildcards(); + chmod(oct $mode,@ARGV) || die "Cannot chmod ".join(' ',$mode,@ARGV).":$!"; } =item mkpath directory... diff --git a/lib/ExtUtils/Command/MM.pm b/lib/ExtUtils/Command/MM.pm index 9eb7d29..4aa3738 100644 --- a/lib/ExtUtils/Command/MM.pm +++ b/lib/ExtUtils/Command/MM.pm @@ -7,8 +7,11 @@ require Exporter; use vars qw($VERSION @ISA @EXPORT); @ISA = qw(Exporter); -@EXPORT = qw(test_harness); -$VERSION = '0.01'; +@EXPORT = qw(test_harness pod2man perllocal_install uninstall + warn_if_old_packlist); +$VERSION = '0.02'; + +my $Is_VMS = $^O eq 'VMS'; =head1 NAME @@ -16,7 +19,7 @@ ExtUtils::Command::MM - Commands for the MM's to use in Makefiles =head1 SYNOPSIS - perl -MExtUtils::Command::MM -e "function" files... + perl "-MExtUtils::Command::MM" -e "function" "--" arguments... =head1 DESCRIPTION @@ -26,8 +29,6 @@ B The interface is not stable. ExtUtils::Command::MM encapsulates code which would otherwise have to be done with large "one" liners. -They all read their input from @ARGV unless otherwise noted. - Any $(FOO) used in the examples are make variables, not Perl. =over 4 @@ -54,6 +55,203 @@ sub test_harness { Test::Harness::runtests(sort { lc $a cmp lc $b } @ARGV); } + + +=item B + + pod2man( '--option=value', + $podfile1 => $manpage1, + $podfile2 => $manpage2, + ... + ); + + # or args on @ARGV + +pod2man() is a function performing most of the duties of the pod2man +program. Its arguments are exactly the same as pod2man as of 5.8.0 +with the addition of: + + --perm_rw octal permission to set the resulting manpage to + +And the removal of: + + --verbose/-v + --help/-h + +If no arguments are given to pod2man it will read from @ARGV. + +=cut + +sub pod2man { + require Pod::Man; + require Getopt::Long; + + my %options = (); + + # We will cheat and just use Getopt::Long. We fool it by putting + # our arguments into @ARGV. Should be safe. + local @ARGV = @_ ? @_ : @ARGV; + Getopt::Long::config ('bundling_override'); + Getopt::Long::GetOptions (\%options, + 'section|s=s', 'release|r=s', 'center|c=s', + 'date|d=s', 'fixed=s', 'fixedbold=s', 'fixeditalic=s', + 'fixedbolditalic=s', 'official|o', 'quotes|q=s', 'lax|l', + 'name|n=s', 'perm_rw:i' + ); + + # If there's no files, don't bother going further. + return 0 unless @ARGV; + + # Official sets --center, but don't override things explicitly set. + if ($options{official} && !defined $options{center}) { + $options{center} = 'Perl Programmers Reference Guide'; + } + + # This isn't a valid Pod::Man option and is only accepted for backwards + # compatibility. + delete $options{lax}; + + my $parser = Pod::Man->new(%options); + + do {{ # so 'next' works + my ($pod, $man) = splice(@ARGV, 0, 2); + + next if ((-e $man) && + (-M $man < -M $pod) && + (-M $man < -M "Makefile")); + + print "Manifying $man\n"; + + $parser->parse_from_file($pod, $man) + or do { warn("Could not install $man\n"); next }; + + if (length $options{perm_rw}) { + chmod(oct($options{perm_rw}), $man) + or do { warn("chmod $options{perm_rw} $man: $!\n"); next }; + } + }} while @ARGV; + + return 1; +} + + +=item B + + perl "-MExtUtils::Command::MM" -e warn_if_old_packlist + +Displays a warning that an old packlist file was found. Reads the +filename from @ARGV. + +=cut + +sub warn_if_old_packlist { + my $packlist = $ARGV[0]; + + return unless -f $packlist; + print <<"PACKLIST_WARNING"; +WARNING: I have found an old package in + $packlist. +Please make sure the two installations are not conflicting +PACKLIST_WARNING + +} + + +=item B + + perl "-MExtUtils::Command::MM" -e perllocal_install + ... + + # VMS only, key/value pairs come on STDIN + perl "-MExtUtils::Command::MM" -e perllocal_install + < ... + +Prints a fragment of POD suitable for appending to perllocal.pod. +Arguments are read from @ARGV. + +'type' is the type of what you're installing. Usually 'Module'. + +'module name' is simply the name of your module. (Foo::Bar) + +Key/value pairs are extra information about the module. Fields include: + + installed into which directory your module was out into + LINKTYPE dynamic or static linking + VERSION module version number + EXE_FILES any executables installed in a space seperated + list + +=cut + +sub perllocal_install { + my($type, $name) = splice(@ARGV, 0, 2); + + # VMS feeds args as a piped file on STDIN since it usually can't + # fit all the args on a single command line. + @ARGV = split /\|/, if $Is_VMS; + + my $pod; + $pod = sprintf < L<$name|$name> + + =over 4 + +POD + + do { + my($key, $val) = splice(@ARGV, 0, 2); + + $pod .= < + +POD + + } while(@ARGV); + + $pod .= "=back\n\n"; + $pod =~ s/^ //mg; + print $pod; + + return 1; +} + +=item B + + perl "-MExtUtils::Command::MM" -e uninstall + +A wrapper around ExtUtils::Install::uninstall(). Warns that +uninstallation is deprecated and doesn't actually perform the +uninstallation. + +=cut + +sub uninstall { + my($packlist) = shift; + + require ExtUtils::Install; + + print <<'WARNING'; + +Uninstall is unsafe and deprecated, the uninstallation was not performed. +We will show what would have been done. + +WARNING + + ExtUtils::Install::uninstall($packlist, 1, 1); + + print <<'WARNING'; + +Uninstall is unsafe and deprecated, the uninstallation was not performed. +Please check the list above carefully, there may be errors. +Remove the appropriate files manually. +Sorry for the inconvenience. + +WARNING + +} + =back =cut diff --git a/lib/ExtUtils/Install.pm b/lib/ExtUtils/Install.pm index b8fb4e3..757679a 100644 --- a/lib/ExtUtils/Install.pm +++ b/lib/ExtUtils/Install.pm @@ -2,14 +2,15 @@ package ExtUtils::Install; use 5.00503; use vars qw(@ISA @EXPORT $VERSION); -$VERSION = 1.29; +$VERSION = 1.31; use Exporter; use Carp (); use Config qw(%Config); @ISA = ('Exporter'); @EXPORT = ('install','uninstall','pm_to_blib', 'install_default'); -$Is_VMS = $^O eq 'VMS'; +$Is_VMS = $^O eq 'VMS'; +$Is_MacPerl = $^O eq 'MacOS'; my $splitchar = $^O eq 'VMS' ? '|' : ($^O eq 'os2' || $^O eq 'dos') ? ';' : ':'; my @PERL_ENV_LIB = split $splitchar, defined $ENV{'PERL5LIB'} ? $ENV{'PERL5LIB'} : $ENV{'PERLLIB'} || ''; @@ -20,33 +21,64 @@ my $Inc_uninstall_warn_handler; my $INSTALL_ROOT = $ENV{PERL_INSTALL_ROOT}; use File::Spec; +my $Curdir = File::Spec->curdir; +my $Updir = File::Spec->updir; -sub install_rooted_file { - if (defined $INSTALL_ROOT) { - File::Spec->catfile($INSTALL_ROOT, $_[0]); - } else { - $_[0]; - } -} -sub install_rooted_dir { - if (defined $INSTALL_ROOT) { - File::Spec->catdir($INSTALL_ROOT, $_[0]); - } else { - $_[0]; - } -} +=head1 NAME -#our(@EXPORT, @ISA, $Is_VMS); -#use strict; +ExtUtils::Install - install files from here to there -sub forceunlink { - chmod 0666, $_[0]; - unlink $_[0] or Carp::croak("Cannot forceunlink $_[0]: $!") -} +=head1 SYNOPSIS + + use ExtUtils::Install; + + install({ 'blib/lib' => 'some/install/dir' } ); + + uninstall($packlist); + + pm_to_blib({ 'lib/Foo/Bar.pm' => 'blib/lib/Foo/Bar.pm' }); + + +=head1 DESCRIPTION + +Handles the installing and uninstalling of perl modules, scripts, man +pages, etc... + +Both install() and uninstall() are specific to the way +ExtUtils::MakeMaker handles the installation and deinstallation of +perl modules. They are not designed as general purpose tools. + +=head2 Functions + +=over 4 + +=item B + + install(\%from_to); + install(\%from_to, $verbose, $dont_execute); + +Copies each directory tree of %from_to to its corresponding value +preserving timestamps and permissions. + +There are two keys with a special meaning in the hash: "read" and +"write". These contain packlist files. After the copying is done, +install() will write the list of target files to $from_to{write}. If +$from_to{read} is given the contents of this file will be merged into +the written file. The read and the written file may be identical, but +on AFS it is quite likely that people are installing to a different +directory than the one where the files later appear. + +If $verbose is true, will print out each file removed. Default is +false. + +If $dont_execute is true it will only print what it was going to do +without actually doing it. Default is false. + +=cut sub install { - my($hash,$verbose,$nonono,$inc_uninstall) = @_; + my($from_to,$verbose,$nonono,$inc_uninstall) = @_; $verbose ||= 0; $nonono ||= 0; @@ -57,32 +89,31 @@ sub install { use File::Find qw(find); use File::Path qw(mkpath); use File::Compare qw(compare); - use File::Spec; - my(%hash) = %$hash; + my(%from_to) = %$from_to; my(%pack, $dir, $warn_permissions); my($packlist) = ExtUtils::Packlist->new(); # -w doesn't work reliably on FAT dirs $warn_permissions++ if $^O eq 'MSWin32'; local(*DIR); for (qw/read write/) { - $pack{$_}=$hash{$_}; - delete $hash{$_}; + $pack{$_}=$from_to{$_}; + delete $from_to{$_}; } my($source_dir_or_file); - foreach $source_dir_or_file (sort keys %hash) { + foreach $source_dir_or_file (sort keys %from_to) { #Check if there are files, and if yes, look if the corresponding #target directory is writable for us opendir DIR, $source_dir_or_file or next; for (readdir DIR) { - next if $_ eq "." || $_ eq ".." || $_ eq ".exists"; - my $targetdir = install_rooted_dir($hash{$source_dir_or_file}); + next if $_ eq $Curdir || $_ eq $Updir || $_ eq ".exists"; + my $targetdir = install_rooted_dir($from_to{$source_dir_or_file}); if (-w $targetdir || mkpath($targetdir)) { last; } else { warn "Warning: You do not have permissions to " . - "install into $hash{$source_dir_or_file}" + "install into $from_to{$source_dir_or_file}" unless $warn_permissions++; } } @@ -92,8 +123,7 @@ sub install { $packlist->read($tmpfile) if (-f $tmpfile); my $cwd = cwd(); - my($source); - MOD_INSTALL: foreach $source (sort keys %hash) { + MOD_INSTALL: foreach my $source (sort keys %from_to) { #copy the tree to the target directory without altering #timestamp and permission and remember for the .packlist #file. The packlist file contains the absolute paths of the @@ -104,29 +134,37 @@ sub install { #there are any files in arch. So we depend on having ./blib/arch #hardcoded here. - my $targetroot = install_rooted_dir($hash{$source}); + my $targetroot = install_rooted_dir($from_to{$source}); - if ($source eq "blib/lib" and - exists $hash{"blib/arch"} and - directory_not_empty("blib/arch")) { - $targetroot = install_rooted_dir($hash{"blib/arch"}); - print "Files found in blib/arch: installing files in blib/lib into architecture dependent library tree\n"; + my $blib_lib = File::Spec->catdir('blib', 'lib'); + my $blib_arch = File::Spec->catdir('blib', 'arch'); + if ($source eq $blib_lib and + exists $from_to{$blib_arch} and + directory_not_empty($blib_arch)) { + $targetroot = install_rooted_dir($from_to{$blib_arch}); + print "Files found in $blib_arch: installing files in $blib_lib into architecture dependent library tree\n"; } - chdir($source) or next; + + chdir $source or next; find(sub { - my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, - $atime,$mtime,$ctime,$blksize,$blocks) = stat; + my ($mode,$size,$atime,$mtime) = (stat)[2,7,8,9]; return unless -f _; return if $_ eq ".exists"; my $targetdir = File::Spec->catdir($targetroot, $File::Find::dir); my $targetfile = File::Spec->catfile($targetdir, $_); + my $sourcedir = File::Spec->catdir($source, $File::Find::dir); + my $sourcefile = File::Spec->catfile($sourcedir, $_); + + my $save_cwd = cwd; + chdir $cwd; # in case the target is relative + # 5.5.3's File::Find missing no_chdir option. my $diff = 0; if ( -f $targetfile && -s _ == $size) { # We have a good chance, we can skip this one - $diff = compare($_,$targetfile); + $diff = compare($sourcefile, $targetfile); } else { - print "$_ differs\n" if $verbose>1; + print "$sourcefile differs\n" if $verbose>1; $diff++; } @@ -137,7 +175,7 @@ sub install { mkpath($targetdir,0,0755) unless $nonono; print "mkpath($targetdir,0,0755)\n" if $verbose>1; } - copy($_,$targetfile) unless $nonono; + copy($sourcefile, $targetfile) unless $nonono; print "Installing $targetfile\n"; utime($atime,$mtime + $Is_VMS,$targetfile) unless $nonono>1; print "utime($atime,$mtime,$targetfile)\n" if $verbose>1; @@ -147,17 +185,20 @@ sub install { } else { print "Skipping $targetfile (unchanged)\n" if $verbose; } - - if (! defined $inc_uninstall) { # it's called - } elsif ($inc_uninstall == 0){ - inc_uninstall($_,$File::Find::dir,$verbose,1); # nonono set to 1 - } else { - inc_uninstall($_,$File::Find::dir,$verbose,0); # nonono set to 0 + + if (defined $inc_uninstall) { + inc_uninstall($sourcefile,$File::Find::dir,$verbose, + $inc_uninstall ? 0 : 1); } + # Record the full pathname. $packlist->{$targetfile}++; - }, "."); + # File::Find can get confused if you chdir in here. + chdir $save_cwd; + + # File::Find seems to always be Unixy except on MacPerl :( + }, $Is_MacPerl ? $Curdir : '.' ); chdir($cwd) or Carp::croak("Couldn't chdir to $cwd: $!"); } if ($pack{'write'}) { @@ -168,6 +209,30 @@ sub install { } } +sub install_rooted_file { + if (defined $INSTALL_ROOT) { + File::Spec->catfile($INSTALL_ROOT, $_[0]); + } else { + $_[0]; + } +} + + +sub install_rooted_dir { + if (defined $INSTALL_ROOT) { + File::Spec->catdir($INSTALL_ROOT, $_[0]); + } else { + $_[0]; + } +} + + +sub forceunlink { + chmod 0666, $_[0]; + unlink $_[0] or Carp::croak("Cannot forceunlink $_[0]: $!") +} + + sub directory_not_empty ($) { my($dir) = @_; my $files = 0; @@ -181,6 +246,28 @@ sub directory_not_empty ($) { return $files; } + +=item B I + + install_default(); + install_default($fullext); + +Calls install() with arguments to copy a module from blib/ to the +default site installation location. + +$fullext is the name of the module converted to a directory +(ie. Foo::Bar would be Foo/Bar). If $fullext is not specified, it +will attempt to read it from @ARGV. + +This is primarily useful for install scripts. + +B This function is not really useful because of the hard-coded +install location with no way to control site vs core vs vendor +directories and the strange way in which the module name is given. +Consider its use discouraged. + +=cut + sub install_default { @_ < 2 or die "install_default should be called with 0 or 1 argument"; my $FULLEXT = @_ ? shift : $ARGV[0]; @@ -205,9 +292,28 @@ sub install_default { },1,0,0); } + +=item B + + uninstall($packlist_file); + uninstall($packlist_file, $verbose, $dont_execute); + +Removes the files listed in a $packlist_file. + +If $verbose is true, will print out each file removed. Default is +false. + +If $dont_execute is true it will only print what it was going to do +without actually doing it. Default is false. + +=cut + sub uninstall { use ExtUtils::Packlist; my($fil,$verbose,$nonono) = @_; + $verbose ||= 0; + $nonono ||= 0; + die "no packlist file found: $fil" unless -f $fil; # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al)); # require $my_req; # Hairy, but for the first @@ -229,7 +335,7 @@ sub inc_uninstall { privlibexp sitearchexp sitelibexp)}) { - next if $dir eq "."; + next if $dir eq $Curdir; next if $seen_dir{$dir}++; my($targetfile) = File::Spec->catfile($dir,$libdir,$file); next unless -f $targetfile; @@ -251,7 +357,10 @@ sub inc_uninstall { if ($verbose) { $Inc_uninstall_warn_handler ||= new ExtUtils::Install::Warn; $libdir =~ s|^\./||s ; # That's just cosmetics, no need to port. It looks prettier. - $Inc_uninstall_warn_handler->add("$libdir/$file",$targetfile); + $Inc_uninstall_warn_handler->add( + File::Spec->catfile($libdir, $file), + $targetfile + ); } # if not verbose, we just say nothing } else { @@ -274,6 +383,24 @@ sub run_filter { close CMD or die "Filter command '$cmd' failed for $src"; } + +=item B + + pm_to_blib(\%from_to, $autosplit_dir); + pm_to_blib(\%from_to, $autosplit_dir, $filter_cmd); + +Copies each key of %from_to to its corresponding value efficiently. +Filenames with the extension .pm are autosplit into the $autosplit_dir. + +$filter_cmd is an optional shell command to run each .pm file through +prior to splitting and copying. Input is the contents of the module, +output the new module contents. + +You can have an environment variable PERL_INSTALL_ROOT set which will +be prepended as a directory to each installed file (and directory). + +=cut + sub pm_to_blib { my($fromto,$autodir,$pm_filter) = @_; @@ -297,41 +424,62 @@ sub pm_to_blib { } mkpath($autodir,0,0755); - foreach (keys %$fromto) { - my $dest = $fromto->{$_}; - next if -f $dest && -M $dest < -M $_; + while(my($from, $to) = each %$fromto) { + next if -f $to && -M $to < -M $from; # When a pm_filter is defined, we need to pre-process the source first # to determine whether it has changed or not. Therefore, only perform # the comparison check when there's no filter to be ran. # -- RAM, 03/01/2001 - my $need_filtering = defined $pm_filter && length $pm_filter && /\.pm$/; + my $need_filtering = defined $pm_filter && length $pm_filter && + $from =~ /\.pm$/; - if (!$need_filtering && 0 == compare($_,$dest)) { - print "Skip $dest (unchanged)\n"; + if (!$need_filtering && 0 == compare($from,$to)) { + print "Skip $to (unchanged)\n"; next; } - if (-f $dest){ - forceunlink($dest); + if (-f $to){ + forceunlink($to); } else { - mkpath(dirname($dest),0,0755); + mkpath(dirname($to),0,0755); } if ($need_filtering) { - run_filter($pm_filter, $_, $dest); - print "$pm_filter <$_ >$dest\n"; + run_filter($pm_filter, $from, $to); + print "$pm_filter <$from >$to\n"; } else { - copy($_,$dest); - print "cp $_ $dest\n"; + copy($from,$to); + print "cp $from $to\n"; } - my($mode,$atime,$mtime) = (stat)[2,8,9]; - utime($atime,$mtime+$Is_VMS,$dest); - chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$dest); - next unless /\.pm$/; - autosplit($dest,$autodir); + my($mode,$atime,$mtime) = (stat $from)[2,8,9]; + utime($atime,$mtime+$Is_VMS,$to); + chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$to); + next unless $from =~ /\.pm$/; + _autosplit($to,$autodir); } } + +=begin _private + +=item _autosplit + +From 1.0307 back, AutoSplit will sometimes leave an open filehandle to +the file being split. This causes problems on systems with mandatory +locking (ie. Windows). So we wrap it and close the filehandle. + +=end _private + +=cut + +sub _autosplit { + my $retval = autosplit(@_); + close *AutoSplit::IN if defined *AutoSplit::IN{IO}; + + return $retval; +} + + package ExtUtils::Install::Warn; sub new { bless {}, shift } @@ -342,87 +490,57 @@ sub add { } sub DESTROY { - unless(defined $INSTALL_ROOT) { - my $self = shift; - my($file,$i,$plural); - foreach $file (sort keys %$self) { - $plural = @{$self->{$file}} > 1 ? "s" : ""; - print "## Differing version$plural of $file found. You might like to\n"; - for (0..$#{$self->{$file}}) { - print "rm ", $self->{$file}[$_], "\n"; - $i++; - } - } - $plural = $i>1 ? "all those files" : "this file"; - print "## Running 'make install UNINST=1' will unlink $plural for you.\n"; - } + unless(defined $INSTALL_ROOT) { + my $self = shift; + my($file,$i,$plural); + foreach $file (sort keys %$self) { + $plural = @{$self->{$file}} > 1 ? "s" : ""; + print "## Differing version$plural of $file found. You might like to\n"; + for (0..$#{$self->{$file}}) { + print "rm ", $self->{$file}[$_], "\n"; + $i++; + } + } + $plural = $i>1 ? "all those files" : "this file"; + print "## Running 'make install UNINST=1' will unlink $plural for you.\n"; + } } -1; +=back -__END__ -=head1 NAME +=head1 ENVIRONMENT -ExtUtils::Install - install files from here to there +=over 4 -=head1 SYNOPSIS +=item B -B +Will be prepended to each install path. -B +=back -B +=head1 AUTHOR -B +Original author lost in the mists of time. Probably the same as Makemaker. -=head1 DESCRIPTION +Currently maintained by Michael G Schwern > -Both install() and uninstall() are specific to the way -ExtUtils::MakeMaker handles the installation and deinstallation of -perl modules. They are not designed as general purpose tools. +Send patches and ideas to >. -install() takes three arguments. A reference to a hash, a verbose -switch and a don't-really-do-it switch. The hash ref contains a -mapping of directories: each key/value pair is a combination of -directories to be copied. Key is a directory to copy from, value is a -directory to copy to. The whole tree below the "from" directory will -be copied preserving timestamps and permissions. +Send bug reports via http://rt.cpan.org/. Please send your +generated Makefile along with your report. -There are two keys with a special meaning in the hash: "read" and -"write". After the copying is done, install will write the list of -target files to the file named by C<$hashref-E{write}>. If there is -another file named by C<$hashref-E{read}>, the contents of this file will -be merged into the written file. The read and the written file may be -identical, but on AFS it is quite likely that people are installing to a -different directory than the one where the files later appear. - -install_default() takes one or less arguments. If no arguments are -specified, it takes $ARGV[0] as if it was specified as an argument. -The argument is the value of MakeMaker's C key, like F. -This function calls install() with the same arguments as the defaults -the MakeMaker would use. - -The argument-less form is convenient for install scripts like - - perl -MExtUtils::Install -e install_default Tk/Canvas - -Assuming this command is executed in a directory with a populated F -directory, it will proceed as if the F was build by MakeMaker on -this machine. This is useful for binary distributions. - -uninstall() takes as first argument a file containing filenames to be -unlinked. The second argument is a verbose switch, the third is a -no-don't-really-do-it-now switch. - -pm_to_blib() takes a hashref as the first argument and copies all keys -of the hash to the corresponding values efficiently. Filenames with -the extension pm are autosplit. Second argument is the autosplit -directory. If third argument is not empty, it is taken as a filter command -to be ran on each .pm file, the output of the command being what is finally -copied, and the source for auto-splitting. +For more up-to-date information, see http://www.makemaker.org. + + +=head1 LICENSE + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +See F -You can have an environment variable PERL_INSTALL_ROOT set which will -be prepended as a directory to each installed file (and directory). =cut + +1; diff --git a/lib/ExtUtils/Liblist.pm b/lib/ExtUtils/Liblist.pm index de79088..8604f82 100644 --- a/lib/ExtUtils/Liblist.pm +++ b/lib/ExtUtils/Liblist.pm @@ -7,12 +7,18 @@ use File::Spec; require ExtUtils::Liblist::Kid; @ISA = qw(ExtUtils::Liblist::Kid File::Spec); +# Backwards compatibility with old interface. +sub ext { + goto &ExtUtils::Liblist::Kid::ext; +} + sub lsdir { shift; my $rex = qr/$_[1]/; opendir DIR, $_[0]; - grep /$rex/, readdir DIR; + my @out = grep /$rex/, readdir DIR; closedir DIR; + return @out; } __END__ @@ -23,9 +29,12 @@ ExtUtils::Liblist - determine libraries to use and how to use them =head1 SYNOPSIS -C + require ExtUtils::Liblist; + + $MM->ext($potential_libs, $verbose, $need_names); -C + # Usually you can get away with: + ExtUtils::Liblist->ext($potential_libs, $verbose, $need_names) =head1 DESCRIPTION diff --git a/lib/ExtUtils/Liblist/Kid.pm b/lib/ExtUtils/Liblist/Kid.pm index a7e4c2d..d17eb87 100644 --- a/lib/ExtUtils/Liblist/Kid.pm +++ b/lib/ExtUtils/Liblist/Kid.pm @@ -24,6 +24,8 @@ sub ext { sub _unix_os2_ext { my($self,$potential_libs, $verbose, $give_libs) = @_; + $verbose ||= 0; + if ($^O =~ 'os2' and $Config{perllibs}) { # Dynamic libraries are not transitive, so we may need including # the libraries linked against perl.dll again. @@ -34,8 +36,8 @@ sub _unix_os2_ext { return ("", "", "", "", ($give_libs ? [] : ())) unless $potential_libs; warn "Potential libraries are '$potential_libs':\n" if $verbose; - my($so) = $Config{'so'}; - my($libs) = $Config{'perllibs'}; + my($so) = $Config{so}; + my($libs) = defined $Config{perllibs} ? $Config{perllibs} : $Config{libs}; my $Config_libext = $Config{lib_ext} || ".a"; @@ -157,7 +159,7 @@ sub _unix_os2_ext { # what do we know about this library... my $is_dyna = ($fullname !~ /\Q$Config_libext\E\z/); - my $in_perl = ($libs =~ /\B-l\Q$ {thislib}\E\b/s); + my $in_perl = ($libs =~ /\B-l\Q${thislib}\E\b/s); # Do not add it into the list if it is already linked in # with the main perl executable. @@ -212,6 +214,7 @@ sub _win32_ext { require Text::ParseWords; my($self, $potential_libs, $verbose, $give_libs) = @_; + $verbose ||= 0; # If user did not supply a list, we punt. # (caller should probably use the list in $Config{libs}) @@ -340,7 +343,7 @@ sub _win32_ext { # give up warn "Note (probably harmless): " - ."No library found for '$thislib'\n" + ."No library found for $thislib\n" unless $found_lib>0; } @@ -364,9 +367,11 @@ sub _win32_ext { sub _vms_ext { my($self, $potential_libs,$verbose,$give_libs) = @_; + $verbose ||= 0; + my(@crtls,$crtlstr); my($dbgqual) = $self->{OPTIMIZE} || $Config{'optimize'} || - $self->{CCFLAS} || $Config{'ccflags'}; + $self->{CCFLAGS} || $Config{'ccflags'}; @crtls = ( ($dbgqual =~ m-/Debug-i ? $Config{'dbgprefix'} : '') . 'PerlShr/Share' ); push(@crtls, grep { not /\(/ } split /\s+/, $Config{'perllibs'}); @@ -398,8 +403,8 @@ sub _vms_ext { my(@dirs,@libs,$dir,$lib,%found,@fndlibs,$ldlib); my $cwd = cwd(); my($so,$lib_ext,$obj_ext) = @Config{'so','lib_ext','obj_ext'}; - # List of common Unix library names and there VMS equivalents - # (VMS equivalent of '' indicates that the library is automatially + # List of common Unix library names and their VMS equivalents + # (VMS equivalent of '' indicates that the library is automatically # searched by the linker, and should be skipped here.) my(@flibs, %libs_seen); my %libmap = ( 'm' => '', 'f77' => '', 'F77' => '', 'V77' => '', 'c' => '', diff --git a/lib/ExtUtils/MANIFEST.SKIP b/lib/ExtUtils/MANIFEST.SKIP index 61dde53..a916b62 100644 --- a/lib/ExtUtils/MANIFEST.SKIP +++ b/lib/ExtUtils/MANIFEST.SKIP @@ -2,16 +2,17 @@ \bRCS\b \bCVS\b ,v$ +\B\.svn\b # Avoid Makemaker generated and utility files. -^MANIFEST\.bak -^Makefile$ -^blib/ -^MakeMaker-\d -^pm_to_blib$ +\bMANIFEST\.bak +\bMakefile$ +\bblib/ +\bMakeMaker-\d +\bpm_to_blib$ # Avoid temp and backup files. ~$ \.old$ \#$ -^\.# +\b\.# diff --git a/lib/ExtUtils/MM_Any.pm b/lib/ExtUtils/MM_Any.pm index fb48ae2..20c6bd6 100644 --- a/lib/ExtUtils/MM_Any.pm +++ b/lib/ExtUtils/MM_Any.pm @@ -3,6 +3,7 @@ package ExtUtils::MM_Any; use strict; use vars qw($VERSION @ISA); $VERSION = 0.04; +@ISA = qw(File::Spec); use Config; use File::Spec; @@ -41,95 +42,372 @@ B These are methods which are by their nature cross-platform and should always be cross-platform. -=head2 File::Spec wrappers B +=head2 File::Spec wrappers -The following methods are deprecated wrappers around File::Spec -functions. They exist from before File::Spec did and in fact are from -which File::Spec sprang. +ExtUtils::MM_Any is a subclass of File::Spec. The methods noted here +override File::Spec. -They are all deprecated. Please use File::Spec directly. +=over 4 + +=item catfile + +File::Spec <= 0.83 has a bug where the file part of catfile is not +canonicalized. This override fixes that bug. + +=cut + +sub catfile { + my $self = shift; + return $self->canonpath($self->SUPER::catfile(@_)); +} + +=back + +=head1 Thought To Be Cross-Platform Methods + +These are methods which are thought to be cross-platform by virtue of +having been written in a way to avoid incompatibilities. They may +require partial overrides. =over 4 -=item canonpath +=item B + + my @cmds = $MM->split_command($cmd, @args); + +Most OS have a maximum command length they can execute at once. Large +modules can easily generate commands well past that limit. Its +necessary to split long commands up into a series of shorter commands. + +split_command() will return a series of @cmds each processing part of +the args. Collectively they will process all the arguments. Each +individual line in @cmds will not be longer than the +$self->max_exec_len being careful to take into account macro expansion. + +$cmd should include any switches and repeated initial arguments. + +If no @args are given, no @cmds will be returned. + +Pairs of arguments will always be preserved in a single command, this +is a heuristic for things like pm_to_blib and pod2man which work on +pairs of arguments. This makes things like this safe: + + $self->split_command($cmd, %pod2man); + =cut -sub canonpath { - shift; - return File::Spec->canonpath(@_);; +sub split_command { + my($self, $cmd, @args) = @_; + + my @cmds = (); + return(@cmds) unless @args; + + # If the command was given as a here-doc, there's probably a trailing + # newline. + chomp $cmd; + + # set aside 20% for macro expansion. + my $len_left = int($self->max_exec_len * 0.80); + $len_left -= length $self->_expand_macros($cmd); + + do { + my $arg_str = ''; + my @next_args; + while( @next_args = splice(@args, 0, 2) ) { + # Two at a time to preserve pairs. + my $next_arg_str = "\t ". join ' ', @next_args, "\n"; + + if( !length $arg_str ) { + $arg_str .= $next_arg_str + } + elsif( length($arg_str) + length($next_arg_str) > $len_left ) { + unshift @args, @next_args; + last; + } + else { + $arg_str .= $next_arg_str; + } + } + chop $arg_str; + + push @cmds, $self->escape_newlines("$cmd\n$arg_str"); + } while @args; + + return @cmds; } -=item catdir + +sub _expand_macros { + my($self, $cmd) = @_; + + $cmd =~ s{\$\((\w+)\)}{ + defined $self->{$1} ? $self->{$1} : "\$($1)" + }e; + return $cmd; +} + + +=item B + + my @commands = $MM->echo($text); + my @commands = $MM->echo($text, $file); + my @commands = $MM->echo($text, $file, $appending); + +Generates a set of @commands which print the $text to a $file. + +If $file is not given, output goes to STDOUT. + +If $appending is true the $file will be appended to rather than +overwritten. =cut -sub catdir { - shift; - return File::Spec->catdir(@_); +sub echo { + my($self, $text, $file, $appending) = @_; + $appending ||= 0; + + my @cmds = map { '$(NOECHO) $(ECHO) '.$self->quote_literal($_) } + split /\n/, $text; + if( $file ) { + my $redirect = $appending ? '>>' : '>'; + $cmds[0] .= " $redirect $file"; + $_ .= " >> $file" foreach @cmds[1..$#cmds]; + } + + return @cmds; } -=item catfile + +=item init_VERSION + + $mm->init_VERSION + +Initialize macros representing versions of MakeMaker and other tools + +MAKEMAKER: path to the MakeMaker module. + +MM_VERSION: ExtUtils::MakeMaker Version + +MM_REVISION: ExtUtils::MakeMaker version control revision (for backwards + compat) + +VERSION: version of your module + +VERSION_MACRO: which macro represents the version (usually 'VERSION') + +VERSION_SYM: like version but safe for use as an RCS revision number + +DEFINE_VERSION: -D line to set the module version when compiling + +XS_VERSION: version in your .xs file. Defaults to $(VERSION) + +XS_VERSION_MACRO: which macro represents the XS version. + +XS_DEFINE_VERSION: -D line to set the xs version when compiling. + +Called by init_main. =cut -sub catfile { - shift; - return File::Spec->catfile(@_); +sub init_VERSION { + my($self) = shift; + + $self->{MAKEMAKER} = $INC{'ExtUtils/MakeMaker.pm'}; + $self->{MM_VERSION} = $ExtUtils::MakeMaker::VERSION; + $self->{MM_REVISION}= $ExtUtils::MakeMaker::Revision; + $self->{VERSION_FROM} ||= ''; + + if ($self->{VERSION_FROM}){ + $self->{VERSION} = $self->parse_version($self->{VERSION_FROM}); + if( $self->{VERSION} eq 'undef' ) { + require Carp; + Carp::carp("WARNING: Setting VERSION via file ". + "'$self->{VERSION_FROM}' failed\n"); + } + } + + # strip blanks + if (defined $self->{VERSION}) { + $self->{VERSION} =~ s/^\s+//; + $self->{VERSION} =~ s/\s+$//; + } + else { + $self->{VERSION} = ''; + } + + + $self->{VERSION_MACRO} = 'VERSION'; + ($self->{VERSION_SYM} = $self->{VERSION}) =~ s/\W/_/g; + $self->{DEFINE_VERSION} = '-D$(VERSION_MACRO)=\"$(VERSION)\"'; + + + # Graham Barr and Paul Marquess had some ideas how to ensure + # version compatibility between the *.pm file and the + # corresponding *.xs file. The bottomline was, that we need an + # XS_VERSION macro that defaults to VERSION: + $self->{XS_VERSION} ||= $self->{VERSION}; + + $self->{XS_VERSION_MACRO} = 'XS_VERSION'; + $self->{XS_DEFINE_VERSION} = '-D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"'; + } -=item curdir +=item wraplist + +Takes an array of items and turns them into a well-formatted list of +arguments. In most cases this is simply something like: + + FOO \ + BAR \ + BAZ =cut -my $Curdir = File::Spec->curdir; -sub curdir { - return $Curdir; +sub wraplist { + my $self = shift; + return join " \\\n\t", @_; } -=item file_name_is_absolute +=item manifypods + +Defines targets and routines to translate the pods into manpages and +put them into the INST_* directories. =cut -sub file_name_is_absolute { - shift; - return File::Spec->file_name_is_absolute(@_); +sub manifypods { + my $self = shift; + + my $POD2MAN_EXE_macro = $self->POD2MAN_EXE_macro(); + my $manifypods_target = $self->manifypods_target(); + + return <manifypods_target; + +Generates the manifypods target. This target generates man pages from +all POD files in MAN1PODS and MAN3PODS. =cut -sub path { - return File::Spec->path(); +sub manifypods_target { + my($self) = shift; + + my $man1pods = ''; + my $man3pods = ''; + my $dependencies = ''; + + # populate manXpods & dependencies: + foreach my $name (keys %{$self->{MAN1PODS}}, keys %{$self->{MAN3PODS}}) { + $dependencies .= " \\\n\t$name"; + } + + foreach my $name (keys %{$self->{MAN3PODS}}) { + $dependencies .= " \\\n\t$name" + } + + my $manify = <{"MAN${section}PODS"}; + push @man_cmds, $self->split_command(<makemakerdflt_target + +Returns a make fragment with the makemakerdeflt_target specified. +This target is the first target in the Makefile, is the default target +and simply points off to 'all' just in case any make variant gets +confused or something gets snuck in before the real 'all' target. =cut -my $Rootdir = File::Spec->rootdir; -sub rootdir { - return $Rootdir; +sub makemakerdflt_target { + return <<'MAKE_FRAG'; +makemakerdflt: all + $(NOECHO) $(NOOP) +MAKE_FRAG + } -=item updir + +=item special_targets + + my $make_frag = $mm->special_targets + +Returns a make fragment containing any targets which have special +meaning to make. For example, .SUFFIXES and .PHONY. =cut -my $Updir = File::Spec->updir; -sub updir { - return $Updir; +sub special_targets { + my $make_frag = <<'MAKE_FRAG'; +.SUFFIXES: .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT) + +.PHONY: all config static dynamic test linkext manifest + +MAKE_FRAG + + $make_frag .= <<'MAKE_FRAG' if $ENV{CLEARCASE_ROOT}; +.NO_CONFIG_REC: Makefile + +MAKE_FRAG + + return $make_frag; } -=back +=item POD2MAN_EXE_macro -=head1 Thought To Be Cross-Platform Methods + my $pod2man_exe_macro = $self->POD2MAN_EXE_macro -These are methods which are thought to be cross-platform by virtue of -having been written in a way to avoid incompatibilities. +Returns a definition for the POD2MAN_EXE macro. This is a program +which emulates the pod2man utility. You can add more switches to the +command by simply appending them on the macro. + +Typical usage: + + $(POD2MAN_EXE) --section=3 --perm_rw=$(PERM_RW) podfile man_page + +=cut + +sub POD2MAN_EXE_macro { + my $self = shift; + +# Need the trailing '--' so perl stops gobbling arguments and - happens +# to be an alternative end of line seperator on VMS so we quote it + return <<'END_OF_DEF'; +POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--" +END_OF_DEF +} -=over 4 =item test_via_harness @@ -167,12 +445,324 @@ sub test_via_script { return qq{\t$perl "-I\$(INST_LIB)" "-I\$(INST_ARCHLIB)" $script\n}; } +=item libscan + + my $wanted = $self->libscan($path); + +Takes a path to a file or dir and returns an empty string if we don't +want to include this file in the library. Otherwise it returns the +the $path unchanged. + +Mainly used to exclude RCS, CVS, and SCCS directories from +installation. + +=cut + +sub libscan { + my($self,$path) = @_; + my($dirs,$file) = ($self->splitpath($path))[1,2]; + return '' if grep /^RCS|CVS|SCCS|\.svn$/, + $self->splitdir($dirs), $file; + + return $path; +} + +=item tool_autosplit + +Defines a simple perl call that runs autosplit. May be deprecated by +pm_to_blib soon. + +=cut + +sub tool_autosplit { + my($self, %attribs) = @_; + + my $maxlen = $attribs{MAXLEN} ? '$$AutoSplit::Maxlen=$attribs{MAXLEN};' + : ''; + + my $asplit = $self->oneliner(sprintf <<'PERL_CODE', $maxlen); +use AutoSplit; %s autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1) +PERL_CODE + + return sprintf <<'MAKE_FRAG', $asplit; +# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto +AUTOSPLITFILE = %s + +MAKE_FRAG + +} + + +=item all_target + +Generate the default target 'all'. + +=cut + +sub all_target { + my $self = shift; + + return <<'MAKE_EXT'; +all :: pure_all + $(NOECHO) $(NOOP) +MAKE_EXT + +} + + +=item metafile_target + + my $target = $mm->metafile_target; + +Generate the metafile target. + +Writes the file META.yml, YAML encoded meta-data about the module. The +format follows Module::Build's as closely as possible. Additionally, we +include: + + version_from + installdirs + +=cut + +sub metafile_target { + my $self = shift; + + my $prereq_pm = ''; + while( my($mod, $ver) = each %{$self->{PREREQ_PM}} ) { + $prereq_pm .= sprintf " %-30s %s\n", "$mod:", $ver; + } + + my $meta = <{DISTNAME} +version: $self->{VERSION} +version_from: $self->{VERSION_FROM} +installdirs: $self->{INSTALLDIRS} +requires: +$prereq_pm +distribution_type: module +generated_by: ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION +YAML + + my @write_meta = $self->echo($meta, 'META.yml'); + return sprintf <<'MAKE_FRAG', join "\n\t", @write_meta; +metafile : + %s +MAKE_FRAG + +} + + +=item metafile_addtomanifest_target + + my $target = $mm->metafile_addtomanifest_target + +Adds the META.yml file to the MANIFEST. + +=cut + +sub metafile_addtomanifest_target { + my $self = shift; + + my $add_meta = $self->oneliner(<<'CODE', ['-MExtUtils::Manifest=maniadd']); +maniadd({q{META.yml} => q{Module meta-data in YAML}}); +CODE + + return sprintf <<'MAKE_FRAG', $add_meta; +metafile_addtomanifest: + $(NOECHO) %s +MAKE_FRAG + +} + + +=back + +=head2 Abstract methods + +Methods which cannot be made cross-platform and each subclass will +have to do their own implementation. + +=over 4 + +=item oneliner + + my $oneliner = $MM->oneliner($perl_code); + my $oneliner = $MM->oneliner($perl_code, \@switches); + +This will generate a perl one-liner safe for the particular platform +you're on based on the given $perl_code and @switches (a -e is +assumed) suitable for using in a make target. It will use the proper +shell quoting and escapes. + +$(PERLRUN) will be used as perl. + +Any newlines in $perl_code will be escaped. Leading and trailing +newlines will be stripped. Makes this idiom much easier: + + my $code = $MM->oneliner(<<'CODE', [...switches...]); +some code here +another line here +CODE + +Usage might be something like: + + # an echo emulation + $oneliner = $MM->oneliner('print "Foo\n"'); + $make = '$oneliner > somefile'; + +All dollar signs must be doubled in the $perl_code if you expect them +to be interpreted normally, otherwise it will be considered a make +macro. Also remember to quote make macros else it might be used as a +bareword. For example: + + # Assign the value of the $(VERSION_FROM) make macro to $vf. + $oneliner = $MM->oneliner('$$vf = "$(VERSION_FROM)"'); + +Its currently very simple and may be expanded sometime in the figure +to include more flexible code and switches. + + +=item B + + my $safe_text = $MM->quote_literal($text); + +This will quote $text so it is interpreted literally in the shell. + +For example, on Unix this would escape any single-quotes in $text and +put single-quotes around the whole thing. + + +=item B + + my $escaped_text = $MM->escape_newlines($text); + +Shell escapes newlines in $text. + + +=item max_exec_len + + my $max_exec_len = $MM->max_exec_len; + +Calculates the maximum command size the OS can exec. Effectively, +this is the max size of a shell command line. + +=for _private +$self->{_MAX_EXEC_LEN} is set by this method, but only for testing purposes. + +=item B + + $MM->init_others(); + +Initializes the macro definitions used by tools_other() and places them +in the $MM object. + +If there is no description, its the same as the parameter to +WriteMakefile() documented in ExtUtils::MakeMaker. + +Defines at least these macros. + + Macro Description + + NOOP + NOECHO + + MAKEFILE + FIRST_MAKEFILE + MAKEFILE_OLD + MAKE_APERL_FILE File used by MAKE_APERL + + SHELL Program used to run + shell commands + + RM_F Remove a file + RM_RF Remove a directory + TOUCH Update a file's timestamp + TEST_F Test for a file's existence + CP Copy a file + MV Move a file + CHMOD Change permissions on a + file + + UMASK_NULL Nullify umask + DEV_NULL Supress all command output + +=item init_DIRFILESEP + + $MM->init_DIRFILESEP; + my $dirfilesep = $MM->{DIRFILESEP}; + +Initializes the DIRFILESEP macro which is the seperator between the +directory and filename in a filepath. ie. / on Unix, \ on Win32 and +nothing on VMS. + +For example: + + # instead of $(INST_ARCHAUTODIR)/extralibs.ld + $(INST_ARCHAUTODIR)$(DIRFILESEP)extralibs.ld + +Something of a hack but it prevents a lot of code duplication between +MM_* variants. + +Do not use this as a seperator between directories. Some operating +systems use different seperators between subdirectories as between +directories and filenames (for example: VOLUME:[dir1.dir2]file on VMS). + +=item init_linker + + $mm->init_linker; + +Initialize macros which have to do with linking. + +PERL_ARCHIVE: path to libperl.a equivalent to be linked to dynamic +extensions. + +PERL_ARCHIVE_AFTER: path to a library which should be put on the +linker command line I the external libraries to be linked to +dynamic extensions. This may be needed if the linker is one-pass, and +Perl includes some overrides for C RTL functions, such as malloc(). + +EXPORT_LIST: name of a file that is passed to linker to define symbols +to be exported. + +Some OSes do not need these in which case leave it blank. + + +=item init_platform + + $mm->init_platform + +Initialize any macros which are for platform specific use only. + +A typical one is the version number of your OS specific mocule. +(ie. MM_Unix_VERSION or MM_VMS_VERSION). + +=item platform_constants + + my $make_frag = $mm->platform_constants + +Returns a make fragment defining all the macros initialized in +init_platform() rather than put them in constants(). + +=cut + +sub init_platform { + return ''; +} + +sub platform_constants { + return ''; +} + + =back =head1 AUTHOR -Michael G Schwern with code from ExtUtils::MM_Unix -and ExtUtils::MM_Win32. +Michael G Schwern and the denizens of +makemaker@perl.org with code from ExtUtils::MM_Unix and +ExtUtils::MM_Win32. =cut diff --git a/lib/ExtUtils/MM_BeOS.pm b/lib/ExtUtils/MM_BeOS.pm index 5118747..4f4a3e5 100644 --- a/lib/ExtUtils/MM_BeOS.pm +++ b/lib/ExtUtils/MM_BeOS.pm @@ -28,18 +28,20 @@ use vars qw(@ISA $VERSION); $VERSION = 1.03; -=item perl_archive +=item init_linker -This is internal method that returns path to libperl.a equivalent -to be linked to dynamic extensions. UNIX does not have one, but at -least BeOS has one. +libperl.a equivalent to be linked to dynamic extensions. =cut -sub perl_archive - { - return File::Spec->catdir('$(PERL_INC)',$Config{libperl}); - } +sub init_linker { + my($self) = shift; + + $self->{PERL_ARCHIVE} ||= + File::Spec->catdir('$(PERL_INC)',$Config{libperl}); + $self->{PERL_ARCHIVE_AFTER} ||= ''; + $self->{EXPORT_LIST} ||= ''; +} =back diff --git a/lib/ExtUtils/MM_Cygwin.pm b/lib/ExtUtils/MM_Cygwin.pm index 3c37ffd..120e1bb 100644 --- a/lib/ExtUtils/MM_Cygwin.pm +++ b/lib/ExtUtils/MM_Cygwin.pm @@ -10,7 +10,28 @@ require ExtUtils::MM_Any; require ExtUtils::MM_Unix; @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); -$VERSION = 1.04; +$VERSION = 1.05; + + +=head1 NAME + +ExtUtils::MM_Cygwin - methods to override UN*X behaviour in ExtUtils::MakeMaker + +=head1 SYNOPSIS + + use ExtUtils::MM_Cygwin; # Done internally by ExtUtils::MakeMaker if needed + +=head1 DESCRIPTION + +See ExtUtils::MM_Unix for a documentation of the methods provided there. + +=over 4 + +=item cflags (o) + +if configured for dynamic loading, triggers #define EXT in EXTERN.h + +=cut sub cflags { my($self,$libperl)=@_; @@ -31,97 +52,45 @@ PERLTYPE = $self->{PERLTYPE} } -sub manifypods { - my($self, %attribs) = @_; - return "\nmanifypods : pure_all\n\t$self->{NOECHO}\$(NOOP)\n" unless - %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}}; - my($dist); - my($pod2man_exe); - if (defined $self->{PERL_SRC}) { - $pod2man_exe = File::Spec->catfile($self->{PERL_SRC},'pod','pod2man'); - } else { - $pod2man_exe = File::Spec->catfile($Config{scriptdirexp},'pod2man'); - } - unless ($self->perl_script($pod2man_exe)) { - # No pod2man but some MAN3PODS to be installed - print <{MAKEFILE}, q[";' \\ --e 'print "Manifying $$m{$$_}\n"; $$m{$$_} =~ s/::/./g;' \\ --e 'system(qq[$(PERLRUN) $(POD2MAN_EXE) ].qq[$$_>$$m{$$_}])==0 or warn "Couldn\\047t install $$m{$$_}\n";' \\ --e 'chmod(oct($(PERM_RW))), $$m{$$_} or warn "chmod $(PERM_RW) $$m{$$_}: $$!\n";}' -]; - push @m, "\nmanifypods : pure_all "; - push @m, join " \\\n\t", keys %{$self->{MAN1PODS}}, - keys %{$self->{MAN3PODS}}; - - push(@m,"\n"); - if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) { - grep { $self->{MAN1PODS}{$_} =~ s/::/./g } keys %{$self->{MAN1PODS}}; - grep { $self->{MAN3PODS}{$_} =~ s/::/./g } keys %{$self->{MAN3PODS}}; - push @m, "\t$self->{NOECHO}\$(POD2MAN) \\\n\t"; - push @m, join " \\\n\t", %{$self->{MAN1PODS}}, %{$self->{MAN3PODS}}; - } - join('', @m); +replaces strings '::' with '.' in MAN*POD man page names + +=cut + +sub replace_manpage_separator { + my($self, $man) = @_; + $man =~ s{/+}{.}g; + return $man; } -sub perl_archive { +=item init_linker + +points to libperl.a + +=cut + +sub init_linker { + my $self = shift; + if ($Config{useshrplib} eq 'true') { my $libperl = '$(PERL_INC)' .'/'. "$Config{libperl}"; if( $] >= 5.007 ) { $libperl =~ s/a$/dll.a/; } - return $libperl; + $self->{PERL_ARCHIVE} = $libperl; } else { - return '$(PERL_INC)' .'/'. ("$Config{libperl}" or "libperl.a"); + $self->{PERL_ARCHIVE} = + '$(PERL_INC)' .'/'. ("$Config{libperl}" or "libperl.a"); } -} - -1; -__END__ - -=head1 NAME - -ExtUtils::MM_Cygwin - methods to override UN*X behaviour in ExtUtils::MakeMaker - -=head1 SYNOPSIS - - use ExtUtils::MM_Cygwin; # Done internally by ExtUtils::MakeMaker if needed - -=head1 DESCRIPTION -See ExtUtils::MM_Unix for a documentation of the methods provided there. - -=over 4 - -=item canonpath - -replaces backslashes with forward ones. then acts as *nixish. - -=item cflags - -if configured for dynamic loading, triggers #define EXT in EXTERN.h - -=item manifypods - -replaces strings '::' with '.' in man page names - -=item perl_archive - -points to libperl.a + $self->{PERL_ARCHIVE_AFTER} ||= ''; + $self->{EXPORT_LIST} ||= ''; +} =back =cut +1; diff --git a/lib/ExtUtils/MM_DOS.pm b/lib/ExtUtils/MM_DOS.pm index 7af868e..93e01f2 100644 --- a/lib/ExtUtils/MM_DOS.pm +++ b/lib/ExtUtils/MM_DOS.pm @@ -32,6 +32,8 @@ Unless otherwise stated, it works just like ExtUtils::MM_Unix =item B +Generates Foo__Bar.3 style man page names + =cut sub replace_manpage_separator { @@ -52,4 +54,5 @@ Michael G Schwern with code from ExtUtils::MM_Unix L, L =cut + 1; diff --git a/lib/ExtUtils/MM_MacOS.pm b/lib/ExtUtils/MM_MacOS.pm index 576d744..a83e37f 100644 --- a/lib/ExtUtils/MM_MacOS.pm +++ b/lib/ExtUtils/MM_MacOS.pm @@ -12,13 +12,12 @@ require ExtUtils::MM_Unix; @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); use vars qw($VERSION); -$VERSION = '1.03'; +$VERSION = '1.04'; use Config; use Cwd 'cwd'; require Exporter; use File::Basename; -use File::Spec; use vars qw(%make_data); my $Mac_FS = eval { require Mac::FileSpec::Unixish }; @@ -37,6 +36,8 @@ ExtUtils::MM_MacOS - methods to override UN*X behaviour in ExtUtils::MakeMaker MM_MacOS currently only produces an approximation to the correct Makefile. +=over 4 + =cut sub new { @@ -51,7 +52,7 @@ sub new { mkdir("Obj", 0777) unless -d "Obj"; - $self = {} unless (defined $self); + $self = {} unless defined $self; check_hints($self); @@ -61,7 +62,8 @@ sub new { if (ref $self->{CONFIGURE} eq 'CODE') { $self = { %$self, %{&{$self->{CONFIGURE}}}}; } else { - Carp::croak "Attribute 'CONFIGURE' to WriteMakefile() not a code reference\n"; + require Carp; + Carp::croak("Attribute 'CONFIGURE' to WriteMakefile() not a code reference\n"); } } @@ -78,7 +80,7 @@ sub new { } $ExtUtils::MakeMaker::Recognized_Att_Keys{$_} = 1 - for map { $_ . 'Optimize' } qw(MWC MWCPPC MWC68K MPW MRC MRC SC); + for map { $_ . 'Optimize' } qw(MWC MWCPPC MWC68K MPW MRC MRC SC); if (defined $ExtUtils::MakeMaker::Parent[-2]){ $self->{PARENT} = $ExtUtils::MakeMaker::Parent[-2]; @@ -86,7 +88,7 @@ sub new { for $key (@ExtUtils::MakeMaker::Prepend_parent) { next unless defined $self->{PARENT}{$key}; $self->{$key} = $self->{PARENT}{$key}; - unless ($^O eq 'VMS' && $key =~ /PERL$/) { + if ($key !~ /PERL$/) { $self->{$key} = $self->catdir("..",$self->{$key}) unless $self->file_name_is_absolute($self->{$key}); } else { @@ -130,7 +132,7 @@ sub new { # This Makefile is for the $self->{NAME} extension to perl. # # It was generated automatically by MakeMaker version -# $VERSION (Revision: $Revision) from the contents of +# $ExtUtils::MakeMaker::VERSION (Revision: $ExtUtils::MakeMaker::Revision) from the contents of # Makefile.PL. Don't edit this file, edit Makefile.PL instead. # # ANY CHANGES MADE HERE WILL BE LOST! @@ -158,10 +160,10 @@ END pasthru c_o xs_c xs_o top_targets linkext dynamic_bs dynamic_lib static_lib manifypods installbin subdirs dist_basics dist_core - dist_dir dist_test dist_ci install force perldepend makefile - staticmake test pm_to_blib selfdocument + distdir dist_test dist_ci install force perldepend makefile + staticmake test pm_to_blib selfdocument const_loadlibs const_cccmd - /) + /) { $self->{SKIPHASH}{$_} = 2; } @@ -169,7 +171,7 @@ END unless grep /rulez/, @ExtUtils::MakeMaker::MM_Sections; if ($self->{PARENT}) { - for (qw/install dist dist_basics dist_core dist_dir dist_test dist_ci/) { + for (qw/install dist dist_basics dist_core distdir dist_test dist_ci/) { $self->{SKIPHASH}{$_} = 1; } } @@ -182,7 +184,8 @@ END my $section; foreach $section ( @ExtUtils::MakeMaker::MM_Sections ){ - next if ($self->{SKIPHASH}{$section} == 2); + next if defined $self->{SKIPHASH}{$section} && + $self->{SKIPHASH}{$section} == 2; print "Processing Makefile '$section' section\n" if ($Verbose >= 2); $self->{ABSTRACT_FROM} = macify($self->{ABSTRACT_FROM}) if $self->{ABSTRACT_FROM}; @@ -242,7 +245,7 @@ sub guess_name { =item macify -Translate relative path names into Mac names. +Translate relative Unix filepaths into Mac names. =cut @@ -268,7 +271,7 @@ sub macify { =item patternify -Translate to Mac names & patterns +Translate Unix filepaths and shell globs to Mac style. =cut @@ -291,7 +294,7 @@ sub patternify { =item init_main -Initializes some of NAME, FULLEXT, BASEEXT, ROOTEXT, DLBASE, PERL_SRC, +Initializes some of NAME, FULLEXT, BASEEXT, DLBASE, PERL_SRC, PERL_LIB, PERL_ARCHLIB, PERL_INC, INSTALLDIRS, INST_*, INSTALL*, PREFIX, CONFIG, AR, AR_STATIC_ARGS, LD, OBJ_EXT, LIB_EXT, MAP_TARGET, LIBPERL_A, VERSION_FROM, VERSION, DISTNAME, VERSION_SYM. @@ -306,14 +309,10 @@ sub init_main { # NAME = The perl module name for this extension (eg DBD::Oracle). # FULLEXT = Pathname for extension directory (eg DBD/Oracle). # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. - # ROOTEXT = Directory part of FULLEXT with trailing :. ($self->{FULLEXT} = $self->{NAME}) =~ s!::!:!g ; #eg. BSD:Foo:Socket ($self->{BASEEXT} = $self->{NAME}) =~ s!.*::!! ; #eg. Socket - ($self->{ROOTEXT} = - $self->{FULLEXT}) =~ s#:?\Q$self->{BASEEXT}\E$## ; #eg. BSD:Foo - $self->{ROOTEXT} .= ":" if ($self->{ROOTEXT}); # --- Initialize PERL_LIB, INST_LIB, PERL_SRC @@ -339,21 +338,15 @@ sub init_main { } } if ($self->{PERL_SRC}){ - $self->{MACPERL_SRC} = File::Spec->catdir("$self->{PERL_SRC}","macos:"); - $self->{MACPERL_LIB} ||= File::Spec->catdir("$self->{MACPERL_SRC}","lib"); - $self->{PERL_LIB} ||= File::Spec->catdir("$self->{PERL_SRC}","lib"); + $self->{PERL_LIB} ||= $self->catdir("$self->{PERL_SRC}","lib"); $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; $self->{PERL_INC} = $self->{PERL_SRC}; - $self->{MACPERL_INC} = $self->{MACPERL_SRC}; } else { # hmmmmmmm ... ? - $self->{PERL_LIB} ||= "$ENV{MACPERL}site_perl"; - $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; - $self->{PERL_INC} = $ENV{MACPERL}; -# die <{PERL_LIB} ||= "$ENV{MACPERL}site_perl"; + $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; + $self->{PERL_INC} = $ENV{MACPERL}; + $self->{PERL_SRC} = ''; } $self->{INSTALLDIRS} = "perl"; @@ -368,12 +361,13 @@ sub init_main { # hm ... do we really care? at all? # warn "Warning: PERL_LIB ($self->{PERL_LIB}) seems not to be a perl library directory # (Exporter.pm not found)" -# unless -f File::Spec->catfile("$self->{PERL_LIB}","Exporter.pm") || +# unless -f $self->catfile("$self->{PERL_LIB}","Exporter.pm") || # $self->{NAME} eq "ExtUtils::MakeMaker"; # Determine VERSION and VERSION_FROM ($self->{DISTNAME}=$self->{NAME}) =~ s#(::)#-#g unless $self->{DISTNAME}; if ($self->{VERSION_FROM}){ + # XXX replace with parse_version() override local *FH; open(FH,macify($self->{VERSION_FROM})) or die "Could not open '$self->{VERSION_FROM}' (attribute VERSION_FROM): $!"; @@ -410,18 +404,32 @@ sub init_main { # XS_VERSION macro that defaults to VERSION: $self->{XS_VERSION} ||= $self->{VERSION}; + + $self->{DEFINE} .= " \$(XS_DEFINE_VERSION) \$(DEFINE_VERSION)"; + + # Preprocessor definitions may be useful + $self->{DEFINE} =~ s/-D/-d /g; + + # UN*X includes probably are not useful + $self->{DEFINE} =~ s/-I\S+/_include($1)/eg; + + + if ($self->{INC}) { + # UN*X includes probably are not useful + $self->{INC} =~ s/-I(\S+)/_include($1)/eg; + } + + # --- Initialize Perl Binary Locations # Find Perl 5. The only contract here is that both 'PERL' and 'FULLPERL' # will be working versions of perl 5. miniperl has priority over perl # for PERL to ensure that $(PERL) is usable while building ./ext/* my ($component,@defpath); - foreach $component ($self->{PERL_SRC}, File::Spec->path(), $Config::Config{binexp}) { + foreach $component ($self->{PERL_SRC}, $self->path(), $Config::Config{binexp}) { push @defpath, $component if defined $component; } $self->{PERL} = "$self->{PERL_SRC}miniperl"; - $self->{FULLPERL} = "$self->{PERL_SRC}perl"; - $self->{MAKEFILE} = "Makefile.mk"; } =item init_others @@ -457,6 +465,51 @@ sub init_others { # --- Initialize Other Attributes } } $self->{SOURCE} = $src; + $self->{FULLPERL} = "$self->{PERL_SRC}perl"; + $self->{MAKEFILE} = "Makefile.mk"; + $self->{FIRST_MAKEFILE} = $self->{MAKEFILE}; + $self->{MAKEFILE_OLD} = $self->{MAKEFILE}.'.old'; + + $self->{'DEV_NULL'} ||= ' \xB3 Dev:Null'; + + return 1; +} + +=item init_platform + +Add MACPERL_SRC MACPERL_LIB + +=item platform_constants + +Add MACPERL_SRC MACPERL_LIB MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC +MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED + +XXX Few are initialized. How many of these are ever used? + +=cut + +sub init_platform { + my $self = shift; + + $self->{MACPERL_SRC} = $self->catdir("$self->{PERL_SRC}","macos:"); + $self->{MACPERL_LIB} ||= $self->catdir("$self->{MACPERL_SRC}","lib"); + $self->{MACPERL_INC} = $self->{MACPERL_SRC}; +} + + + +sub platform_constants { + my $self = shift; + + foreach my $macro (qw(MACPERL_SRC MACPERL_LIB MACLIBS_68K MACLIBS_PPC + MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K + MACLIBS_ALL_PPC MACLIBS_SHARED)) + { + next unless defined $self->{$macro}; + $make_frag .= "$macro = $self->{$macro}\n"; + } + + return $make_frag; } @@ -474,7 +527,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) # in case we don't find it below! if ($self->{VERSION_FROM}) { my $version_from = macify($self->{VERSION_FROM}); - $pm{$version_from} = File::Spec->catfile('$(INST_LIBDIR)', + $pm{$version_from} = $self->catfile('$(INST_LIBDIR)', $version_from); } @@ -494,7 +547,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) } elsif ($name =~ /\.h$/i){ $h{$name} = 1; } elsif ($name =~ /\.(p[ml]|pod)$/){ - $pm{$name} = File::Spec->catfile('$(INST_LIBDIR)',$name); + $pm{$name} = $self->catfile('$(INST_LIBDIR)',$name); } elsif ($name =~ /\.PL$/ && $name ne "Makefile.PL") { ($pl_files{$name} = $name) =~ s/\.PL$// ; } @@ -523,8 +576,8 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) # # In this way the 'lib' directory is seen as the root of the actual # perl library whereas the others are relative to INST_LIBDIR - # (which includes ROOTEXT). This is a subtle distinction but one - # that's important for nested modules. + # This is a subtle distinction but one that's important for nested + # modules. $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}] unless $self->{PMLIBDIRS}; @@ -544,7 +597,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) require File::Find; File::Find::find(sub { if (-d $_){ - if ($_ eq "CVS" || $_ eq "RCS"){ + unless ($self->libscan($_)){ $File::Find::prune = 1; } return; @@ -553,7 +606,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) my($striplibpath,$striplibname); $prefix = '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:); ($striplibname,$striplibpath) = fileparse($striplibpath); - my($inst) = File::Spec->catfile($prefix,$striplibpath,$striplibname); + my($inst) = $self->catfile($prefix,$striplibpath,$striplibname); local($_) = $inst; # for backwards compatibility $inst = $self->libscan($inst); print "libscan($path) => '$inst'\n" if ($Verbose >= 2); @@ -578,103 +631,39 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) } } -=item libscan (o) - -Takes a path to a file that is found by init_dirscan and returns false -if we don't want to include this file in the library. Mainly used to -exclude RCS, CVS, and SCCS directories from installation. -=cut - -# '; - -sub libscan { - my($self,$path) = @_; - return '' if $path =~ m/:(RCS|CVS|SCCS):/ ; - $path; -} +=item init_VERSION (o) -=item constants (o) - -Initializes lots of constants and .SUFFIXES and .PHONY +Change DEFINE_VERSION and XS_DEFINE_VERSION =cut -sub constants { - my($self) = @_; - my(@m,$tmp); - - for $tmp (qw/ - NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION - INST_LIB INST_ARCHLIB PERL_LIB PERL_SRC MACPERL_SRC MACPERL_LIB PERL FULLPERL - XSPROTOARG MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED SOURCE TYPEMAPS - / ) { - next unless defined $self->{$tmp}; - if ($tmp eq 'TYPEMAPS' && ref $self->{$tmp}) { - push @m, sprintf "$tmp = %s\n", join " ", @{$self->{$tmp}}; - } else { - push @m, "$tmp = $self->{$tmp}\n"; - } - } +sub init_VERSION { + my $self = shift; - push @m, q{ -MODULES = }.join(" \\\n\t", sort keys %{$self->{PM}})."\n"; - push @m, "PMLIBDIRS = @{$self->{PMLIBDIRS}}\n" if @{$self->{PMLIBDIRS}}; + $self->SUPER::init_VERSION; - push @m, ' + $self->{DEFINE_VERSION} = '-d $(VERSION_MACRO)="¶"$(VERSION)¶""'; + $self->{XS_DEFINE_VERSION} = '-d $(XS_VERSION_MACRO)="¶"$(XS_VERSION)¶""'; +} -.INCLUDE : $(MACPERL_SRC)BuildRules.mk -'; +=item special_targets (o) - push @m, qq{ -VERSION_MACRO = VERSION -DEFINE_VERSION = -d \$(VERSION_MACRO)="¶"\$(VERSION)¶"" -XS_VERSION_MACRO = XS_VERSION -XS_DEFINE_VERSION = -d \$(XS_VERSION_MACRO)="¶"\$(XS_VERSION)¶"" -}; +Add .INCLUDE - $self->{DEFINE} .= " \$(XS_DEFINE_VERSION) \$(DEFINE_VERSION)"; +=cut - push @m, qq{ -MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'} -MM_VERSION = $ExtUtils::MakeMaker::VERSION -}; - - push @m, q{ -# FULLEXT = Pathname for extension directory (eg DBD:Oracle). -# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. -# ROOTEXT = Directory part of FULLEXT (eg DBD) -# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. -}; - - if ($self->{DEFINE}) { - $self->{DEFINE} =~ s/-D/-d /g; # Preprocessor definitions may be useful - $self->{DEFINE} =~ s/-I\S+/_include($1)/eg; # UN*X includes probably are not useful - } - if ($self->{INC}) { - $self->{INC} =~ s/-I(\S+)/_include($1)/eg; # UN*X includes probably are not useful - } - for $tmp (qw/ - FULLEXT BASEEXT ROOTEXT DEFINE INC - / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; - } +sub special_targets { + my $self = shift; - push @m, " -# Handy lists of source code files: -XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})." -C_FILES = ".join(" \\\n\t", @{$self->{C}})." -H_FILES = ".join(" \\\n\t", @{$self->{H}})." -"; + my $make_frag = $self->SUPER::special_targets; - push @m, ' + return $make_frag . <<'MAKE_FRAG'; +.INCLUDE : $(MACPERL_SRC)BuildRules.mk $(MACPERL_SRC)ExtBuildRules.mk -.INCLUDE : $(MACPERL_SRC)ExtBuildRules.mk -'; +MAKE_FRAG - join('',@m); } =item static (o) @@ -765,32 +754,56 @@ sub clean { # Delete temporary files but do not touch installed files. We don\'t delete # the Makefile here so a later make realclean still has a makefile to use. -clean :: +clean :: clean_subdirs '); - # clean subdirectories first - for $dir (@{$self->{DIR}}) { - push @m, -" Set OldEcho \{Echo\} - Set Echo 0 - Directory $dir - If \"\`Exists -f $self->{MAKEFILE}\`\" != \"\" - \$(MAKE) clean - End - Set Echo \{OldEcho\} - "; - } my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; push @m, "\t\$(RM_RF) @otherfiles\n"; # See realclean and ext/utils/make_ext for usage of Makefile.old push(@m, - "\t\$(MV) $self->{MAKEFILE} $self->{MAKEFILE}.old\n"); + "\t\$(MV) \$(FIRST_MAKEFILE) \$(MAKEFILE_OLD)\n"); push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; join("", @m); } +=item clean_subdirs_target + +MacOS semantics for changing directories and checking for existence +very different than everyone else. + +=cut + +sub clean_subdirs_target { + my($self) = shift; + + # No subdirectories, no cleaning. + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +clean_subdirs : + $(NOECHO)$(NOOP) +NOOP_FRAG + + + my $clean = "clean_subdirs :\n"; + + for my $dir (@{$self->{DIR}}) { + $clean .= sprintf <<'MAKE_FRAG', $dir; + Set OldEcho {Echo} + Set Echo 0 + Directory %s + If "`Exists -f $(FIRST_MAKEFILE)`" != "" + $(MAKE) clean + End + Set Echo {OldEcho} + +MAKE_FRAG + } + + return $clean; +} + + =item realclean (o) Defines the realclean target. @@ -804,28 +817,50 @@ sub realclean { # Delete temporary files (via clean) and also delete installed files realclean purge :: clean '); - # realclean subdirectories first (already cleaned) - my $sub = -" Set OldEcho \{Echo\} + + my(@otherfiles) = ('$(FIRST_MAKEFILE)', '$(MAKEFILE_OLD)'); # Makefiles last + push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; + push(@m, "\t\$(RM_RF) @otherfiles\n") if @otherfiles; + push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; + join("", @m); +} + + +=item realclean_subdirs_target + +MacOS semantics for changing directories and checking for existence +very different than everyone else. + +=cut + +sub realclean_subdirs_target { + my $self = shift; + + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +realclean_subdirs : + $(NOECHO)$(NOOP) +NOOP_FRAG + + my $rclean = "realclean_subdirs :\n"; + + foreach my $dir (@{$self->{DIR}}){ + $rclean .= sprintf <<'RCLEAN', $dir, + Set OldEcho \{Echo\} Set Echo 0 Directory %s - If \"\`Exists -f %s\`\" != \"\" + If \"\`Exists -f $(FIRST_MAKEFILE)\`\" != \"\" \$(MAKE) realclean End Set Echo \{OldEcho\} - "; - foreach(@{$self->{DIR}}){ - push(@m, sprintf($sub,$_,"$self->{MAKEFILE}.old","-f $self->{MAKEFILE}.old")); - push(@m, sprintf($sub,$_,"$self->{MAKEFILE}",'')); + +RCLEAN + } - my(@otherfiles) = ($self->{MAKEFILE}, - "$self->{MAKEFILE}.old"); # Makefiles last - push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; - push(@m, "\t\$(RM_RF) @otherfiles\n") if @otherfiles; - push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; - join("", @m); + + return $rclean; } + =item rulez (o) =cut @@ -863,7 +898,7 @@ sub processPL { foreach $target (@$list) { push @m, " ProcessPL :: $target -\t$self->{NOECHO}\$(NOOP) +\t$(NOECHO)\$(NOOP) $target :: $plfile \t\$(PERL) -I\$(MACPERL_LIB) -I\$(PERL_LIB) $plfile $target @@ -875,15 +910,16 @@ $target :: $plfile sub cflags { my($self,$libperl) = @_; - my $optimize; + my $optimize = ''; for (map { $_ . "Optimize" } qw(MWC MWCPPC MWC68K MPW MRC MRC SC)) { - $optimize .= "$_ = $self->{$_}" if exists $self->{$_}; + $optimize .= "$_ = $self->{$_}" if exists $self->{$_}; } return $self->{CFLAGS} = $optimize; } + sub _include { # for Unix-style includes, with -I instead of -i my($inc) = @_; require File::Spec::Unix; @@ -896,45 +932,8 @@ sub _include { # for Unix-style includes, with -I instead of -i } } -# yes, these are just copies of the same routines in -# MakeMaker.pm, but with paths changed. -sub check_hints { - my($self) = @_; - # We allow extension-specific hints files. - - return unless -d ":hints"; - - # First we look for the best hintsfile we have - my($hint)="${^O}_$Config{osvers}"; - $hint =~ s/\./_/g; - $hint =~ s/_$//; - return unless $hint; - - # Also try without trailing minor version numbers. - while (1) { - last if -f ":hints:$hint.pl"; # found - } continue { - last unless $hint =~ s/_[^_]*$//; # nothing to cut off - } - my $hint_file = ":hints:$hint.pl"; - - return unless -f $hint_file; # really there - - _run_hintfile($self, $hint_file); -} +=back -sub _run_hintfile { - no strict 'vars'; - local($self) = shift; # make $self available to the hint file. - my($hint_file) = shift; +=cut - local $@; - print STDERR "Processing hints file $hint_file\n"; - my $ret = do $hint_file; - unless( defined $ret ) { - print STDERR $@ if $@; - } -} 1; - -__END__ diff --git a/lib/ExtUtils/MM_NW5.pm b/lib/ExtUtils/MM_NW5.pm index 7f13dd0..40c4823 100644 --- a/lib/ExtUtils/MM_NW5.pm +++ b/lib/ExtUtils/MM_NW5.pm @@ -37,17 +37,34 @@ my $GCC = 1 if $Config{'cc'} =~ /^gcc/i; my $DMAKE = 1 if $Config{'make'} =~ /^dmake/i; -sub init_others { - my ($self) = @_; - $self->SUPER::init_others(@_); +=item init_platform (o) + +Add Netware macros. + +LIBPTH, BASE_IMPORT, NLM_VERSION, MPKTOOL, TOOLPATH, BOOT_SYMBOL, +NLM_SHORT_NAME, INCLUDE, PATH, MM_NW5_REVISION + + +=item platform_constants + +Add Netware macros initialized above to the Makefile. + +=cut + +sub init_platform { + my($self) = shift; + + # To get Win32's setup. + $self->SUPER::init_platform; # incpath is copied to makefile var INCLUDE in constants sub, here just # make it empty my $libpth = $Config{'libpth'}; $libpth =~ s( )(;); $self->{'LIBPTH'} = $libpth; + $self->{'BASE_IMPORT'} = $Config{'base_import'}; - + # Additional import file specified from Makefile.pl if($self->{'base_import'}) { $self->{'BASE_IMPORT'} .= ', ' . $self->{'base_import'}; @@ -56,188 +73,61 @@ sub init_others { $self->{'NLM_VERSION'} = $Config{'nlm_version'}; $self->{'MPKTOOL'} = $Config{'mpktool'}; $self->{'TOOLPATH'} = $Config{'toolpath'}; -} - - -=item constants (o) - -Initializes lots of constants and .SUFFIXES and .PHONY - -=cut - -sub const_cccmd { - my($self,$libperl)=@_; - return $self->{CONST_CCCMD} if $self->{CONST_CCCMD}; - return '' unless $self->needs_linking(); - return $self->{CONST_CCCMD} = <<'MAKE_FRAG'; -CCCMD = $(CC) $(CCFLAGS) $(INC) $(OPTIMIZE) \ - $(PERLTYPE) $(MPOLLUTE) -o $@ \ - -DVERSION=\"$(VERSION)\" -DXS_VERSION=\"$(XS_VERSION)\" -MAKE_FRAG - -} - -sub constants { - my($self) = @_; - my(@m,$tmp); - -# Added LIBPTH, BASE_IMPORT, ABSTRACT, NLM_VERSION BOOT_SYMBOL, NLM_SHORT_NAME -# for NETWARE - - for $tmp (qw/ - - AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION - VERSION_SYM XS_VERSION INST_BIN INST_LIB - INST_ARCHLIB INST_SCRIPT PREFIX INSTALLDIRS - INSTALLPRIVLIB INSTALLARCHLIB INSTALLSITELIB - INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB - PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB - FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC - PERL_INC PERL FULLPERL LIBPTH BASE_IMPORT PERLRUN - FULLPERLRUN PERLRUNINST FULLPERLRUNINST - FULL_AR PERL_CORE NLM_VERSION MPKTOOL TOOLPATH - - / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; - } (my $boot = $self->{'NAME'}) =~ s/:/_/g; $self->{'BOOT_SYMBOL'}=$boot; - push @m, "BOOT_SYMBOL = $self->{'BOOT_SYMBOL'}\n"; # If the final binary name is greater than 8 chars, # truncate it here. if(length($self->{'BASEEXT'}) > 8) { $self->{'NLM_SHORT_NAME'} = substr($self->{'BASEEXT'},0,8); - push @m, "NLM_SHORT_NAME = $self->{'NLM_SHORT_NAME'}\n"; } - push @m, qq{ -VERSION_MACRO = VERSION -DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\" -XS_VERSION_MACRO = XS_VERSION -XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\" -}; - # Get the include path and replace the spaces with ; # Copy this to makefile as INCLUDE = d:\...;d:\; - (my $inc = $Config{'incpath'}) =~ s/([ ]*)-I/;/g; - - # Get the additional include path from the user through the command prompt - # and append to INCLUDE -# $self->{INC} = ''; - push @m, "INC = $self->{'INC'}\n"; - - push @m, qq{ -INCLUDE = $inc; -}; + ($self->{INCLUDE} = $Config{'incpath'}) =~ s/([ ]*)-I/;/g; # Set the path to CodeWarrior binaries which might not have been set in # any other place - push @m, qq{ -PATH = \$(PATH);\$(TOOLPATH) -}; - - push @m, qq{ -MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'} -MM_VERSION = $ExtUtils::MakeMaker::VERSION -}; - - push @m, q{ -# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). -# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) -# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) -# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. -}; - - for $tmp (qw/ - FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT - LDFROM LINKTYPE - / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; - } - - push @m, " -# Handy lists of source code files: -XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})." -C_FILES = ".join(" \\\n\t", @{$self->{C}})." -O_FILES = ".join(" \\\n\t", @{$self->{O_FILES}})." -H_FILES = ".join(" \\\n\t", @{$self->{H}})." -MAN1PODS = ".join(" \\\n\t", sort keys %{$self->{MAN1PODS}})." -MAN3PODS = ".join(" \\\n\t", sort keys %{$self->{MAN3PODS}})." -"; - - for $tmp (qw/ - INST_MAN1DIR INSTALLMAN1DIR MAN1EXT - INST_MAN3DIR INSTALLMAN3DIR MAN3EXT - /) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; - } - - push @m, qq{ -.USESHELL : -} if $DMAKE; + $self->{PATH} = '$(PATH);$(TOOLPATH)'; - push @m, q{ -.NO_CONFIG_REC: Makefile -} if $ENV{CLEARCASE_ROOT}; - - # why not q{} ? -- emacs - push @m, qq{ -# work around a famous dec-osf make(1) feature(?): -makemakerdflt: all - -.SUFFIXES: .xs .c .C .cpp .cxx .cc \$(OBJ_EXT) + $self->{MM_NW5_VERSION} = $VERSION; +} -.PHONY: all config static dynamic test linkext manifest +sub platform_constants { + my($self) = shift; + my $make_frag = ''; -# Where is the Config information that we are using/depend on -CONFIGDEP = \$(PERL_ARCHLIB)\\Config.pm \$(PERL_INC)\\config.h -}; + # Setup Win32's constants. + $make_frag .= $self->SUPER::platform_constants; - my @parentdir = split(/::/, $self->{PARENT_NAME}); - push @m, q{ -# Where to put things: -INST_LIBDIR = }. File::Spec->catdir('$(INST_LIB)',@parentdir) .q{ -INST_ARCHLIBDIR = }. File::Spec->catdir('$(INST_ARCHLIB)',@parentdir) .q{ + foreach my $macro (qw(LIBPTH BASE_IMPORT NLM_VERSION MPKTOOL + TOOLPATH BOOT_SYMBOL NLM_SHORT_NAME INCLUDE PATH + MM_NW5_VERSION + )) + { + next unless defined $self->{$macro}; + $make_frag .= "$macro = $self->{$macro}\n"; + } -INST_AUTODIR = }. File::Spec->catdir('$(INST_LIB)','auto','$(FULLEXT)') .q{ -INST_ARCHAUTODIR = }. File::Spec->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)') .q{ -}; + return $make_frag; +} - if ($self->has_link_code()) { - push @m, ' -INST_STATIC = $(INST_ARCHAUTODIR)\$(BASEEXT)$(LIB_EXT) -INST_DYNAMIC = $(INST_ARCHAUTODIR)\$(DLBASE).$(DLEXT) -INST_BOOT = $(INST_ARCHAUTODIR)\$(BASEEXT).bs -'; - } else { - push @m, ' -INST_STATIC = -INST_DYNAMIC = -INST_BOOT = -'; - } - $tmp = $self->export_list; - push @m, " -EXPORT_LIST = $tmp -"; - $tmp = $self->perl_archive; - push @m, " -PERL_ARCHIVE = $tmp -"; +=item const_cccmd (o) - push @m, q{ -TO_INST_PM = }.join(" \\\n\t", sort keys %{$self->{PM}}).q{ +=cut -PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{ -}; +sub const_cccmd { + my($self,$libperl)=@_; + return $self->{CONST_CCCMD} if $self->{CONST_CCCMD}; + return '' unless $self->needs_linking(); + return $self->{CONST_CCCMD} = <<'MAKE_FRAG'; +CCCMD = $(CC) $(CCFLAGS) $(INC) $(OPTIMIZE) \ + $(PERLTYPE) $(MPOLLUTE) -o $@ \ + -DVERSION=\"$(VERSION)\" -DXS_VERSION=\"$(XS_VERSION)\" +MAKE_FRAG - join('',@m); } @@ -251,7 +141,7 @@ sub static_lib { return '' unless $self->has_link_code; my $m = <<'END'; -$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)\.exists +$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(RM_RF) $@ END @@ -274,12 +164,12 @@ END $m .= sprintf <<'END', $ar_arg; $(AR) %s - $(NOECHO)echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld + $(NOECHO) $(ECHO) "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld $(CHMOD) 755 $@ END $m .= <<'END' if $self->{PERL_SRC}; - $(NOECHO)echo "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs + $(NOECHO) $(ECHO) "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs END @@ -313,16 +203,16 @@ INST_DYNAMIC_DEP = '.$inst_dynamic_dep.' # Create xdc data for an MT safe NLM in case of mpk build $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) - @echo Export boot_$(BOOT_SYMBOL) > $(BASEEXT).def - @echo $(BASE_IMPORT) >> $(BASEEXT).def - @echo Import @$(PERL_INC)\perl.imp >> $(BASEEXT).def + $(NOECHO) $(ECHO) Export boot_$(BOOT_SYMBOL) > $(BASEEXT).def + $(NOECHO) $(ECHO) $(BASE_IMPORT) >> $(BASEEXT).def + $(NOECHO) $(ECHO) Import @$(PERL_INC)\perl.imp >> $(BASEEXT).def MAKE_FRAG if ( $self->{CCFLAGS} =~ m/ -DMPK_ON /) { $m .= <<'MAKE_FRAG'; $(MPKTOOL) $(XDCFLAGS) $(BASEEXT).xdc - @echo xdcdata $(BASEEXT).xdc >> $(BASEEXT).def + $(NOECHO) $(ECHO) xdcdata $(BASEEXT).xdc >> $(BASEEXT).def MAKE_FRAG } diff --git a/lib/ExtUtils/MM_OS2.pm b/lib/ExtUtils/MM_OS2.pm index fb72f5f..47ecba8 100644 --- a/lib/ExtUtils/MM_OS2.pm +++ b/lib/ExtUtils/MM_OS2.pm @@ -32,16 +32,20 @@ the semantics. =over 4 +=item init_dist (o) + +Define TO_UNIX to convert OS2 linefeeds to Unix style. + =cut -sub dist { - my($self, %attribs) = @_; +sub init_dist { + my($self) = @_; - $attribs{TO_UNIX} ||= sprintf <<'MAKE_TEXT', $self->{NOECHO}; -%s$(TEST_F) tmp.zip && $(RM) tmp.zip; $(ZIP) -ll -mr tmp.zip $(DISTVNAME) && unzip -o tmp.zip && $(RM) tmp.zip + $self->{TO_UNIX} ||= <<'MAKE_TEXT'; +$(NOECHO) $(TEST_F) tmp.zip && $(RM) tmp.zip; $(ZIP) -ll -mr tmp.zip $(DISTVNAME) && unzip -o tmp.zip && $(RM) tmp.zip MAKE_TEXT - return $self->SUPER::dist(%attribs); + $self->SUPER::init_dist; } sub dlsyms { @@ -117,38 +121,23 @@ sub maybe_command { return; } -sub perl_archive { - return "\$(PERL_INC)/libperl\$(LIB_EXT)"; -} +=item init_linker -=item perl_archive_after - -This is an internal method that returns path to a library which -should be put on the linker command line I the external libraries -to be linked to dynamic extensions. This may be needed if the linker -is one-pass, and Perl includes some overrides for C RTL functions, -such as malloc(). +=cut -=cut +sub init_linker { + my $self = shift; -sub perl_archive_after -{ - return "\$(PERL_INC)/libperl_override\$(LIB_EXT)" unless $OS2::is_aout; - return ""; -} + $self->{PERL_ARCHIVE} = "\$(PERL_INC)/libperl\$(LIB_EXT)"; -sub export_list -{ - my ($self) = @_; - return "$self->{BASEEXT}.def"; + $self->{PERL_ARCHIVE_AFTER} = !$OS2::is_aout + ? "\$(PERL_INC)/libperl_override\$(LIB_EXT)" + : ''; + $self->{EXPORT_LIST} = '$(BASEEXT).def'; } -1; - -__END__ - -=pod - =back =cut + +1; diff --git a/lib/ExtUtils/MM_UWIN.pm b/lib/ExtUtils/MM_UWIN.pm index 59384a2..2bfddcf 100644 --- a/lib/ExtUtils/MM_UWIN.pm +++ b/lib/ExtUtils/MM_UWIN.pm @@ -49,4 +49,6 @@ Michael G Schwern with code from ExtUtils::MM_Unix L, L +=cut + 1; diff --git a/lib/ExtUtils/MM_Unix.pm b/lib/ExtUtils/MM_Unix.pm index c5bb19e..87d93bf 100644 --- a/lib/ExtUtils/MM_Unix.pm +++ b/lib/ExtUtils/MM_Unix.pm @@ -6,30 +6,41 @@ use strict; use Exporter (); use Carp; -use Config; +use Config qw(%Config); use File::Basename qw(basename dirname fileparse); -use File::Spec; use DirHandle; -use strict; + use vars qw($VERSION @ISA - $Is_Mac $Is_OS2 $Is_VMS $Is_Win32 $Is_Dos $Is_VOS + $Is_Mac $Is_OS2 $Is_VMS $Is_Win32 $Is_Win95 $Is_Dos $Is_VOS + $Is_QNX $Is_AIX $Is_OSF $Is_IRIX $Is_NetBSD + $Is_SunOS4 $Is_Solaris $Is_SunOS $Verbose %pm %static $Xsubpp_Version %Config_Override ); use ExtUtils::MakeMaker qw($Verbose neatvalue); -$VERSION = '1.33'; +$VERSION = '1.35'; require ExtUtils::MM_Any; @ISA = qw(ExtUtils::MM_Any); -$Is_OS2 = $^O eq 'os2'; -$Is_Mac = $^O eq 'MacOS'; -$Is_Win32 = $^O eq 'MSWin32' || $Config{osname} eq 'NetWare'; -$Is_Dos = $^O eq 'dos'; -$Is_VOS = $^O eq 'vos'; -$Is_VMS = $^O eq 'VMS'; +$Is_OS2 = $^O eq 'os2'; +$Is_Mac = $^O eq 'MacOS'; +$Is_Win32 = $^O eq 'MSWin32' || $Config{osname} eq 'NetWare'; +$Is_Win95 = $Is_Win32 && Win32::IsWin95(); +$Is_Dos = $^O eq 'dos'; +$Is_VOS = $^O eq 'vos'; +$Is_VMS = $^O eq 'VMS'; +$Is_QNX = $^O eq 'qnx'; +$Is_AIX = $^O eq 'aix'; +$Is_OSF = $^O eq 'dec_osf'; +$Is_IRIX = $^O eq 'irix'; +$Is_NetBSD = $^O eq 'netbsd'; +$Is_SunOS4 = $^O eq 'sunos'; +$Is_Solaris = $^O eq 'solaris'; +$Is_SunOS = $Is_SunOS4 || $Is_Solaris; + =head1 NAME @@ -65,7 +76,8 @@ will be overridable via the MY class. The following description of methods is still under development. Please refer to the code for not suitably documented -sections and complain loudly to the makemaker mailing list. +sections and complain loudly to the makemaker@perl.org mailing list. +Better yet, provide a patch. Not all of the methods below are overridable in a Makefile.PL. Overridable methods are marked as (o). All methods are @@ -75,102 +87,15 @@ L) and L). =cut # So we don't have to keep calling the methods over and over again, -# we have these globals to cache the values. They have to be global -# else the SelfLoaded methods can't see them. -use vars qw($Curdir $Rootdir $Updir); -$Curdir = File::Spec->curdir; -$Rootdir = File::Spec->rootdir; -$Updir = File::Spec->updir; - -sub c_o; -sub clean; -sub const_cccmd; -sub const_config; -sub const_loadlibs; -sub constants; -sub depend; -sub dir_target; -sub dist; -sub dist_basics; -sub dist_ci; -sub dist_core; -sub dist_dir; -sub dist_test; -sub dlsyms; -sub dynamic; -sub dynamic_bs; -sub dynamic_lib; -sub exescan; -sub export_list; -sub extliblist; -sub find_perl; -sub fixin; -sub force; -sub guess_name; -sub has_link_code; -sub init_dirscan; -sub init_main; -sub init_others; -sub install; -sub installbin; -sub libscan; -sub linkext; -sub lsdir; -sub macro; -sub makeaperl; -sub makefile; -sub manifypods; -sub maybe_command; -sub maybe_command_in_dirs; -sub needs_linking; -sub nicetext; -sub parse_abstract; -sub parse_version; -sub pasthru; -sub perl_archive; -sub perl_archive_after; -sub perl_script; -sub perldepend; -sub pm_to_blib; -sub ppd; -sub post_constants; -sub post_initialize; -sub postamble; -sub prefixify; -sub processPL; -sub quote_paren; -sub realclean; -sub replace_manpage_separator; -sub static; -sub static_lib; -sub staticmake; -sub subdir_x; -sub subdirs; -sub test; -sub test_via_harness; -sub test_via_script; -sub tool_autosplit; -sub tool_xsubpp; -sub tools_other; -sub top_targets; -sub writedoc; -sub xs_c; -sub xs_cpp; -sub xs_o; -sub xsubpp_version; - -#use SelfLoader; - -# SelfLoader not smart enough to avoid autoloading DESTROY -sub DESTROY { } - -#1; - -#__DATA__ - -=head2 SelfLoaded methods +# we have these globals to cache the values. Faster and shrtr. +my $Curdir = __PACKAGE__->curdir; +my $Rootdir = __PACKAGE__->rootdir; +my $Updir = __PACKAGE__->updir; -=over 2 + +=head2 Methods + +=over 4 =item c_o (o) @@ -343,27 +268,11 @@ sub clean { # Delete temporary files but do not touch installed files. We don\'t delete # the Makefile here so a later make realclean still has a makefile to use. -clean :: +clean :: clean_subdirs '); - # clean subdirectories first - for $dir (@{$self->{DIR}}) { - if ($Is_Win32 && Win32::IsWin95()) { - push @m, <{MAKEFILE} - \$(MAKE) clean - cd .. -EOT - } - else { - push @m, <{MAKEFILE} && \$(MAKE) clean -EOT - } - } my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files - if ( $^O eq 'qnx' ) { + if ( $Is_QNX ) { my @errfiles = @{$self->{C}}; for ( @errfiles ) { s/.c$/.err/; @@ -386,15 +295,47 @@ EOT push(@otherfiles, qw[core core.*perl.*.? *perl.core]); } - push @m, "\t-$self->{RM_RF} @otherfiles\n"; + push @m, "\t-\$(RM_RF) @otherfiles\n"; # See realclean and ext/utils/make_ext for usage of Makefile.old push(@m, - "\t-$self->{MV} $self->{MAKEFILE} $self->{MAKEFILE}.old \$(DEV_NULL)\n"); + "\t-\$(MV) \$(FIRST_MAKEFILE) \$(MAKEFILE_OLD) \$(DEV_NULL)\n"); push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; join("", @m); } + +=item clean_subdirs_target + + my $make_frag = $MM->clean_subdirs_target; + +Returns the clean_subdirs target. This is used by the clean target to +call clean on any subdirectories which contain Makefiles. + +=cut + +sub clean_subdirs_target { + my($self) = shift; + + # No subdirectories, no cleaning. + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +clean_subdirs : + $(NOECHO) $(NOOP) +NOOP_FRAG + + + my $clean = "clean_subdirs :\n"; + + for my $dir (@{$self->{DIR}}) { + $clean .= sprintf <<'MAKE_FRAG', $dir; + -cd %s && $(TEST_F) $(FIRST_MAKEFILE) && $(MAKE) clean +MAKE_FRAG + } + + return $clean; +} + + =item const_cccmd (o) Returns the full compiler call for C programs and stores the @@ -430,7 +371,7 @@ sub const_config { my(%once_only); foreach $m (@{$self->{CONFIG}}){ # SITE*EXP macros are defined in &constants; avoid duplicates here - next if $once_only{$m} or $m eq 'sitelibexp' or $m eq 'sitearchexp'; + next if $once_only{$m}; $self->{uc $m} = quote_paren($self->{uc $m}); push @m, uc($m) , ' = ' , $self->{uc $m}, "\n"; $once_only{$m} = 1; @@ -466,53 +407,54 @@ sub const_loadlibs { =item constants (o) -Initializes lots of constants and .SUFFIXES and .PHONY + my $make_frag = $mm->constants; + +Prints out macros for lots of constants. =cut sub constants { my($self) = @_; - my(@m,$tmp); + my @m = (); - for $tmp (qw/ + for my $macro (qw/ - AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION - VERSION_SYM XS_VERSION - INST_ARCHLIB INST_SCRIPT INST_BIN INST_LIB + AR_STATIC_ARGS DIRFILESEP + NAME NAME_SYM + VERSION VERSION_MACRO VERSION_SYM DEFINE_VERSION + XS_VERSION XS_VERSION_MACRO XS_DEFINE_VERSION + INST_ARCHLIB INST_SCRIPT INST_BIN INST_LIB INSTALLDIRS - PREFIX SITEPREFIX VENDORPREFIX - INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB - INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH + DESTDIR PREFIX + PERLPREFIX SITEPREFIX VENDORPREFIX + INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB + INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN INSTALLSCRIPT - PERL_LIB PERL_ARCHLIB - SITELIBEXP SITEARCHEXP + PERL_LIB + PERL_ARCHLIB LIBPERL_A MYEXTLIB - FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC - PERL_INC PERL FULLPERL PERLRUN FULLPERLRUN PERLRUNINST - FULLPERLRUNINST ABSPERL ABSPERLRUN ABSPERLRUNINST - FULL_AR PERL_CORE NOOP NOECHO + FIRST_MAKEFILE MAKEFILE_OLD MAKE_APERL_FILE + PERLMAINCC PERL_SRC PERL_INC + PERL FULLPERL ABSPERL + PERLRUN FULLPERLRUN ABSPERLRUN + PERLRUNINST FULLPERLRUNINST ABSPERLRUNINST + PERL_CORE + PERM_RW PERM_RWX / ) { - next unless defined $self->{$tmp}; + next unless defined $self->{$macro}; # pathnames can have sharp signs in them; escape them so # make doesn't think it is a comment-start character. - $self->{$tmp} =~ s/#/\\#/g; - push @m, "$tmp = $self->{$tmp}\n"; + $self->{$macro} =~ s/#/\\#/g; + push @m, "$macro = $self->{$macro}\n"; } push @m, qq{ -VERSION_MACRO = VERSION -DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\" -XS_VERSION_MACRO = XS_VERSION -XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\" -PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc -}; - - push @m, qq{ -MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'} -MM_VERSION = $ExtUtils::MakeMaker::VERSION +MAKEMAKER = $self->{MAKEMAKER} +MM_VERSION = $self->{MM_VERSION} +MM_REVISION = $self->{MM_REVISION} }; push @m, q{ @@ -522,115 +464,75 @@ MM_VERSION = $ExtUtils::MakeMaker::VERSION # DLBASE = Basename part of dynamic library. May be just equal BASEEXT. }; - for $tmp (qw/ + for my $macro (qw/ FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT LDFROM LINKTYPE PM_FILTER / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; + next unless defined $self->{$macro}; + push @m, "$macro = $self->{$macro}\n"; } push @m, " # Handy lists of source code files: -XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})." -C_FILES = ".join(" \\\n\t", @{$self->{C}})." -O_FILES = ".join(" \\\n\t", @{$self->{O_FILES}})." -H_FILES = ".join(" \\\n\t", @{$self->{H}})." -MAN1PODS = ".join(" \\\n\t", sort keys %{$self->{MAN1PODS}})." -MAN3PODS = ".join(" \\\n\t", sort keys %{$self->{MAN3PODS}})." +XS_FILES = ".$self->wraplist(sort keys %{$self->{XS}})." +C_FILES = ".$self->wraplist(@{$self->{C}})." +O_FILES = ".$self->wraplist(@{$self->{O_FILES}})." +H_FILES = ".$self->wraplist(@{$self->{H}})." +MAN1PODS = ".$self->wraplist(sort keys %{$self->{MAN1PODS}})." +MAN3PODS = ".$self->wraplist(sort keys %{$self->{MAN3PODS}})." "; - for $tmp (qw/ - INST_MAN1DIR MAN1EXT + for my $macro (qw/ + INST_MAN1DIR MAN1EXT INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR INST_MAN3DIR MAN3EXT INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR /) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; + next unless defined $self->{$macro}; + push @m, "$macro = $self->{$macro}\n"; } - for $tmp (qw( - PERM_RW PERM_RWX - ) - ) - { - my $method = lc($tmp); - # warn "self[$self] method[$method]"; - push @m, "$tmp = ", $self->$method(), "\n"; - } push @m, q{ -.NO_CONFIG_REC: Makefile -} if $ENV{CLEARCASE_ROOT}; - - # why not q{} ? -- emacs - push @m, qq{ -# work around a famous dec-osf make(1) feature(?): -makemakerdflt: all +# Where is the Config information that we are using/depend on +CONFIGDEP = $(PERL_ARCHLIB)$(DIRFILESEP)Config.pm $(PERL_INC)$(DIRFILESEP)config.h +}; -.SUFFIXES: .xs .c .C .cpp .i .s .cxx .cc \$(OBJ_EXT) -# Nick wanted to get rid of .PRECIOUS. I don't remember why. I seem to recall, that -# some make implementations will delete the Makefile when we rebuild it. Because -# we call false(1) when we rebuild it. So make(1) is not completely wrong when it -# does so. Our milage may vary. -# .PRECIOUS: Makefile # seems to be not necessary anymore + push @m, qq{ +# Where to build things +INST_LIBDIR = $self->{INST_LIBDIR} +INST_ARCHLIBDIR = $self->{INST_ARCHLIBDIR} -.PHONY: all config static dynamic test linkext manifest +INST_AUTODIR = $self->{INST_AUTODIR} +INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR} -# Where is the Config information that we are using/depend on -CONFIGDEP = \$(PERL_ARCHLIB)/Config.pm \$(PERL_INC)/config.h +INST_STATIC = $self->{INST_STATIC} +INST_DYNAMIC = $self->{INST_DYNAMIC} +INST_BOOT = $self->{INST_BOOT} }; - my @parentdir = split(/::/, $self->{PARENT_NAME}); - push @m, q{ -# Where to put things: -INST_LIBDIR = }. File::Spec->catdir('$(INST_LIB)',@parentdir) .q{ -INST_ARCHLIBDIR = }. File::Spec->catdir('$(INST_ARCHLIB)',@parentdir) .q{ -INST_AUTODIR = }. File::Spec->catdir('$(INST_LIB)','auto','$(FULLEXT)') .q{ -INST_ARCHAUTODIR = }. File::Spec->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)') .q{ + push @m, qq{ +# Extra linker info +EXPORT_LIST = $self->{EXPORT_LIST} +PERL_ARCHIVE = $self->{PERL_ARCHIVE} +PERL_ARCHIVE_AFTER = $self->{PERL_ARCHIVE_AFTER} }; - if ($self->has_link_code()) { - push @m, ' -INST_STATIC = $(INST_ARCHAUTODIR)/$(BASEEXT)$(LIB_EXT) -INST_DYNAMIC = $(INST_ARCHAUTODIR)/$(DLBASE).$(DLEXT) -INST_BOOT = $(INST_ARCHAUTODIR)/$(BASEEXT).bs -'; - } else { - push @m, ' -INST_STATIC = -INST_DYNAMIC = -INST_BOOT = -'; - } - - $tmp = $self->export_list; - push @m, " -EXPORT_LIST = $tmp -"; - $tmp = $self->perl_archive; - push @m, " -PERL_ARCHIVE = $tmp -"; - $tmp = $self->perl_archive_after; push @m, " -PERL_ARCHIVE_AFTER = $tmp -"; - push @m, q{ -TO_INST_PM = }.join(" \\\n\t", sort keys %{$self->{PM}}).q{ +TO_INST_PM = ".$self->wraplist(sort keys %{$self->{PM}})." -PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{ -}; +PM_TO_BLIB = ".$self->wraplist(%{$self->{PM}})." +"; join('',@m); } + =item depend (o) Same as macro for the depend attribute. @@ -669,8 +571,8 @@ sub dir_target { my($self,@dirs) = @_; my(@m,$dir,$targdir); foreach $dir (@dirs) { - my($src) = File::Spec->catfile($self->{PERL_INC},'perl.h'); - my($targ) = File::Spec->catfile($dir,'.exists'); + my($src) = $self->catfile($self->{PERL_INC},'perl.h'); + my($targ) = $self->catfile($dir,'.exists'); # catfile may have adapted syntax of $dir to target OS, so... if ($Is_VMS) { # Just remove file name; dirspec is often in macro ($targdir = $targ) =~ s:/?\.exists\z::; @@ -681,53 +583,109 @@ sub dir_target { next if $self->{DIR_TARGET}{$self}{$targdir}++; push @m, qq{ $targ :: $src - $self->{NOECHO}\$(MKPATH) $targdir - $self->{NOECHO}\$(EQUALIZE_TIMESTAMP) $src $targ + \$(NOECHO) \$(MKPATH) $targdir + \$(NOECHO) \$(EQUALIZE_TIMESTAMP) $src $targ }; push(@m, qq{ - -$self->{NOECHO}\$(CHMOD) \$(PERM_RWX) $targdir + -\$(NOECHO) \$(CHMOD) \$(PERM_RWX) $targdir }) unless $Is_VMS; } join "", @m; } -=item dist (o) +=item init_dist + + $mm->init_dist; Defines a lot of macros for distribution support. + macro description default + + TAR tar command to use tar + TARFLAGS flags to pass to TAR cvf + + ZIP zip command to use zip + ZIPFLAGS flags to pass to ZIP -r + + COMPRESS compression command to gzip --best + use for tarfiles + SUFFIX suffix to put on .gz + compressed files + + SHAR shar command to use shar + + PREOP extra commands to run before + making the archive + POSTOP extra commands to run after + making the archive + + TO_UNIX a command to convert linefeeds + to Unix style in your archive + + CI command to checkin your ci -u + sources to version control + RCS_LABEL command to label your sources rcs -Nv$(VERSION_SYM): -q + just after CI is run + + DIST_CP $how argument to manicopy() best + when the distdir is created + + DIST_DEFAULT default target to use to tardist + create a distribution + + DISTVNAME name of the resulting archive $(DISTNAME)-$(VERSION) + (minus suffixes) + +=cut + +sub init_dist { + my $self = shift; + + $self->{TAR} ||= 'tar'; + $self->{TARFLAGS} ||= 'cvf'; + $self->{ZIP} ||= 'zip'; + $self->{ZIPFLAGS} ||= '-r'; + $self->{COMPRESS} ||= 'gzip --best'; + $self->{SUFFIX} ||= '.gz'; + $self->{SHAR} ||= 'shar'; + $self->{PREOP} ||= '$(NOECHO) $(NOOP)'; # eg update MANIFEST + $self->{POSTOP} ||= '$(NOECHO) $(NOOP)'; # eg remove the distdir + $self->{TO_UNIX} ||= '$(NOECHO) $(NOOP)'; + + $self->{CI} ||= 'ci -u'; + $self->{RCS_LABEL}||= 'rcs -Nv$(VERSION_SYM): -q'; + $self->{DIST_CP} ||= 'best'; + $self->{DIST_DEFAULT} ||= 'tardist'; + + ($self->{DISTNAME} = $self->{NAME}) =~ s{::}{-}g unless $self->{DISTNAME}; + $self->{DISTVNAME} ||= $self->{DISTNAME}.'-'.$self->{VERSION}; + +} + +=item dist (o) + + my $dist_macros = $mm->dist(%overrides); + +Generates a make fragment defining all the macros initialized in +init_dist. + +%overrides can be used to override any of the above. + =cut sub dist { my($self, %attribs) = @_; - # VERSION should be sanitised before use as a file name - $attribs{VERSION} ||= '$(VERSION)'; - $attribs{NAME} ||= '$(DISTNAME)'; - $attribs{TAR} ||= 'tar'; - $attribs{TARFLAGS} ||= 'cvf'; - $attribs{ZIP} ||= 'zip'; - $attribs{ZIPFLAGS} ||= '-r'; - $attribs{COMPRESS} ||= 'gzip --best'; - $attribs{SUFFIX} ||= '.gz'; - $attribs{SHAR} ||= 'shar'; - $attribs{PREOP} ||= "$self->{NOECHO}\$(NOOP)"; # eg update MANIFEST - $attribs{POSTOP} ||= "$self->{NOECHO}\$(NOOP)"; # eg remove the distdir - $attribs{TO_UNIX} ||= "$self->{NOECHO}\$(NOOP)"; - - $attribs{CI} ||= 'ci -u'; - $attribs{RCS_LABEL}||= 'rcs -Nv$(VERSION_SYM): -q'; - $attribs{DIST_CP} ||= 'best'; - $attribs{DIST_DEFAULT} ||= 'tardist'; - - $attribs{DISTVNAME} ||= "$attribs{NAME}-$attribs{VERSION}"; - - # We've already printed out VERSION and NAME variables. - delete $attribs{VERSION}; - delete $attribs{NAME}; - my $make = ''; - while(my($var, $value) = each %attribs) { - $make .= "$var = $value\n"; + foreach my $key (qw( + TAR TARFLAGS ZIP ZIPFLAGS COMPRESS SUFFIX SHAR + PREOP POSTOP TO_UNIX + CI RCS_LABEL DIST_CP DIST_DEFAULT + DISTNAME DISTVNAME + )) + { + my $value = $attribs{$key} || $self->{$key}; + $make .= "$key = $value\n"; } return $make; @@ -770,35 +728,116 @@ Defines a check in target for RCS. sub dist_ci { my($self) = shift; - my @m; - push @m, q{ + return q{ ci : $(PERLRUN) "-MExtUtils::Manifest=maniread" \\ - -e "@all = keys %{ maniread() };" \\ - -e 'print("Executing $(CI) @all\n"); system("$(CI) @all");' \\ - -e 'print("Executing $(RCS_LABEL) ...\n"); system("$(RCS_LABEL) @all");' + -e "@all = keys %{ maniread() };" \\ + -e "print("Executing $(CI) @all\n"); system(qq{$(CI) @all});" \\ + -e "print("Executing $(RCS_LABEL) ...\n"); system(qq{$(RCS_LABEL) @all});" }; - join "", @m; } =item dist_core (o) -Defines the targets dist, tardist, zipdist, uutardist, shdist + my $dist_make_fragment = $MM->dist_core; + +Puts the targets necessary for 'make dist' together into one make +fragment. =cut sub dist_core { my($self) = shift; - my @m; - push @m, q{ + + my $make_frag = ''; + foreach my $target (qw(dist tardist uutardist tarfile zipdist zipfile + shdist)) + { + my $method = $target.'_target'; + $make_frag .= "\n"; + $make_frag .= $self->$method(); + } + + return $make_frag; +} + + +=item B + + my $make_frag = $MM->dist_target; + +Returns the 'dist' target to make an archive for distribution. This +target simply checks to make sure the Makefile is up-to-date and +depends on $(DIST_DEFAULT). + +=cut + +sub dist_target { + my($self) = shift; + + my $date_check = $self->oneliner(<<'CODE', ['-l']); +print 'Warning: Makefile possibly out of date with $(VERSION_FROM)' + if -e '$(VERSION_FROM)' and -M '$(VERSION_FROM)' < -M '$(FIRST_MAKEFILE)'; +CODE + + return sprintf <<'MAKE_FRAG', $date_check; dist : $(DIST_DEFAULT) - }.$self->{NOECHO}.q{$(PERL) -le 'print "Warning: Makefile possibly out of date with $$vf" if ' \ - -e '-e ($$vf="$(VERSION_FROM)") and -M $$vf < -M "}.$self->{MAKEFILE}.q{";' + $(NOECHO) %s +MAKE_FRAG +} + +=item B + my $make_frag = $MM->tardist_target; + +Returns the 'tardist' target which is simply so 'make tardist' works. +The real work is done by the dynamically named tardistfile_target() +method, tardist should have that as a dependency. + +=cut + +sub tardist_target { + my($self) = shift; + + return <<'MAKE_FRAG'; tardist : $(DISTVNAME).tar$(SUFFIX) + $(NOECHO) $(NOOP) +MAKE_FRAG +} + +=item B + + my $make_frag = $MM->zipdist_target; + +Returns the 'zipdist' target which is simply so 'make zipdist' works. +The real work is done by the dynamically named zipdistfile_target() +method, zipdist should have that as a dependency. + +=cut + +sub zipdist_target { + my($self) = shift; + return <<'MAKE_FRAG'; zipdist : $(DISTVNAME).zip + $(NOECHO) $(NOOP) +MAKE_FRAG +} + +=item B + + my $make_frag = $MM->tarfile_target; + +The name of this target is the name of the tarball generated by +tardist. This target does the actual work of turning the distdir into +a tarball. +=cut + +sub tarfile_target { + my($self) = shift; + + return <<'MAKE_FRAG'; $(DISTVNAME).tar$(SUFFIX) : distdir $(PREOP) $(TO_UNIX) @@ -806,39 +845,84 @@ $(DISTVNAME).tar$(SUFFIX) : distdir $(RM_RF) $(DISTVNAME) $(COMPRESS) $(DISTVNAME).tar $(POSTOP) +MAKE_FRAG +} + +=item zipfile_target + my $make_frag = $MM->zipfile_target; + +The name of this target is the name of the zip file generated by +zipdist. This target does the actual work of turning the distdir into +a zip file. + +=cut + +sub zipfile_target { + my($self) = shift; + + return <<'MAKE_FRAG'; $(DISTVNAME).zip : distdir $(PREOP) $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) $(RM_RF) $(DISTVNAME) $(POSTOP) +MAKE_FRAG +} + +=item uutardist_target + + my $make_frag = $MM->uutardist_target; + +Converts the tarfile into a uuencoded file + +=cut + +sub uutardist_target { + my($self) = shift; + return <<'MAKE_FRAG'; uutardist : $(DISTVNAME).tar$(SUFFIX) - uuencode $(DISTVNAME).tar$(SUFFIX) \\ - $(DISTVNAME).tar$(SUFFIX) > \\ - $(DISTVNAME).tar$(SUFFIX)_uu + uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu +MAKE_FRAG +} + + +=item shdist_target + + my $make_frag = $MM->shdist_target; + +Converts the distdir into a shell archive. + +=cut + +sub shdist_target { + my($self) = shift; + return <<'MAKE_FRAG'; shdist : distdir $(PREOP) $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar $(RM_RF) $(DISTVNAME) $(POSTOP) -}; - join "", @m; +MAKE_FRAG } -=item dist_dir +=item distdir Defines the scratch directory target that will hold the distribution before tar-ing (or shar-ing). =cut -sub dist_dir { +# For backwards compatibility. +*dist_dir = *distdir; + +sub distdir { my($self) = shift; return <<'MAKE_FRAG'; -distdir : +distdir : metafile metafile_addtomanifest $(RM_RF) $(DISTVNAME) $(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \ -e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');" @@ -877,7 +961,7 @@ files. sub dlsyms { my($self,%attribs) = @_; - return '' unless ($^O eq 'aix' && $self->needs_linking() ); + return '' unless ($Is_AIX && $self->needs_linking() ); my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {}; my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || []; @@ -918,9 +1002,8 @@ sub dynamic { ' ## $(INST_PM) has been moved to the all: target. ## It remains here for awhile to allow for old usage: "make dynamic" -#dynamic :: '.$self->{MAKEFILE}.' $(INST_DYNAMIC) $(INST_BOOT) $(INST_PM) -dynamic :: '.$self->{MAKEFILE}.' $(INST_DYNAMIC) $(INST_BOOT) - '.$self->{NOECHO}.'$(NOOP) +dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT) + $(NOECHO) $(NOOP) '; } @@ -936,25 +1019,25 @@ sub dynamic_bs { BOOTSTRAP = ' unless $self->has_link_code(); - return ' -BOOTSTRAP = '."$self->{BASEEXT}.bs".' + return <<'MAKE_FRAG'; +BOOTSTRAP = $(BASEEXT).bs # As Mkbootstrap might not write a file (if none is required) # we use touch to prevent make continually trying to remake it. # The DynaLoader only reads a non-empty file. -$(BOOTSTRAP): '."$self->{MAKEFILE} $self->{BOOTDEP}".' $(INST_ARCHAUTODIR)/.exists - '.$self->{NOECHO}.'echo "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))" - '.$self->{NOECHO}.'$(PERLRUN) \ +$(BOOTSTRAP): $(FIRST_MAKEFILE) $(BOOTDEP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(ECHO) "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))" + $(NOECHO) $(PERLRUN) \ "-MExtUtils::Mkbootstrap" \ - -e "Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');" - '.$self->{NOECHO}.'$(TOUCH) $(BOOTSTRAP) + -e "Mkbootstrap('$(BASEEXT)','$(BSLOADLIBS)');" + $(NOECHO) $(TOUCH) $(BOOTSTRAP) $(CHMOD) $(PERM_RW) $@ -$(INST_BOOT): $(BOOTSTRAP) $(INST_ARCHAUTODIR)/.exists - '."$self->{NOECHO}$self->{RM_RF}".' $(INST_BOOT) - -'.$self->{CP}.' $(BOOTSTRAP) $(INST_BOOT) +$(INST_BOOT): $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(RM_RF) $(INST_BOOT) + -$(CP) $(BOOTSTRAP) $(INST_BOOT) $(CHMOD) $(PERM_RW) $@ -'; +MAKE_FRAG } =item dynamic_lib (o) @@ -973,7 +1056,7 @@ sub dynamic_lib { my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || ""; my($armaybe) = $attribs{ARMAYBE} || $self->{ARMAYBE} || ":"; my($ldfrom) = '$(LDFROM)'; - $armaybe = 'ar' if ($^O eq 'dec_osf' and $armaybe eq ':'); + $armaybe = 'ar' if ($Is_OSF and $armaybe eq ':'); my(@m); my $ld_opt = $Is_OS2 ? '$(OPTIMIZE) ' : ''; # Useful on other systems too? push(@m,' @@ -983,17 +1066,17 @@ ARMAYBE = '.$armaybe.' OTHERLDFLAGS = '.$ld_opt.$otherldflags.' INST_DYNAMIC_DEP = '.$inst_dynamic_dep.' -$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)/.exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(PERL_ARCHIVE_AFTER) $(INST_DYNAMIC_DEP) +$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(PERL_ARCHIVE_AFTER) $(INST_DYNAMIC_DEP) '); if ($armaybe ne ':'){ $ldfrom = 'tmp$(LIB_EXT)'; push(@m,' $(ARMAYBE) cr '.$ldfrom.' $(OBJECT)'."\n"); push(@m,' $(RANLIB) '."$ldfrom\n"); } - $ldfrom = "-all $ldfrom -none" if ($^O eq 'dec_osf'); + $ldfrom = "-all $ldfrom -none" if $Is_OSF; # The IRIX linker doesn't use LD_RUN_PATH - my $ldrun = $^O eq 'irix' && $self->{LD_RUN_PATH} ? + my $ldrun = $Is_IRIX && $self->{LD_RUN_PATH} ? qq{-rpath "$self->{LD_RUN_PATH}"} : ''; # For example in AIX the shared objects/libraries from previous builds @@ -1006,7 +1089,7 @@ $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)/.exists my $libs = '$(LDLOADLIBS)'; - if ($^O eq 'netbsd') { + if ($Is_NetBSD) { # Use nothing on static perl platforms, and to the flags needed # to link against the shared libperl library on shared perl # platforms. We peek at lddlflags to see if we need -Wl,-R @@ -1065,34 +1148,54 @@ sub find_perl { my($self, $ver, $names, $dirs, $trace) = @_; my($name, $dir); if ($trace >= 2){ - print "Looking for perl $ver by these names: + print "Looking for perl $ver by these names: @$names in these dirs: @$dirs "; } + + my $stderr_duped = 0; + local *STDERR_COPY; + if( open(STDERR_COPY, '>&STDERR') ) { + $stderr_duped = 1; + } + else { + warn <{PERL_SRC} may be undefined - my ($abs, $val); - if (File::Spec->file_name_is_absolute($name)) { # /foo/bar - $abs = $name; - } elsif (File::Spec->canonpath($name) eq File::Spec->canonpath(basename($name))) { # foo - $abs = File::Spec->catfile($dir, $name); - } else { # foo/bar - $abs = File::Spec->canonpath(File::Spec->catfile($Curdir, $name)); - } - print "Checking $abs\n" if ($trace >= 2); - next unless $self->maybe_command($abs); - print "Executing $abs\n" if ($trace >= 2); - $val = `$abs -e 'require $ver; print "VER_OK\n" ' 2>&1`; - if ($val =~ /VER_OK/) { - print "Using PERL=$abs\n" if $trace; - return $abs; - } elsif ($trace >= 2) { - print "Result: `$val'\n"; - } - } + foreach $dir (@$dirs){ + next unless defined $dir; # $self->{PERL_SRC} may be undefined + my ($abs, $val); + if ($self->file_name_is_absolute($name)) { # /foo/bar + $abs = $name; + } elsif ($self->canonpath($name) eq + $self->canonpath(basename($name))) { # foo + $abs = $self->catfile($dir, $name); + } else { # foo/bar + $abs = $self->catfile($Curdir, $name); + } + print "Checking $abs\n" if ($trace >= 2); + next unless $self->maybe_command($abs); + print "Executing $abs\n" if ($trace >= 2); + + # To avoid using the unportable 2>&1 to supress STDERR, + # we close it before running the command. + close STDERR if $stderr_duped; + $val = `$abs -e "require $ver; print qq{VER_OK\n}"`; + open STDERR, '>&STDERR_COPY' if $stderr_duped; + + if ($val =~ /^VER_OK/) { + print "Using PERL=$abs\n" if $trace; + return $abs; + } elsif ($trace >= 2) { + print "Result: '$val'\n"; + } + } } print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n"; 0; # false and not empty @@ -1154,13 +1257,13 @@ sub fixin { # stolen from the pink Camel book, more or less $interpreter = $Config{perlpath}; } } else { - my(@absdirs) = reverse grep {File::Spec->file_name_is_absolute} File::Spec->path; + my(@absdirs) = reverse grep {$self->file_name_is_absolute} $self->path; $interpreter = ''; my($dir); foreach $dir (@absdirs) { if ($self->maybe_command($cmd)) { warn "Ignoring $interpreter in $file\n" if $Verbose && $interpreter; - $interpreter = File::Spec->catfile($dir,$cmd); + $interpreter = $self->catfile($dir,$cmd); } } } @@ -1227,7 +1330,7 @@ sub force { my($self) = shift; '# Phony target to force checking subdirectories. FORCE: - '.$self->{NOECHO}.'$(NOOP) + $(NOECHO) $(NOOP) '; } @@ -1273,7 +1376,10 @@ sub has_link_code { =item init_dirscan -Initializes DIR, XS, PM, C, O_FILES, H, PL_FILES, MAN*PODS, EXE_FILES. +Scans the directory structure and initializes DIR, XS, XS_FILES, PM, +C, C_FILES, O_FILES, H, H_FILES, PL_FILES, MAN*PODS, EXE_FILES. + +Called by init_main. =cut @@ -1296,7 +1402,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) next unless $self->libscan($name); if (-d $name){ next if -l $name; # We do not support symlinks at all - $dir{$name} = $name if (-f File::Spec->catfile($name,"Makefile.PL")); + $dir{$name} = $name if (-f $self->catfile($name,"Makefile.PL")); } elsif ($name =~ /\.xs\z/){ my($c); ($c = $name) =~ s/\.xs\z/.c/; $xs{$name} = $c; @@ -1316,10 +1422,10 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) ($pl_files{$name} = $name) =~ s/[._]pl\z//i ; } else { - $pm{$name} = File::Spec->catfile($self->{INST_LIBDIR},$name); + $pm{$name} = $self->catfile($self->{INST_LIBDIR},$name); } } elsif ($name =~ /\.(p[ml]|pod)\z/){ - $pm{$name} = File::Spec->catfile($self->{INST_LIBDIR},$name); + $pm{$name} = $self->catfile($self->{INST_LIBDIR},$name); } } @@ -1349,14 +1455,14 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) # (which includes PARENT_NAME). This is a subtle distinction but one # that's important for nested modules. - if ($Is_VMS) { - # avoid logical name collisions by adding directory syntax - $self->{PMLIBDIRS} = ['./lib', './' . $self->{BASEEXT}] - unless $self->{PMLIBDIRS}; - } - else { - $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}] - unless $self->{PMLIBDIRS}; + unless( $self->{PMLIBDIRS} ) { + if( $Is_VMS ) { + # Avoid logical name vs directory collisions + $self->{PMLIBDIRS} = ['./lib', "./$self->{BASEEXT}"]; + } + else { + $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}]; + } } #only existing directories that aren't in $dir are allowed @@ -1376,7 +1482,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) require File::Find; File::Find::find(sub { if (-d $_){ - if ($_ eq "CVS" || $_ eq "RCS"){ + unless ($self->libscan($_)){ $File::Find::prune = 1; } return; @@ -1391,7 +1497,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) $prefix = $self->{INST_LIB} if ($striplibpath = $path) =~ s:^(\W*)lib\W:$1:i; - my($inst) = File::Spec->catfile($prefix,$striplibpath); + my($inst) = $self->catfile($prefix,$striplibpath); local($_) = $inst; # for backwards compatibility $inst = $self->libscan($inst); print "libscan($path) => '$inst'\n" if ($Verbose >= 2); @@ -1400,14 +1506,17 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) }, @{$self->{PMLIBDIRS}}); } - $self->{DIR} = [sort keys %dir] unless $self->{DIR}; - $self->{XS} = \%xs unless $self->{XS}; - $self->{PM} = \%pm unless $self->{PM}; - $self->{C} = [sort keys %c] unless $self->{C}; - my(@o_files) = @{$self->{C}}; - $self->{O_FILES} = [grep s/\.c(pp|xx|c)?\z/$self->{OBJ_EXT}/i, @o_files] ; - $self->{H} = [sort keys %h] unless $self->{H}; - $self->{PL_FILES} = \%pl_files unless $self->{PL_FILES}; + $self->{PM} ||= \%pm; + $self->{PL_FILES} ||= \%pl_files; + + $self->{DIR} ||= [sort keys %dir]; + + $self->{XS} ||= \%xs; + $self->{C} ||= [sort keys %c]; + my @o_files = @{$self->{C}}; + $self->{O_FILES} = [grep s/\.c(pp|xx|c)?\z/$self->{OBJ_EXT}/i, @o_files]; + + $self->{H} ||= [sort keys %h]; # Set up names of manual pages to generate from pods my %pods; @@ -1426,7 +1535,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) my($ispod)=0; if (open(FH,"<$name")) { while () { - if (/^=\w/) { + if (/^=(?:head\d+|item|pod)\b/) { $ispod=1; last; } @@ -1439,7 +1548,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) next unless $ispod; if ($pods{MAN1}) { $self->{MAN1PODS}->{$name} = - File::Spec->catfile("\$(INST_MAN1DIR)", basename($name).".\$(MAN1EXT)"); + $self->catfile("\$(INST_MAN1DIR)", basename($name).".\$(MAN1EXT)"); } } } @@ -1455,7 +1564,7 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) my($ispod)=0; if (open(FH,"<$name")) { while () { - if (/^=\w/) { + if (/^=head1\s+\w+/) { $ispod=1; last; } @@ -1480,18 +1589,34 @@ sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) } my($manpagename) = $name; $manpagename =~ s/\.p(od|m|l)\z//; - unless ($manpagename =~ s!^\W*lib\W+!!s) { # everything below lib is ok - $manpagename = File::Spec->catfile(split(/::/,$self->{PARENT_NAME}),$manpagename); + # everything below lib is ok + if($self->{PARENT_NAME} && $manpagename !~ s!^\W*lib\W+!!s) { + $manpagename = $self->catfile( + split(/::/,$self->{PARENT_NAME}),$manpagename + ); } if ($pods{MAN3}) { $manpagename = $self->replace_manpage_separator($manpagename); $self->{MAN3PODS}->{$name} = - File::Spec->catfile("\$(INST_MAN3DIR)", "$manpagename.\$(MAN3EXT)"); + $self->catfile("\$(INST_MAN3DIR)", "$manpagename.\$(MAN3EXT)"); } } } } +=item init_DIRFILESEP + +Using / for Unix. Called by init_main. + +=cut + +sub init_DIRFILESEP { + my($self) = shift; + + $self->{DIRFILESEP} = '/'; +} + + =item init_main Initializes AR, AR_STATIC_ARGS, BASEEXT, CONFIG, DISTNAME, DLBASE, @@ -1499,7 +1624,7 @@ EXE_EXT, FULLEXT, FULLPERL, FULLPERLRUN, FULLPERLRUNINST, INST_*, INSTALL*, INSTALLDIRS, LD, LIB_EXT, LIBPERL_A, MAP_TARGET, NAME, OBJ_EXT, PARENT_NAME, PERL, PERL_ARCHLIB, PERL_INC, PERL_LIB, PERL_SRC, PERLRUN, PERLRUNINST, PREFIX, VERSION, -VERSION_FROM, VERSION_SYM, XS_VERSION. +VERSION_SYM, XS_VERSION. =cut @@ -1515,7 +1640,7 @@ sub init_main { ### Only UNIX: ### ($self->{FULLEXT} = ### $self->{NAME}) =~ s!::!/!g ; #eg. BSD/Foo/Socket - $self->{FULLEXT} = File::Spec->catdir(split /::/, $self->{NAME}); + $self->{FULLEXT} = $self->catdir(split /::/, $self->{NAME}); # Copied from DynaLoader: @@ -1550,17 +1675,17 @@ sub init_main { unless ($self->{PERL_SRC}){ my($dir); foreach $dir ($Updir, - File::Spec->catdir($Updir,$Updir), - File::Spec->catdir($Updir,$Updir,$Updir), - File::Spec->catdir($Updir,$Updir,$Updir,$Updir), - File::Spec->catdir($Updir,$Updir,$Updir,$Updir,$Updir)) + $self->catdir($Updir,$Updir), + $self->catdir($Updir,$Updir,$Updir), + $self->catdir($Updir,$Updir,$Updir,$Updir), + $self->catdir($Updir,$Updir,$Updir,$Updir,$Updir)) { if ( - -f File::Spec->catfile($dir,"config_h.SH") + -f $self->catfile($dir,"config_h.SH") && - -f File::Spec->catfile($dir,"perl.h") + -f $self->catfile($dir,"perl.h") && - -f File::Spec->catfile($dir,"lib","Exporter.pm") + -f $self->catfile($dir,"lib","Exporter.pm") ) { $self->{PERL_SRC}=$dir ; last; @@ -1572,28 +1697,28 @@ sub init_main { $self->{PERL_CORE} and !$self->{PERL_SRC}; if ($self->{PERL_SRC}){ - $self->{PERL_LIB} ||= File::Spec->catdir("$self->{PERL_SRC}","lib"); + $self->{PERL_LIB} ||= $self->catdir("$self->{PERL_SRC}","lib"); if (defined $Cross::platform) { $self->{PERL_ARCHLIB} = - File::Spec->catdir("$self->{PERL_SRC}","xlib",$Cross::platform); + $self->catdir("$self->{PERL_SRC}","xlib",$Cross::platform); $self->{PERL_INC} = - File::Spec->catdir("$self->{PERL_SRC}","xlib",$Cross::platform, + $self->catdir("$self->{PERL_SRC}","xlib",$Cross::platform, $Is_Win32?("CORE"):()); } else { $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; $self->{PERL_INC} = ($Is_Win32) ? - File::Spec->catdir($self->{PERL_LIB},"CORE") : $self->{PERL_SRC}; + $self->catdir($self->{PERL_LIB},"CORE") : $self->{PERL_SRC}; } # catch a situation that has occurred a few times in the past: unless ( - -s File::Spec->catfile($self->{PERL_SRC},'cflags') + -s $self->catfile($self->{PERL_SRC},'cflags') or $Is_VMS && - -s File::Spec->catfile($self->{PERL_SRC},'perlshr_attr.opt') + -s $self->catfile($self->{PERL_SRC},'perlshr_attr.opt') or $Is_Mac or @@ -1618,20 +1743,20 @@ from the perl source tree. my $old = $self->{PERL_LIB} || $self->{PERL_ARCHLIB} || $self->{PERL_INC}; $self->{PERL_LIB} ||= $Config{privlibexp}; $self->{PERL_ARCHLIB} ||= $Config{archlibexp}; - $self->{PERL_INC} = File::Spec->catdir("$self->{PERL_ARCHLIB}","CORE"); # wild guess for now + $self->{PERL_INC} = $self->catdir("$self->{PERL_ARCHLIB}","CORE"); # wild guess for now my $perl_h; - if (not -f ($perl_h = File::Spec->catfile($self->{PERL_INC},"perl.h")) + if (not -f ($perl_h = $self->catfile($self->{PERL_INC},"perl.h")) and not $old){ # Maybe somebody tries to build an extension with an # uninstalled Perl outside of Perl build tree my $found; for my $dir (@INC) { - $found = $dir, last if -e File::Spec->catdir($dir, "Config.pm"); + $found = $dir, last if -e $self->catdir($dir, "Config.pm"); } if ($found) { my $inc = dirname $found; - if (-e File::Spec->catdir($inc, "perl.h")) { + if (-e $self->catdir($inc, "perl.h")) { $self->{PERL_LIB} = $found; $self->{PERL_ARCHLIB} = $found; $self->{PERL_INC} = $inc; @@ -1643,7 +1768,7 @@ EOP } } - unless(-f ($perl_h = File::Spec->catfile($self->{PERL_INC},"perl.h"))) + unless(-f ($perl_h = $self->catfile($self->{PERL_INC},"perl.h"))) { die qq{ Error: Unable to locate installed Perl libraries or Perl source code. @@ -1669,10 +1794,6 @@ usually solves this kind of problem. # MakeMaker. $self->{INSTALLDIRS} ||= "site"; - - $self->init_INST; - $self->init_INSTALL; - $self->{MAN1EXT} ||= $Config{man1ext}; $self->{MAN3EXT} ||= $Config{man3ext}; @@ -1682,8 +1803,8 @@ usually solves this kind of problem. $self->{CONFIG} = [] unless (ref $self->{CONFIG}); push(@{$self->{CONFIG}}, @ExtUtils::MakeMaker::Get_from_Config); push(@{$self->{CONFIG}}, 'shellflags') if $Config{shellflags}; - my(%once_only,$m); - foreach $m (@{$self->{CONFIG}}){ + my(%once_only); + foreach my $m (@{$self->{CONFIG}}){ next if $once_only{$m}; print STDOUT "CONFIG key '$m' does not exist in Config.pm\n" unless exists $Config{$m}; @@ -1712,47 +1833,16 @@ usually solves this kind of problem. # make a simple check if we find Exporter warn "Warning: PERL_LIB ($self->{PERL_LIB}) seems not to be a perl library directory (Exporter.pm not found)" - unless -f File::Spec->catfile("$self->{PERL_LIB}","Exporter.pm") || + unless -f $self->catfile("$self->{PERL_LIB}","Exporter.pm") || $self->{NAME} eq "ExtUtils::MakeMaker"; - - # Determine VERSION and VERSION_FROM - ($self->{DISTNAME}=$self->{NAME}) =~ s#(::)#-#g unless $self->{DISTNAME}; - if ($self->{VERSION_FROM}){ - $self->{VERSION} = $self->parse_version($self->{VERSION_FROM}); - if( $self->{VERSION} eq 'undef' ) { - carp "WARNING: Setting VERSION via file ". - "'$self->{VERSION_FROM}' failed\n"; - } - } - - # strip blanks - if (defined $self->{VERSION}) { - $self->{VERSION} =~ s/^\s+//; - $self->{VERSION} =~ s/\s+$//; - } - else { - $self->{VERSION} = ''; - } - ($self->{VERSION_SYM} = $self->{VERSION}) =~ s/\W/_/g; - - $self->{DISTVNAME} = "$self->{DISTNAME}-$self->{VERSION}"; - - # Graham Barr and Paul Marquess had some ideas how to ensure - # version compatibility between the *.pm file and the - # corresponding *.xs file. The bottomline was, that we need an - # XS_VERSION macro that defaults to VERSION: - $self->{XS_VERSION} ||= $self->{VERSION}; - - - # --- Initialize Perl Binary Locations - $self->init_PERL; } =item init_others Initializes EXTRALIBS, BSLOADLIBS, LDLOADLIBS, LIBS, LD_RUN_PATH, -OBJECT, BOOTDEP, PERLMAINCC, LDFROM, LINKTYPE, NOOP, FIRST_MAKEFILE, -MAKEFILE, NOECHO, RM_F, RM_RF, TEST_F, TOUCH, CP, MV, CHMOD, UMASK_NULL +OBJECT, BOOTDEP, PERLMAINCC, LDFROM, LINKTYPE, SHELL, NOOP, +FIRST_MAKEFILE, MAKEFILE_OLD, NOECHO, RM_F, RM_RF, TEST_F, +TOUCH, CP, MV, CHMOD, UMASK_NULL =cut @@ -1764,9 +1854,9 @@ sub init_others { # --- Initialize Other Attributes # undefined. In any case we turn it into an anon array: # May check $Config{libs} too, thus not empty. - $self->{LIBS}=[''] unless $self->{LIBS}; + $self->{LIBS} = [$self->{LIBS}] unless ref $self->{LIBS}; - $self->{LIBS}=[$self->{LIBS}] if ref \$self->{LIBS} eq 'SCALAR'; + $self->{LIBS} = [''] unless @{$self->{LIBS}} && defined $self->{LIBS}[0]; $self->{LD_RUN_PATH} = ""; my($libs); foreach $libs ( @{$self->{LIBS}} ){ @@ -1802,36 +1892,61 @@ sub init_others { # --- Initialize Other Attributes : ($Config{usedl} ? 'dynamic' : 'static'); }; - # These get overridden for VMS and maybe some other systems - $self->{NOOP} ||= '$(SHELL) -c true'; - $self->{FIRST_MAKEFILE} ||= "Makefile"; - $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE}; - $self->{MAKE_APERL_FILE} ||= "Makefile.aperl"; - $self->{NOECHO} = '@' unless defined $self->{NOECHO}; - $self->{RM_F} ||= "rm -f"; - $self->{RM_RF} ||= "rm -rf"; - $self->{TOUCH} ||= "touch"; - $self->{TEST_F} ||= "test -f"; - $self->{CP} ||= "cp"; - $self->{MV} ||= "mv"; - $self->{CHMOD} ||= "chmod"; - $self->{UMASK_NULL} ||= "umask 0"; - $self->{DEV_NULL} ||= "> /dev/null 2>&1"; + $self->{NOOP} ||= '$(SHELL) -c true'; + $self->{NOECHO} = '@' unless defined $self->{NOECHO}; + + $self->{MAKEFILE} ||= 'Makefile'; + $self->{FIRST_MAKEFILE} ||= $self->{MAKEFILE}; + $self->{MAKEFILE_OLD} ||= '$(FIRST_MAKEFILE).old'; + $self->{MAKE_APERL_FILE} ||= '$(FIRST_MAKEFILE).aperl'; + + $self->{SHELL} ||= $Config{sh} || '/bin/sh'; + + $self->{ECHO} ||= 'echo'; + $self->{RM_F} ||= "rm -f"; + $self->{RM_RF} ||= "rm -rf"; + $self->{TOUCH} ||= "touch"; + $self->{TEST_F} ||= "test -f"; + $self->{CP} ||= "cp"; + $self->{MV} ||= "mv"; + $self->{CHMOD} ||= "chmod"; + $self->{MKPATH} ||= '$(PERLRUN) "-MExtUtils::Command" -e mkpath'; + $self->{EQUALIZE_TIMESTAMP} ||= + '$(PERLRUN) "-MExtUtils::Command" -e eqtime'; + + $self->{UNINST} ||= 0; + $self->{VERBINST} ||= 0; + $self->{MOD_INSTALL} ||= + $self->oneliner(<<'CODE', ['-MExtUtils::Install']); +install({@ARGV}, '$(VERBINST)', 0, '$(UNINST)'); +CODE + $self->{DOC_INSTALL} ||= + '$(PERLRUN) "-MExtUtils::Command::MM" -e perllocal_install'; + $self->{UNINSTALL} ||= + '$(PERLRUN) "-MExtUtils::Command::MM" -e uninstall'; + $self->{WARN_IF_OLD_PACKLIST} ||= + '$(PERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist'; + + $self->{UMASK_NULL} ||= "umask 0"; + $self->{DEV_NULL} ||= "> /dev/null 2>&1"; + + return 1; } =item init_INST $mm->init_INST; -Called by init_main. Sets up all INST_* variables. +Called by init_main. Sets up all INST_* variables except those related +to XS code. Those are handled in init_xs. =cut sub init_INST { my($self) = shift; - $self->{INST_ARCHLIB} ||= File::Spec->catdir($Curdir,"blib","arch"); - $self->{INST_BIN} ||= File::Spec->catdir($Curdir,'blib','bin'); + $self->{INST_ARCHLIB} ||= $self->catdir($Curdir,"blib","arch"); + $self->{INST_BIN} ||= $self->catdir($Curdir,'blib','bin'); # INST_LIB typically pre-set if building an extension after # perl has been built and installed. Setting INST_LIB allows @@ -1840,30 +1955,30 @@ sub init_INST { if ($self->{PERL_CORE}) { if (defined $Cross::platform) { $self->{INST_LIB} = $self->{INST_ARCHLIB} = - File::Spec->catdir($self->{PERL_LIB},"..","xlib", + $self->catdir($self->{PERL_LIB},"..","xlib", $Cross::platform); } else { $self->{INST_LIB} = $self->{INST_ARCHLIB} = $self->{PERL_LIB}; } } else { - $self->{INST_LIB} = File::Spec->catdir($Curdir,"blib","lib"); + $self->{INST_LIB} = $self->catdir($Curdir,"blib","lib"); } } my @parentdir = split(/::/, $self->{PARENT_NAME}); - $self->{INST_LIBDIR} = File::Spec->catdir($self->{INST_LIB},@parentdir); - $self->{INST_ARCHLIBDIR} = File::Spec->catdir($self->{INST_ARCHLIB}, + $self->{INST_LIBDIR} = $self->catdir($self->{INST_LIB},@parentdir); + $self->{INST_ARCHLIBDIR} = $self->catdir($self->{INST_ARCHLIB}, @parentdir); - $self->{INST_AUTODIR} = File::Spec->catdir($self->{INST_LIB},'auto', + $self->{INST_AUTODIR} = $self->catdir($self->{INST_LIB},'auto', $self->{FULLEXT}); - $self->{INST_ARCHAUTODIR} = File::Spec->catdir($self->{INST_ARCHLIB}, + $self->{INST_ARCHAUTODIR} = $self->catdir($self->{INST_ARCHLIB}, 'auto',$self->{FULLEXT}); - $self->{INST_SCRIPT} ||= File::Spec->catdir($Curdir,'blib','script'); + $self->{INST_SCRIPT} ||= $self->catdir($Curdir,'blib','script'); - $self->{INST_MAN1DIR} ||= File::Spec->catdir($Curdir,'blib','man1'); - $self->{INST_MAN3DIR} ||= File::Spec->catdir($Curdir,'blib','man3'); + $self->{INST_MAN1DIR} ||= $self->catdir($Curdir,'blib','man1'); + $self->{INST_MAN3DIR} ||= $self->catdir($Curdir,'blib','man3'); return 1; } @@ -1873,7 +1988,7 @@ sub init_INST { $mm->init_INSTALL; Called by init_main. Sets up all INSTALL_* variables (except -INSTALLDIRS) and PREFIX. +INSTALLDIRS) and *PREFIX. =cut @@ -1884,9 +1999,9 @@ sub init_INSTALL { if( $Config{usevendorprefix} ) { $Config_Override{installvendorman1dir} = - File::Spec->catdir($Config{vendorprefixexp}, 'man', 'man$(MAN1EXT)'); + $self->catdir($Config{vendorprefixexp}, 'man', 'man1'); $Config_Override{installvendorman3dir} = - File::Spec->catdir($Config{vendorprefixexp}, 'man', 'man$(MAN3EXT)'); + $self->catdir($Config{vendorprefixexp}, 'man', 'man3'); } else { $Config_Override{installvendorman1dir} = ''; @@ -1905,32 +2020,42 @@ sub init_INSTALL { # it up. unless( $Config{installsiteman1dir} ) { $Config_Override{installsiteman1dir} = - File::Spec->catdir($sprefix, 'man', 'man$(MAN1EXT)'); + $self->catdir($sprefix, 'man', 'man1'); } unless( $Config{installsiteman3dir} ) { $Config_Override{installsiteman3dir} = - File::Spec->catdir($sprefix, 'man', 'man$(MAN3EXT)'); + $self->catdir($sprefix, 'man', 'man3'); } unless( $Config{installsitebin} ) { $Config_Override{installsitebin} = - File::Spec->catdir($sprefix, 'bin'); + $self->catdir($sprefix, 'bin'); } - my $u_prefix = $self->{PREFIX} || ''; - my $u_sprefix = $self->{SITEPREFIX} || $u_prefix; - my $u_vprefix = $self->{VENDORPREFIX} || $u_prefix; + $self->{PREFIX} ||= ''; + + if( $self->{PREFIX} ) { + @{$self}{qw(PERLPREFIX SITEPREFIX VENDORPREFIX)} = + ('$(PREFIX)') x 3; + } + else { + $self->{PERLPREFIX} ||= $iprefix; + $self->{SITEPREFIX} ||= $sprefix; + $self->{VENDORPREFIX} ||= $vprefix; + } - $self->{PREFIX} ||= $u_prefix || $iprefix; - $self->{SITEPREFIX} ||= $u_sprefix || $sprefix; - $self->{VENDORPREFIX} ||= $u_vprefix || $vprefix; + # Add DESTDIR. + $self->{DESTDIR} ||= ''; + foreach my $prefix (qw(PREFIX PERLPREFIX SITEPREFIX VENDORPREFIX)) { + $self->{$prefix} = '$(DESTDIR)'.$self->{$prefix}; + } my $arch = $Config{archname}; my $version = $Config{version}; # default style - my $libstyle = 'lib/perl5'; + my $libstyle = $Config{installstyle} || 'lib/perl5'; my $manstyle = ''; if( $self->{LIBSTYLE} ) { @@ -1948,73 +2073,73 @@ sub init_INSTALL { my %bin_layouts = ( bin => { s => $iprefix, - r => $u_prefix, + t => 'perl', d => 'bin' }, vendorbin => { s => $vprefix, - r => $u_vprefix, + t => 'vendor', d => 'bin' }, sitebin => { s => $sprefix, - r => $u_sprefix, + t => 'site', d => 'bin' }, script => { s => $iprefix, - r => $u_prefix, + t => 'perl', d => 'bin' }, ); my %man_layouts = ( man1dir => { s => $iprefix, - r => $u_prefix, - d => 'man/man$(MAN1EXT)', + t => 'perl', + d => 'man/man1', style => $manstyle, }, siteman1dir => { s => $sprefix, - r => $u_sprefix, - d => 'man/man$(MAN1EXT)', + t => 'site', + d => 'man/man1', style => $manstyle, }, vendorman1dir => { s => $vprefix, - r => $u_vprefix, - d => 'man/man$(MAN1EXT)', + t => 'vendor', + d => 'man/man1', style => $manstyle, }, man3dir => { s => $iprefix, - r => $u_prefix, - d => 'man/man$(MAN3EXT)', + t => 'perl', + d => 'man/man3', style => $manstyle, }, siteman3dir => { s => $sprefix, - r => $u_sprefix, - d => 'man/man$(MAN3EXT)', + t => 'site', + d => 'man/man3', style => $manstyle, }, vendorman3dir => { s => $vprefix, - r => $u_vprefix, - d => 'man/man$(MAN3EXT)', + t => 'vendor', + d => 'man/man3', style => $manstyle, }, ); my %lib_layouts = ( privlib => { s => $iprefix, - r => $u_prefix, + t => 'perl', d => '', style => $libstyle, }, vendorlib => { s => $vprefix, - r => $u_vprefix, + t => 'vendor', d => '', style => $libstyle, }, sitelib => { s => $sprefix, - r => $u_sprefix, + t => 'site', d => 'site_perl', style => $libstyle, }, archlib => { s => $iprefix, - r => $u_prefix, + t => 'perl', d => "$version/$arch", style => $libstyle }, vendorarch => { s => $vprefix, - r => $u_vprefix, + t => 'vendor', d => "$version/$arch", style => $libstyle }, sitearch => { s => $sprefix, - r => $u_sprefix, + t => 'site', d => "site_perl/$version/$arch", style => $libstyle }, ); @@ -2027,7 +2152,7 @@ sub init_INSTALL { if( $var =~ /arch/ ) { $self->{$Installvar} ||= - File::Spec->catdir($self->{LIB}, $Config{archname}); + $self->catdir($self->{LIB}, $Config{archname}); } else { $self->{$Installvar} ||= $self->{LIB}; @@ -2035,10 +2160,15 @@ sub init_INSTALL { } } + my %type2prefix = ( perl => 'PERLPREFIX', + site => 'SITEPREFIX', + vendor => 'VENDORPREFIX' + ); my %layouts = (%bin_layouts, %man_layouts, %lib_layouts); while( my($var, $layout) = each(%layouts) ) { - my($s, $r, $d, $style) = @{$layout}{qw(s r d style)}; + my($s, $t, $d, $style) = @{$layout}{qw(s t d style)}; + my $r = '$('.$type2prefix{$t}.')'; print STDERR "Prefixing $var\n" if $Verbose >= 2; @@ -2046,22 +2176,34 @@ sub init_INSTALL { my $Installvar = uc $installvar; next if $self->{$Installvar}; - if( $r ) { - $d = "$style/$d" if $style; - $self->prefixify($installvar, $s, $r, $d); - } - else { - $self->{$Installvar} = $Config_Override{$installvar} || - $Config{$installvar}; - } + $d = "$style/$d" if $style; + $self->prefixify($installvar, $s, $r, $d); print STDERR " $Installvar == $self->{$Installvar}\n" if $Verbose >= 2; } + # Generate these if they weren't figured out. + $self->{VENDORARCHEXP} ||= $self->{INSTALLVENDORARCH}; + $self->{VENDORLIBEXP} ||= $self->{INSTALLVENDORLIB}; + return 1; } +=item init_linker + +Unix has no need of special linker flags. + +=cut + +sub init_linker { + my($self) = shift; + $self->{PERL_ARCHIVE} ||= ''; + $self->{PERL_ARCHIVE_AFTER} ||= ''; + $self->{EXPORT_LIST} ||= ''; +} + + =begin _protected =item init_lib2arch @@ -2114,6 +2256,7 @@ Called by init_main. Sets up ABSPERL, PERL, FULLPERL and all the PERL is allowed to be miniperl FULLPERL must be a complete perl + ABSPERL is PERL converted to an absolute path *PERLRUN contains everything necessary to run perl, find it's @@ -2135,8 +2278,12 @@ sub init_PERL { } # Build up a set of file names (not command names). - my $thisperl = File::Spec->canonpath($^X); + my $thisperl = $self->canonpath($^X); $thisperl .= $Config{exe_ext} unless $thisperl =~ m/$Config{exe_ext}$/i; + + # We need a relative path to perl when in the core. + $thisperl = $self->abs2rel($thisperl) if $self->{PERL_CORE}; + my @perls = ($thisperl); push @perls, map { "$_$Config{exe_ext}" } ('perl', 'perl5', "perl$Config{version}"); @@ -2164,11 +2311,11 @@ sub init_PERL { # sometimes. $self->{ABSPERL} = $self->{PERL}; my $has_mcr = $self->{ABSPERL} =~ s/^MCR\s*//; - if( File::Spec->file_name_is_absolute($self->{ABSPERL}) ) { + if( $self->file_name_is_absolute($self->{ABSPERL}) ) { $self->{ABSPERL} = '$(PERL)'; } else { - $self->{ABSPERL} = File::Spec->rel2abs($self->{ABSPERL}); + $self->{ABSPERL} = $self->rel2abs($self->{ABSPERL}); $self->{ABSPERL} = 'MCR '.$self->{ABSPERL} if $has_mcr; } @@ -2177,10 +2324,12 @@ sub init_PERL { # How do we run perl? foreach my $perl (qw(PERL FULLPERL ABSPERL)) { - $self->{$perl.'RUN'} = "\$($perl)"; + my $run = $perl.'RUN'; + + $self->{$run} = "\$($perl)"; # Make sure perl can find itself before it's installed. - $self->{$perl.'RUN'} .= q{ "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)"} + $self->{$run} .= q{ "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)"} if $self->{UNINSTALLED_PERL} || $self->{PERL_CORE}; $self->{$perl.'RUNINST'} = @@ -2190,6 +2339,39 @@ sub init_PERL { return 1; } + +=item init_platform (o) + +Add MM_Unix_VERSION. + +=item platform_constants (o) + +=cut + +sub init_platform { + my($self) = shift; + + $self->{MM_Unix_VERSION} = $VERSION; + $self->{PERL_MALLOC_DEF} = '-DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc '. + '-Dfree=Perl_mfree -Drealloc=Perl_realloc '. + '-Dcalloc=Perl_calloc'; + +} + +sub platform_constants { + my($self) = shift; + my $make_frag = ''; + + foreach my $macro (qw(MM_Unix_VERSION PERL_MALLOC_DEF)) + { + next unless defined $self->{$macro}; + $make_frag .= "$macro = $self->{$macro}\n"; + } + + return $make_frag; +} + + =item init_PERM $mm->init_PERM @@ -2201,12 +2383,38 @@ Called by init_main. Initializes PERL_* sub init_PERM { my($self) = shift; - $self->{PERM_RW} = 644; - $self->{PERM_RWX} = 755; + $self->{PERM_RW} = 644 unless defined $self->{PERM_RW}; + $self->{PERM_RWX} = 755 unless defined $self->{PERM_RWX}; return 1; } - + + +=item init_xs + + $mm->init_xs + +Sets up macros having to do with XS code. Currently just INST_STATIC, +INST_DYNAMIC and INST_BOOT. + +=cut + +sub init_xs { + my $self = shift; + + if ($self->has_link_code()) { + $self->{INST_STATIC} = + $self->catfile('$(INST_ARCHAUTODIR)', '$(BASEEXT)$(LIB_EXT)'); + $self->{INST_DYNAMIC} = + $self->catfile('$(INST_ARCHAUTODIR)', '$(DLBASE).$(DLEXT)'); + $self->{INST_BOOT} = + $self->catfile('$(INST_ARCHAUTODIR)', '$(BASEEXT).bs'); + } else { + $self->{INST_STATIC} = ''; + $self->{INST_DYNAMIC} = ''; + $self->{INST_BOOT} = ''; + } +} =item install (o) @@ -2230,43 +2438,44 @@ install_vendor :: all pure_vendor_install doc_vendor_install pure_install :: pure_$(INSTALLDIRS)_install doc_install :: doc_$(INSTALLDIRS)_install - }.$self->{NOECHO}.q{echo Appending installation info to $(INSTALLARCHLIB)/perllocal.pod pure__install : pure_site_install - @echo INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site doc__install : doc_site_install - @echo INSTALLDIRS not defined, defaulting to INSTALLDIRS=site + $(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site pure_perl_install :: - }.$self->{NOECHO}.q{$(MOD_INSTALL) \ - read }.File::Spec->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q{ \ - write }.File::Spec->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q{ \ + $(NOECHO) $(MOD_INSTALL) \ + read }.$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q{ \ + write }.$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q{ \ $(INST_LIB) $(INSTALLPRIVLIB) \ $(INST_ARCHLIB) $(INSTALLARCHLIB) \ $(INST_BIN) $(INSTALLBIN) \ $(INST_SCRIPT) $(INSTALLSCRIPT) \ $(INST_MAN1DIR) $(INSTALLMAN1DIR) \ $(INST_MAN3DIR) $(INSTALLMAN3DIR) - }.$self->{NOECHO}.q{$(WARN_IF_OLD_PACKLIST) \ - }.File::Spec->catdir('$(SITEARCHEXP)','auto','$(FULLEXT)').q{ + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + }.$self->catdir('$(SITEARCHEXP)','auto','$(FULLEXT)').q{ pure_site_install :: - }.$self->{NOECHO}.q{$(MOD_INSTALL) \ - read }.File::Spec->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q{ \ - write }.File::Spec->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q{ \ + $(NOECHO) $(MOD_INSTALL) \ + read }.$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q{ \ + write }.$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q{ \ $(INST_LIB) $(INSTALLSITELIB) \ $(INST_ARCHLIB) $(INSTALLSITEARCH) \ $(INST_BIN) $(INSTALLSITEBIN) \ $(INST_SCRIPT) $(INSTALLSCRIPT) \ $(INST_MAN1DIR) $(INSTALLSITEMAN1DIR) \ $(INST_MAN3DIR) $(INSTALLSITEMAN3DIR) - }.$self->{NOECHO}.q{$(WARN_IF_OLD_PACKLIST) \ - }.File::Spec->catdir('$(PERL_ARCHLIB)','auto','$(FULLEXT)').q{ + $(NOECHO) $(WARN_IF_OLD_PACKLIST) \ + }.$self->catdir('$(PERL_ARCHLIB)','auto','$(FULLEXT)').q{ pure_vendor_install :: - }.$self->{NOECHO}.q{$(MOD_INSTALL) \ + $(NOECHO) $(MOD_INSTALL) \ + read }.$self->catfile('$(VENDORARCHEXP)','auto','$(FULLEXT)','.packlist').q{ \ + write }.$self->catfile('$(INSTALLVENDORARCH)','auto','$(FULLEXT)','.packlist').q{ \ $(INST_LIB) $(INSTALLVENDORLIB) \ $(INST_ARCHLIB) $(INSTALLVENDORARCH) \ $(INST_BIN) $(INSTALLVENDORBIN) \ @@ -2275,26 +2484,37 @@ pure_vendor_install :: $(INST_MAN3DIR) $(INSTALLVENDORMAN3DIR) doc_perl_install :: - -}.$self->{NOECHO}.q{$(MKPATH) $(INSTALLARCHLIB) - -}.$self->{NOECHO}.q{$(DOC_INSTALL) \ + $(NOECHO) $(ECHO) Appending installation info to $(INSTALLARCHLIB)/perllocal.pod + -$(NOECHO) $(MKPATH) $(INSTALLARCHLIB) + -$(NOECHO) $(DOC_INSTALL) \ "Module" "$(NAME)" \ "installed into" "$(INSTALLPRIVLIB)" \ LINKTYPE "$(LINKTYPE)" \ VERSION "$(VERSION)" \ EXE_FILES "$(EXE_FILES)" \ - >> }.File::Spec->catfile('$(INSTALLARCHLIB)','perllocal.pod').q{ + >> }.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q{ doc_site_install :: - -}.$self->{NOECHO}.q{$(MKPATH) $(INSTALLARCHLIB) - -}.$self->{NOECHO}.q{$(DOC_INSTALL) \ + $(NOECHO) $(ECHO) Appending installation info to $(INSTALLSITEARCH)/perllocal.pod + -$(NOECHO) $(MKPATH) $(INSTALLSITEARCH) + -$(NOECHO) $(DOC_INSTALL) \ "Module" "$(NAME)" \ "installed into" "$(INSTALLSITELIB)" \ LINKTYPE "$(LINKTYPE)" \ VERSION "$(VERSION)" \ EXE_FILES "$(EXE_FILES)" \ - >> }.File::Spec->catfile('$(INSTALLSITEARCH)','perllocal.pod').q{ + >> }.$self->catfile('$(INSTALLSITEARCH)','perllocal.pod').q{ doc_vendor_install :: + $(NOECHO) $(ECHO) Appending installation info to $(INSTALLVENDORARCH)/perllocal.pod + -$(NOECHO) $(MKPATH) $(INSTALLVENDORARCH) + -$(NOECHO) $(DOC_INSTALL) \ + "Module" "$(NAME)" \ + "installed into" "$(INSTALLVENDORLIB)" \ + LINKTYPE "$(LINKTYPE)" \ + VERSION "$(VERSION)" \ + EXE_FILES "$(EXE_FILES)" \ + >> }.$self->catfile('$(INSTALLVENDORARCH)','perllocal.pod').q{ }; @@ -2302,12 +2522,13 @@ doc_vendor_install :: uninstall :: uninstall_from_$(INSTALLDIRS)dirs uninstall_from_perldirs :: - }.$self->{NOECHO}. - q{$(UNINSTALL) }.File::Spec->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q{ + $(NOECHO) $(UNINSTALL) }.$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q{ uninstall_from_sitedirs :: - }.$self->{NOECHO}. - q{$(UNINSTALL) }.File::Spec->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q{ + $(NOECHO) $(UNINSTALL) }.$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q{ + +uninstall_from_vendordirs :: + $(NOECHO) $(UNINSTALL) }.$self->catfile('$(VENDORARCHEXP)','auto','$(FULLEXT)','.packlist').q{ }; join("",@m); @@ -2326,7 +2547,7 @@ sub installbin { my(@m, $from, $to, %fromto, @to); push @m, $self->dir_target(qw[$(INST_SCRIPT)]); for $from (@{$self->{EXE_FILES}}) { - my($path)= File::Spec->catfile('$(INST_SCRIPT)', basename($from)); + my($path)= $self->catfile('$(INST_SCRIPT)', basename($from)); local($_) = $path; # for backwards compatibility $to = $self->libscan($path); print "libscan($from) => '$to'\n" if ($Verbose >=2); @@ -2342,41 +2563,26 @@ EXE_FILES = @{$self->{EXE_FILES}} -e "MY->fixin(shift)" }).qq{ pure_all :: @to - $self->{NOECHO}\$(NOOP) + \$(NOECHO) \$(NOOP) realclean :: - $self->{RM_F} @to + \$(RM_F) @to }); while (($from,$to) = each %fromto) { last unless defined $from; my $todir = dirname($to); push @m, " -$to: $from $self->{MAKEFILE} " . File::Spec->catdir($todir,'.exists') . " - $self->{NOECHO}$self->{RM_F} $to - $self->{CP} $from $to +$to: $from \$(FIRST_MAKEFILE) " . $self->catdir($todir,'.exists') . " + \$(NOECHO) \$(RM_F) $to + \$(CP) $from $to \$(FIXIN) $to - -$self->{NOECHO}\$(CHMOD) \$(PERM_RWX) $to + -\$(NOECHO) \$(CHMOD) \$(PERM_RWX) $to "; } join "", @m; } -=item libscan (o) - -Takes a path to a file that is found by init_dirscan and returns false -if we don't want to include this file in the library. Mainly used to -exclude RCS, CVS, and SCCS directories from installation. - -=cut - -# '; - -sub libscan { - my($self,$path) = @_; - return '' if $path =~ m:\b(RCS|CVS|SCCS)\b: ; - $path; -} =item linkext (o) @@ -2391,7 +2597,7 @@ sub linkext { $attribs{LINKTYPE} : '$(LINKTYPE)'; " linkext :: $linktype - $self->{NOECHO}\$(NOOP) + \$(NOECHO) \$(NOOP) "; } @@ -2462,10 +2668,10 @@ $(MAP_TARGET) :: static $(MAKE_APERL_FILE) $(MAKE) -f $(MAKE_APERL_FILE) $@ $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) - }.$self->{NOECHO}.q{echo Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) - }.$self->{NOECHO}.q{$(PERLRUNINST) \ + $(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET) + $(NOECHO) $(PERLRUNINST) \ Makefile.PL DIR=}, $dir, q{ \ - MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ + FIRST_MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=}; foreach (@ARGV){ @@ -2593,10 +2799,10 @@ MAP_PRELIBS = $Config{perllibs} $Config{cryptlib} if (! -f $libperl and ! -f $lperl) { # We did not find a static libperl. Maybe there is a shared one? - if ($^O eq 'solaris' or $^O eq 'sunos') { + if ($Is_SunOS) { $lperl = $libperl = "$dir/$Config{libperl}"; # SUNOS ld does not take the full path to a shared library - $libperl = '' if $^O eq 'sunos'; + $libperl = '' if $Is_SunOS4; } } @@ -2615,10 +2821,10 @@ LLIBPERL = $llibperl "; push @m, " -\$(INST_ARCHAUTODIR)/extralibs.all: \$(INST_ARCHAUTODIR)/.exists ".join(" \\\n\t", @$extra)." - $self->{NOECHO}$self->{RM_F} \$\@ - $self->{NOECHO}\$(TOUCH) \$\@ -"; +\$(INST_ARCHAUTODIR)/extralibs.all: \$(INST_ARCHAUTODIR)\$(DIRFILESEP).exists ".join(" \\\n\t", @$extra).' + $(NOECHO) $(RM_F) $@ + $(NOECHO) $(TOUCH) $@ +'; my $catfile; foreach $catfile (@$extra){ @@ -2628,10 +2834,10 @@ LLIBPERL = $llibperl push @m, " \$(MAP_TARGET) :: $tmp/perlmain\$(OBJ_EXT) \$(MAP_LIBPERL) \$(MAP_STATIC) \$(INST_ARCHAUTODIR)/extralibs.all \$(MAP_LINKCMD) -o \$\@ \$(OPTIMIZE) $tmp/perlmain\$(OBJ_EXT) \$(LDFROM) \$(MAP_STATIC) \$(LLIBPERL) `cat \$(INST_ARCHAUTODIR)/extralibs.all` \$(MAP_PRELIBS) - $self->{NOECHO}echo 'To install the new \"\$(MAP_TARGET)\" binary, call' - $self->{NOECHO}echo ' make -f $makefilename inst_perl MAP_TARGET=\$(MAP_TARGET)' - $self->{NOECHO}echo 'To remove the intermediate files say' - $self->{NOECHO}echo ' make -f $makefilename map_clean' + \$(NOECHO) \$(ECHO) 'To install the new \"\$(MAP_TARGET)\" binary, call' + \$(NOECHO) \$(ECHO) ' make -f $makefilename inst_perl MAP_TARGET=\$(MAP_TARGET)' + \$(NOECHO) \$(ECHO) 'To remove the intermediate files say' + \$(NOECHO) \$(ECHO) ' make -f $makefilename map_clean' $tmp/perlmain\$(OBJ_EXT): $tmp/perlmain.c "; @@ -2639,25 +2845,25 @@ $tmp/perlmain\$(OBJ_EXT): $tmp/perlmain.c push @m, qq{ $tmp/perlmain.c: $makefilename}, q{ - }.$self->{NOECHO}.q{echo Writing $@ - }.$self->{NOECHO}.q{$(PERL) $(MAP_PERLINC) "-MExtUtils::Miniperl" \\ + $(NOECHO) $(ECHO) Writing $@ + $(NOECHO) $(PERL) $(MAP_PERLINC) "-MExtUtils::Miniperl" \\ -e "writemain(grep s#.*/auto/##s, split(q| |, q|$(MAP_STATIC)|))" > $@t && $(MV) $@t $@ }; - push @m, "\t",$self->{NOECHO}.q{$(PERL) $(INSTALLSCRIPT)/fixpmain + push @m, "\t", q{$(NOECHO) $(PERL) $(INSTALLSCRIPT)/fixpmain } if (defined (&Dos::UseLFN) && Dos::UseLFN()==0); push @m, q{ doc_inst_perl: - }.$self->{NOECHO}.q{echo Appending installation info to $(INSTALLARCHLIB)/perllocal.pod - -}.$self->{NOECHO}.q{$(MKPATH) $(INSTALLARCHLIB) - -}.$self->{NOECHO}.q{$(DOC_INSTALL) \ + $(NOECHO) $(ECHO) Appending installation info to $(INSTALLARCHLIB)/perllocal.pod + -$(NOECHO) $(MKPATH) $(INSTALLARCHLIB) + -$(NOECHO) $(DOC_INSTALL) \ "Perl binary" "$(MAP_TARGET)" \ MAP_STATIC "$(MAP_STATIC)" \ MAP_EXTRA "`cat $(INST_ARCHAUTODIR)/extralibs.all`" \ MAP_LIBPERL "$(MAP_LIBPERL)" \ - >> }.File::Spec->catfile('$(INSTALLARCHLIB)','perllocal.pod').q{ + >> }.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q{ }; @@ -2665,7 +2871,7 @@ doc_inst_perl: inst_perl: pure_inst_perl doc_inst_perl pure_inst_perl: $(MAP_TARGET) - }.$self->{CP}.q{ $(MAP_TARGET) }.File::Spec->catfile('$(INSTALLBIN)','$(MAP_TARGET)').q{ + }.$self->{CP}.q{ $(MAP_TARGET) }.$self->catfile('$(INSTALLBIN)','$(MAP_TARGET)').q{ clean :: map_clean @@ -2695,15 +2901,15 @@ $(OBJECT) : $(FIRST_MAKEFILE) push @m, q{ # We take a very conservative approach here, but it\'s worth it. # We move Makefile to Makefile.old here to avoid gnu make looping. -}.$self->{MAKEFILE}.q{ : Makefile.PL $(CONFIGDEP) - }.$self->{NOECHO}.q{echo "Makefile out-of-date with respect to $?" - }.$self->{NOECHO}.q{echo "Cleaning current config before rebuilding Makefile..." - -}.$self->{NOECHO}.q{$(RM_F) }."$self->{MAKEFILE}.old".q{ - -}.$self->{NOECHO}.q{$(MV) }."$self->{MAKEFILE} $self->{MAKEFILE}.old".q{ - -$(MAKE) -f }.$self->{MAKEFILE}.q{.old clean $(DEV_NULL) || $(NOOP) +$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP) $(VERSION_FROM) + $(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?" + $(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..." + $(NOECHO) $(RM_F) $(MAKEFILE_OLD) + $(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + -$(MAKE) -f $(MAKEFILE_OLD) clean $(DEV_NULL) || $(NOOP) $(PERLRUN) Makefile.PL }.join(" ",map(qq["$_"],@ARGV)).q{ - }.$self->{NOECHO}.q{echo "==> Your Makefile has been rebuilt. <==" - }.$self->{NOECHO}.q{echo "==> Please rerun the make command. <==" + $(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <==" + $(NOECHO) $(ECHO) "==> Please rerun the make command. <==" false }; @@ -2711,58 +2917,6 @@ $(OBJECT) : $(FIRST_MAKEFILE) join "", @m; } -=item manifypods (o) - -Defines targets and routines to translate the pods into manpages and -put them into the INST_* directories. - -=cut - -sub manifypods { - my($self, %attribs) = @_; - return "\nmanifypods : pure_all\n\t$self->{NOECHO}\$(NOOP)\n" unless - %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}}; - my($dist); - my($pod2man_exe); - if (defined $self->{PERL_SRC}) { - $pod2man_exe = File::Spec->catfile($self->{PERL_SRC},'pod','pod2man'); - } else { - $pod2man_exe = File::Spec->catfile($Config{scriptdirexp},'pod2man'); - } - unless ($pod2man_exe = $self->perl_script($pod2man_exe)) { - # Maybe a build by uninstalled Perl? - $pod2man_exe = File::Spec->catfile($self->{PERL_INC}, "pod", "pod2man"); - } - unless ($pod2man_exe = $self->perl_script($pod2man_exe)) { - # No pod2man but some MAN3PODS to be installed - print <{MAKEFILE}, q[";' \\ --e 'print "Manifying $$m{$$_}\n";' \\ --e 'system(q[$(PERLRUN) $(POD2MAN_EXE) ].qq[$$_>$$m{$$_}])==0 or warn "Couldn\\047t install $$m{$$_}\n";' \\ --e 'chmod(oct($(PERM_RW)), $$m{$$_}) or warn "chmod $(PERM_RW) $$m{$$_}: $$!\n";}' -]; - push @m, "\nmanifypods : pure_all "; - push @m, join " \\\n\t", keys %{$self->{MAN1PODS}}, keys %{$self->{MAN3PODS}}; - - push(@m,"\n"); - if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) { - push @m, "\t$self->{NOECHO}\$(POD2MAN) \\\n\t"; - push @m, join " \\\n\t", %{$self->{MAN1PODS}}, %{$self->{MAN3PODS}}; - } - join('', @m); -} =item maybe_command @@ -2776,44 +2930,6 @@ sub maybe_command { return; } -=item maybe_command_in_dirs - -method under development. Not yet used. Ask Ilya :-) - -=cut - -sub maybe_command_in_dirs { # $ver is optional argument if looking for perl -# Ilya's suggestion. Not yet used, want to understand it first, but at least the code is here - my($self, $names, $dirs, $trace, $ver) = @_; - my($name, $dir); - foreach $dir (@$dirs){ - next unless defined $dir; # $self->{PERL_SRC} may be undefined - foreach $name (@$names){ - my($abs,$tryabs); - if (File::Spec->file_name_is_absolute($name)) { # /foo/bar - $abs = $name; - } elsif (File::Spec->canonpath($name) eq File::Spec->canonpath(basename($name))) { # bar - $abs = File::Spec->catfile($dir, $name); - } else { # foo/bar - $abs = File::Spec->catfile($Curdir, $name); - } - print "Checking $abs for $name\n" if ($trace >= 2); - next unless $tryabs = $self->maybe_command($abs); - print "Substituting $tryabs instead of $abs\n" - if ($trace >= 2 and $tryabs ne $abs); - $abs = $tryabs; - if (defined $ver) { - print "Executing $abs\n" if ($trace >= 2); - if (`$abs -e 'require $ver; print "VER_OK\n" ' 2>&1` =~ /VER_OK/) { - print "Using PERL=$abs\n" if $trace; - return $abs; - } - } else { # Do not look for perl - return $abs; - } - } - } -} =item needs_linking (o) @@ -2826,7 +2942,7 @@ sub needs_linking { my($self) = shift; my($child,$caller); $caller = (caller(0))[3]; - confess("Needs_linking called too early") if + confess("needs_linking called too early") if $caller =~ /^ExtUtils::MakeMaker::/; return $self->{NEEDS_LINKING} if defined $self->{NEEDS_LINKING}; if ($self->has_link_code or $self->{MAKEAPERL}){ @@ -2985,10 +3101,10 @@ sub perldepend { # We do NOT just update config.h because that is not sufficient. # An out of date config.h is not fatal but complains loudly! $(PERL_INC)/config.h: $(PERL_SRC)/config.sh - -}.$self->{NOECHO}.q{echo "Warning: $(PERL_INC)/config.h out of date with $(PERL_SRC)/config.sh"; false + -$(NOECHO) $(ECHO) "Warning: $(PERL_INC)/config.h out of date with $(PERL_SRC)/config.sh"; false $(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh - }.$self->{NOECHO}.q{echo "Warning: $(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh" + $(NOECHO) $(ECHO) "Warning: $(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh" cd $(PERL_SRC) && $(MAKE) lib/Config.pm } if $self->{PERL_SRC}; @@ -3065,7 +3181,7 @@ interpreted as an octal value. =cut sub perm_rw { - shift->{PERM_RW} || "644"; + return shift->{PERM_RW}; } =item perm_rwx (o) @@ -3078,7 +3194,7 @@ See also perl_rw. =cut sub perm_rwx { - shift->{PERM_RWX} || "755"; + return shift->{PERM_RWX}; } =item pm_to_blib @@ -3088,36 +3204,23 @@ destination and autosplits them. See L =cut -sub _pm_to_blib_flush { - my ($self, $autodir, $rr, $ra, $rl) = @_; - $$rr .= -q{ }.$self->{NOECHO}.q[$(PERLRUNINST) "-MExtUtils::Install" \ - -e "pm_to_blib({qw{].qq[@$ra].q[}},'].$autodir.q{','$(PM_FILTER)')" -}; - @$ra = (); - $$rl = 0; -} - sub pm_to_blib { my $self = shift; - my($autodir) = File::Spec->catdir('$(INST_LIB)','auto'); + my($autodir) = $self->catdir('$(INST_LIB)','auto'); my $r = q{ pm_to_blib: $(TO_INST_PM) }; - my %pm_to_blib = %{$self->{PM}}; - my @a; - my $l = 0; - while (my ($pm, $blib) = each %pm_to_blib) { - my $la = length $pm; - my $lb = length $blib; - if ($l + $la + $lb + @a / 2 > 200) { # limit line length - _pm_to_blib_flush($self, $autodir, \$r, \@a, \$l); - } - push @a, $pm, $blib; - $l += $la + $lb; - } - _pm_to_blib_flush($self, $autodir, \$r, \@a, \$l); - return $r.q{ }.$self->{NOECHO}.q{$(TOUCH) $@}; + + my $pm_to_blib = $self->oneliner(<split_command($pm_to_blib, %{$self->{PM}}); + + $r .= join '', map { "\t\$(NOECHO) $_\n" } @cmds; + $r .= q{ $(NOECHO) $(TOUCH) $@}; + + return $r; } =item post_constants (o) @@ -3128,7 +3231,6 @@ within Makefile.PL after all constants have been defined. =cut sub post_constants{ - my($self) = shift; ""; } @@ -3140,7 +3242,6 @@ chunk of text to the Makefile after the object is initialized. =cut sub post_initialize { - my($self) = shift; ""; } @@ -3152,7 +3253,6 @@ text to the Makefile at the end. =cut sub postamble { - my($self) = shift; ""; } @@ -3182,40 +3282,38 @@ sub ppd { my $author = $self->{AUTHOR} || ''; $author =~ s//>/g; - $author =~ s/@/\\@/g; - - my $make_ppd = sprintf <<'PPD_OUT', $pack_ver, $abstract, $author; -# Creates a PPD (Perl Package Description) for a binary distribution. -ppd: - @$(PERL) -e "print qq{\n\t$(DISTNAME)\n\t%s\n\t%s\n}" > $(DISTNAME).ppd -PPD_OUT + my $ppd_xml = sprintf <<'PPD_HTML', $pack_ver, $abstract, $author; + + $(DISTNAME) + %s + %s +PPD_HTML - $make_ppd .= ' @$(PERL) -e "print qq{\t\n'; + $ppd_xml .= " \n"; foreach my $prereq (sort keys %{$self->{PREREQ_PM}}) { my $pre_req = $prereq; $pre_req =~ s/::/-/g; my ($dep_ver) = join ",", (split (/\./, $self->{PREREQ_PM}{$prereq}), (0) x 4) [0 .. 3]; - $make_ppd .= sprintf q{\t\t\n}, $pre_req, $dep_ver; - } - $make_ppd .= qq[}" >> \$(DISTNAME).ppd\n]; - - - $make_ppd .= sprintf <<'PPD_OUT', $Config{archname}; - @$(PERL) -e "print qq{\t\t\n\t\t\n + $ppd_xml .= sprintf <<'PPD_OUT', $pre_req, $dep_ver; + PPD_OUT - chomp $make_ppd; + } + $ppd_xml .= sprintf <<'PPD_OUT', $Config{archname}; + + +PPD_OUT if ($self->{PPM_INSTALL_SCRIPT}) { if ($self->{PPM_INSTALL_EXEC}) { - $make_ppd .= sprintf q{\t\t%s\n}, + $ppd_xml .= sprintf qq{ %s\n}, $self->{PPM_INSTALL_EXEC}, $self->{PPM_INSTALL_SCRIPT}; } else { - $make_ppd .= sprintf q{\t\t%s\n}, + $ppd_xml .= sprintf qq{ %s\n}, $self->{PPM_INSTALL_SCRIPT}; } } @@ -3223,13 +3321,20 @@ PPD_OUT my ($bin_location) = $self->{BINARY_LOCATION} || ''; $bin_location =~ s/\\/\\\\/g; - $make_ppd .= sprintf q{\t\t\n}, $bin_location; - $make_ppd .= q{\t\n}; - $make_ppd .= q{\n}; + $ppd_xml .= sprintf <<'PPD_XML', $bin_location; + + + +PPD_XML + + my @ppd_cmds = $self->echo($ppd_xml, '$(DISTNAME).ppd'); - $make_ppd .= '}" >> $(DISTNAME).ppd'; + return sprintf <<'PPD_OUT', join "\n\t", @ppd_cmds; +# Creates a PPD (Perl Package Description) for a binary distribution. +ppd: + %s +PPD_OUT - return $make_ppd; } =item prefixify @@ -3237,8 +3342,12 @@ PPD_OUT $MM->prefixify($var, $prefix, $new_prefix, $default); Using either $MM->{uc $var} || $Config{lc $var}, it will attempt to -replace it's $prefix with a $new_prefix. Should the $prefix fail to -match it sill simply set it to the $new_prefix + $default. +replace it's $prefix with a $new_prefix. + +Should the $prefix fail to match I a PREFIX was given as an +argument to WriteMakefile() it will set it to the $new_prefix + +$default. This is for systems whose file layouts don't neatly fit into +our ideas of prefixes. This is for heuristics which attempt to create directory structures that mirror those of the installed perl. @@ -3263,12 +3372,12 @@ sub prefixify { print STDERR " prefixify $var => $path\n" if $Verbose >= 2; print STDERR " from $sprefix to $rprefix\n" if $Verbose >= 2; - unless( $path =~ s{^\Q$sprefix\E\b}{$rprefix}s ) { + if( $path !~ s{^\Q$sprefix\E\b}{$rprefix}s && $self->{ARGS}{PREFIX} ) { print STDERR " cannot prefix, using default.\n" if $Verbose >= 2; print STDERR " no default!\n" if !$default && $Verbose >= 2; - $path = File::Spec->catdir($rprefix, $default) if $default; + $path = $self->catdir($rprefix, $default) if $default; } print " now $path\n" if $Verbose >= 2; @@ -3294,7 +3403,7 @@ sub processPL { foreach $target (@$list) { push @m, " all :: $target - $self->{NOECHO}\$(NOOP) + \$(NOECHO) \$(NOOP) $target :: $plfile \$(PERLRUNINST) $plfile $target @@ -3313,11 +3422,11 @@ but handles simple ones. =cut sub quote_paren { - local $_ = shift; - s/\$\((.+?)\)/\$\\\\($1\\\\)/g; # protect $(...) - s/(?{DIR}}){ - push(@m, sprintf($sub,$_,"$self->{MAKEFILE}.old","-f $self->{MAKEFILE}.old")); - push(@m, sprintf($sub,$_,"$self->{MAKEFILE}",'')); - } - push(@m, " $self->{RM_RF} \$(INST_AUTODIR) \$(INST_ARCHAUTODIR)\n"); - push(@m, " $self->{RM_RF} \$(DISTVNAME)\n"); if( $self->has_link_code ){ - push(@m, " $self->{RM_F} \$(INST_DYNAMIC) \$(INST_BOOT)\n"); - push(@m, " $self->{RM_F} \$(INST_STATIC)\n"); + push(@m, " \$(RM_F) \$(INST_DYNAMIC) \$(INST_BOOT)\n"); + push(@m, " \$(RM_F) \$(INST_STATIC)\n"); } + + my @files = (); + push @files, $attribs{FILES} if $attribs{FILES}; + push @files, '$(FIRST_MAKEFILE)', '$(MAKEFILE_OLD)'; + + # Occasionally files are repeated several times from different sources + { my(%f) = map { ($_,1) } @files; @files = keys %f; } + # Issue a several little RM_F commands rather than risk creating a # very long command line (useful for extensions such as Encode # that have many files). - if (keys %{$self->{PM}}) { - my $line = ""; - foreach (values %{$self->{PM}}) { - if (length($line) + length($_) > 80) { - push @m, "\t$self->{RM_F} $line\n"; - $line = $_; - } - else { - $line .= " $_"; - } - } - push @m, "\t$self->{RM_F} $line\n" if $line; + my $line = ""; + foreach my $file (@files) { + if (length($line) + length($file) > 200) { + push @m, "\t\$(RM_F) $line\n"; + $line = $file; + } + else { + $line .= " $file"; + } } - my(@otherfiles) = ($self->{MAKEFILE}, - "$self->{MAKEFILE}.old"); # Makefiles last - push(@otherfiles, $attribs{FILES}) if $attribs{FILES}; - push(@m, " $self->{RM_RF} @otherfiles\n") if @otherfiles; - push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; + push @m, "\t\$(RM_F) $line\n" if $line; + push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; + join("", @m); } + +=item realclean_subdirs_target + + my $make_frag = $MM->realclean_subdirs_target; + +Returns the realclean_subdirs target. This is used by the realclean +target to call realclean on any subdirectories which contain Makefiles. + +=cut + +sub realclean_subdirs_target { + my $self = shift; + + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +realclean_subdirs : + $(NOECHO) $(NOOP) +NOOP_FRAG + + my $rclean = "realclean_subdirs :\n"; + + foreach my $dir (@{$self->{DIR}}){ + $rclean .= sprintf <<'RCLEAN', $dir, $dir; + -cd %s && $(TEST_F) $(MAKEFILE_OLD) && $(MAKE) -f $(MAKEFILE_OLD) realclean + -cd %s && $(TEST_F) $(FIRST_MAKEFILE) && $(MAKE) realclean +RCLEAN + + } + + return $rclean; +} + + =item replace_manpage_separator my $man_name = $MM->replace_manpage_separator($file_path); @@ -3400,6 +3526,78 @@ sub replace_manpage_separator { return $man; } + +=item oneliner (o) + +=cut + +sub oneliner { + my($self, $cmd, $switches) = @_; + $switches = [] unless defined $switches; + + # Strip leading and trailing newlines + $cmd =~ s{^\n+}{}; + $cmd =~ s{\n+$}{}; + + $cmd = $self->quote_literal($cmd); + $cmd = $self->escape_newlines($cmd); + + $switches = join ' ', @$switches; + + return qq{\$(PERLRUN) $switches -e $cmd}; +} + + +=item quote_literal + +=cut + +sub quote_literal { + my($self, $text) = @_; + + # I think all we have to quote is single quotes and I think + # this is a safe way to do it. + $text =~ s{'}{'\\''}g; + + return "'$text'"; +} + + +=item escape_newlines + +=cut + +sub escape_newlines { + my($self, $text) = @_; + + $text =~ s{\n}{\\\n}g; + + return $text; +} + + +=item max_exec_len + +Using POSIX::ARG_MAX. Otherwise falling back to 4096. + +=cut + +sub max_exec_len { + my $self = shift; + + if (!defined $self->{_MAX_EXEC_LEN}) { + if (my $arg_max = eval { require POSIX; &POSIX::ARG_MAX }) { + $self->{_MAX_EXEC_LEN} = $arg_max; + } + else { # POSIX minimum exec size + $self->{_MAX_EXEC_LEN} = 4096; + } + } + + return $self->{_MAX_EXEC_LEN}; +} + + =item static (o) Defines the static target. @@ -3413,9 +3611,8 @@ sub static { ' ## $(INST_PM) has been moved to the all: target. ## It remains here for awhile to allow for old usage: "make static" -#static :: '.$self->{MAKEFILE}.' $(INST_STATIC) $(INST_PM) -static :: '.$self->{MAKEFILE}.' $(INST_STATIC) - '.$self->{NOECHO}.'$(NOOP) +static :: $(FIRST_MAKEFILE) $(INST_STATIC) + $(NOECHO) $(NOOP) '; } @@ -3427,19 +3624,20 @@ Defines how to produce the *.a (or equivalent) files. sub static_lib { my($self) = @_; -# Come to think of it, if there are subdirs with linkcode, we still have no INST_STATIC -# return '' unless $self->needs_linking(); #might be because of a subdir - return '' unless $self->has_link_code; my(@m); push(@m, <<'END'); -$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)/.exists + +$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(RM_RF) $@ END + # If this extension has its own library (eg SDBM_File) # then copy that to $(INST_STATIC) and add $(OBJECT) into it. - push(@m, "\t$self->{CP} \$(MYEXTLIB) \$\@\n") if $self->{MYEXTLIB}; + push(@m, <<'MAKE_FRAG') if $self->{MYEXTLIB}; + $(CP) $(MYEXTLIB) $@ +MAKE_FRAG my $ar; if (exists $self->{FULL_AR} && -x $self->{FULL_AR}) { @@ -3449,20 +3647,19 @@ END } else { $ar = 'AR'; } - push @m, - "\t\$($ar) ".'$(AR_STATIC_ARGS) $@ $(OBJECT) && $(RANLIB) $@'."\n"; - push @m, -q{ $(CHMOD) $(PERM_RWX) $@ - }.$self->{NOECHO}.q{echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)/extralibs.ld -}; + push @m, sprintf <<'MAKE_FRAG', $ar; + $(%s) $(AR_STATIC_ARGS) $@ $(OBJECT) && $(RANLIB) $@ + $(CHMOD) $(PERM_RWX) $@ + $(NOECHO) $(ECHO) "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)/extralibs.ld +MAKE_FRAG + # Old mechanism - still available: - push @m, -"\t$self->{NOECHO}".q{echo "$(EXTRALIBS)" >> $(PERL_SRC)/ext.libs -} if $self->{PERL_SRC} && $self->{EXTRALIBS}; - push @m, "\n"; + push @m, <<'MAKE_FRAG' if $self->{PERL_SRC} && $self->{EXTRALIBS}; + $(NOECHO) $(ECHO) "$(EXTRALIBS)" >> $(PERL_SRC)/ext.libs +MAKE_FRAG - push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); - join('', "\n",@m); + push @m, "\n", $self->dir_target('$(INST_ARCHAUTODIR)'); + join('', @m); } =item staticmake (o) @@ -3480,7 +3677,7 @@ sub staticmake { # And as it's not yet built, we add the current extension # but only if it has some C code (or XS code, which implies C code) if (@{$self->{C}}) { - @static = File::Spec->catfile($self->{INST_ARCHLIB}, + @static = $self->catfile($self->{INST_ARCHLIB}, "auto", $self->{FULLEXT}, "$self->{BASEEXT}$self->{LIB_EXT}" @@ -3515,34 +3712,11 @@ Helper subroutine for subdirs sub subdir_x { my($self, $subdir) = @_; - my(@m); - if ($Is_Win32 && Win32::IsWin95()) { - if ($Config{'make'} =~ /dmake/i) { - # dmake-specific - return <{NOECHO}cd $subdir && \$(MAKE) -f \$(FIRST_MAKEFILE) all \$(PASTHRU) + $(NOECHO)cd %s && $(MAKE) -f $(FIRST_MAKEFILE) all $(PASTHRU) EOT - } } =item subdirs (o) @@ -3602,14 +3776,14 @@ testdb :: testdb_\$(LINKTYPE) test :: \$(TEST_TYPE) "); - if ($Is_Win32 && Win32::IsWin95()) { - push(@m, map(qq{\t$self->{NOECHO}\$(PERLRUN) -e "exit unless -f shift; chdir '$_'; system q{\$(MAKE) test \$(PASTHRU)}" $self->{MAKEFILE}\n}, @{$self->{DIR}})); + if ($Is_Win95) { + push(@m, map(qq{\t\$(NOECHO) \$(PERLRUN) -e "exit unless -f shift; chdir '$_'; system q{\$(MAKE) test \$(PASTHRU)}" \$(FIRST_MAKEFILE)\n}, @{$self->{DIR}})); } else { - push(@m, map("\t$self->{NOECHO}cd $_ && \$(TEST_F) $self->{MAKEFILE} && \$(MAKE) test \$(PASTHRU)\n", @{$self->{DIR}})); + push(@m, map("\t\$(NOECHO) cd $_ && \$(TEST_F) \$(FIRST_MAKEFILE) && \$(MAKE) test \$(PASTHRU)\n", @{$self->{DIR}})); } - push(@m, "\t$self->{NOECHO}echo 'No tests defined for \$(NAME) extension.'\n") + push(@m, "\t\$(NOECHO) $(ECHO) 'No tests defined for \$(NAME) extension.'\n") unless $tests or -f "test.pl" or @{$self->{DIR}}; push(@m, "\n"); @@ -3666,87 +3840,37 @@ sub test_via_script { return $self->SUPER::test_via_script("PERL_DL_NONLAZY=1 $perl", $script); } -=item tool_autosplit (o) - -Defines a simple perl call that runs autosplit. May be deprecated by -pm_to_blib soon. - -=cut - -sub tool_autosplit { - my($self, %attribs) = @_; - my($asl) = ""; - $asl = "\$\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN}; - return sprintf <<'MAKE_FRAG', $asl; -# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto -AUTOSPLITFILE = $(PERLRUN) -e 'use AutoSplit; %s autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1) ;' +=item tools_other (o) -MAKE_FRAG + my $make_frag = $MM->tools_other; -} +Returns a make fragment containing definitions for: -=item tools_other (o) +SHELL, CHMOD, CP, MV, NOOP, NOECHO, RM_F, RM_RF, TEST_F, TOUCH, +DEV_NULL, UMASK_NULL, MKPATH, EQUALIZE_TIMESTAMP, +WARN_IF_OLD_PACKLIST, UNINST, VERBINST, MOD_INSTALL, DOC_INSTALL and +UNINSTALL -Defines SHELL, LD, TOUCH, CP, MV, RM_F, RM_RF, CHMOD, UMASK_NULL in -the Makefile. Also defines the perl programs MKPATH, -WARN_IF_OLD_PACKLIST, MOD_INSTALL. DOC_INSTALL, and UNINSTALL. +init_others() initializes all these values. =cut sub tools_other { my($self) = shift; my @m; - my $bin_sh = $Config{sh} || '/bin/sh'; - push @m, qq{ -SHELL = $bin_sh -}; - for (qw/ CHMOD CP LD MV NOOP RM_F RM_RF TEST_F TOUCH UMASK_NULL DEV_NULL/ ) { - push @m, "$_ = $self->{$_}\n"; + for my $tool (qw{ SHELL CHMOD CP MV NOOP NOECHO RM_F RM_RF TEST_F TOUCH + UMASK_NULL DEV_NULL MKPATH EQUALIZE_TIMESTAMP ECHO + UNINST VERBINST + MOD_INSTALL DOC_INSTALL UNINSTALL + WARN_IF_OLD_PACKLIST + } ) + { + next unless defined $self->{$tool}; + push @m, "$tool = $self->{$tool}\n"; } - push @m, q{ -# The following is a portable way to say mkdir -p -# To see which directories are created, change the if 0 to if 1 -MKPATH = $(PERLRUN) "-MExtUtils::Command" -e mkpath - -# This helps us to minimize the effect of the .exists files A yet -# better solution would be to have a stable file in the perl -# distribution with a timestamp of zero. But this solution doesn't -# need any changes to the core distribution and works with older perls -EQUALIZE_TIMESTAMP = $(PERLRUN) "-MExtUtils::Command" -e eqtime -}; - - - return join "", @m if $self->{PARENT}; - - push @m, q{ -# Here we warn users that an old packlist file was found somewhere, -# and that they should call some uninstall routine -WARN_IF_OLD_PACKLIST = $(PERL) -we 'exit unless -f $$ARGV[0];' \\ --e 'print "WARNING: I have found an old package in\n";' \\ --e 'print "\t$$ARGV[0].\n";' \\ --e 'print "Please make sure the two installations are not conflicting\n";' - -UNINST=0 -VERBINST=0 - -MOD_INSTALL = $(PERL) "-I$(INST_LIB)" "-I$(PERL_LIB)" "-MExtUtils::Install" \ --e "install({@ARGV},'$(VERBINST)',0,'$(UNINST)');" - -DOC_INSTALL = $(PERL) -e '$$\="\n\n";' \ --e 'print "=head2 ", scalar(localtime), ": C<", shift, ">", " L<", $$arg=shift, "|", $$arg, ">";' \ --e 'print "=over 4";' \ --e 'while (defined($$key = shift) and defined($$val = shift)){print "=item *";print "C<$$key: $$val>";}' \ --e 'print "=back";' - -UNINSTALL = $(PERLRUN) "-MExtUtils::Install" \ --e 'uninstall($$ARGV[0],1,1); print "\nUninstall is deprecated. Please check the";' \ --e 'print " packlist above carefully.\n There may be errors. Remove the";' \ --e 'print " appropriate files manually.\n Sorry for the inconveniences.\n"' -}; - return join "", @m; } @@ -3759,8 +3883,16 @@ Determines typemaps, xsubpp version, prototype behaviour. sub tool_xsubpp { my($self) = shift; return "" unless $self->needs_linking; - my($xsdir) = File::Spec->catdir($self->{PERL_LIB},"ExtUtils"); - my(@tmdeps) = File::Spec->catdir('$(XSUBPPDIR)','typemap'); + + my $xsdir; + foreach my $dir (@INC) { + $xsdir = $self->catdir($dir, 'ExtUtils'); + if( -r $self->catfile($xsdir, "xsubpp") ) { + last; + } + } + + my(@tmdeps) = $self->catdir('$(XSUBPPDIR)','typemap'); if( $self->{TYPEMAPS} ){ my $typemap; foreach $typemap (@{$self->{TYPEMAPS}}){ @@ -3779,7 +3911,7 @@ sub tool_xsubpp { } - my $xsubpp_version = $self->xsubpp_version(File::Spec->catfile($xsdir,"xsubpp")); + my $xsubpp_version = $self->xsubpp_version($self->catfile($xsdir,"xsubpp")); # What are the correct thresholds for version 1 && 2 Paul? if ( $xsubpp_version > 1.923 ){ @@ -3862,6 +3994,22 @@ EOM return $Xsubpp_Version = "1.0" ; } + +=item all_target + +Build man pages, too + +=cut + +sub all_target { + my $self = shift; + + return <<'MAKE_EXT'; +all :: pure_all manifypods + $(NOECHO) $(NOOP) +MAKE_EXT +} + =item top_targets (o) Defines the targets all, subdirs, config, and O_FILES @@ -3874,43 +4022,39 @@ sub top_targets { my($self) = shift; my(@m); - push @m, ' -all :: pure_all manifypods - '.$self->{NOECHO}.'$(NOOP) -' - unless $self->{SKIPHASH}{'all'}; + push @m, $self->all_target, "\n" unless $self->{SKIPHASH}{'all'}; push @m, ' pure_all :: config pm_to_blib subdirs linkext - '.$self->{NOECHO}.'$(NOOP) + $(NOECHO) $(NOOP) subdirs :: $(MYEXTLIB) - '.$self->{NOECHO}.'$(NOOP) + $(NOECHO) $(NOOP) -config :: '.$self->{MAKEFILE}.' $(INST_LIBDIR)/.exists - '.$self->{NOECHO}.'$(NOOP) +config :: $(FIRST_MAKEFILE) $(INST_LIBDIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) -config :: $(INST_ARCHAUTODIR)/.exists - '.$self->{NOECHO}.'$(NOOP) +config :: $(INST_ARCHAUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) -config :: $(INST_AUTODIR)/.exists - '.$self->{NOECHO}.'$(NOOP) +config :: $(INST_AUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) '; push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]); if (%{$self->{MAN1PODS}}) { - push @m, qq[ -config :: \$(INST_MAN1DIR)/.exists - $self->{NOECHO}\$(NOOP) + push @m, q[ +config :: $(INST_MAN1DIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) ]; push @m, $self->dir_target(qw[$(INST_MAN1DIR)]); } if (%{$self->{MAN3PODS}}) { - push @m, qq[ -config :: \$(INST_MAN3DIR)/.exists - $self->{NOECHO}\$(NOOP) + push @m, q[ +config :: $(INST_MAN3DIR)$(DIRFILESEP).exists + $(NOECHO) $(NOOP) ]; push @m, $self->dir_target(qw[$(INST_MAN3DIR)]); @@ -3990,47 +4134,6 @@ sub xs_o { # many makes are too dumb to use xs_c then c_o '; } -=item perl_archive - -This is internal method that returns path to libperl.a equivalent -to be linked to dynamic extensions. UNIX does not have one but other -OSs might have one. - -=cut - -sub perl_archive -{ - return ""; -} - -=item perl_archive_after - -This is an internal method that returns path to a library which -should be put on the linker command line I the external libraries -to be linked to dynamic extensions. This may be needed if the linker -is one-pass, and Perl includes some overrides for C RTL functions, -such as malloc(). - -=cut - -sub perl_archive_after -{ - return ""; -} - -=item export_list - -This is internal method that returns name of a file that is -passed to linker to define symbols to be exported. -UNIX does not have one but OS2 and Win32 do. - -=cut - -sub export_list -{ - return ""; -} - 1; diff --git a/lib/ExtUtils/MM_VMS.pm b/lib/ExtUtils/MM_VMS.pm index 3fedae8..cd68c5e 100644 --- a/lib/ExtUtils/MM_VMS.pm +++ b/lib/ExtUtils/MM_VMS.pm @@ -7,18 +7,25 @@ package ExtUtils::MM_VMS; use strict; -use Carp qw( &carp ); use Config; require Exporter; -use VMS::Filespec; + +BEGIN { + # so we can compile the thing on non-VMS platforms. + if( $^O eq 'VMS' ) { + require VMS::Filespec; + VMS::Filespec->import; + } +} + use File::Basename; -use File::Spec; use vars qw($Revision @ISA $VERSION); -($VERSION) = $Revision = '5.65'; +($VERSION) = '5.66'; +($Revision = substr(q$Revision: 1.82 $, 10)) =~ s/\s+$//; require ExtUtils::MM_Any; require ExtUtils::MM_Unix; -@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix File::Spec ); +@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); use ExtUtils::MakeMaker qw($Verbose neatvalue); @@ -52,9 +59,8 @@ Converts a list into a string wrapped at approximately 80 columns. sub wraplist { my($self) = shift; my($line,$hlen) = ('',0); - my($word); - foreach $word (@_) { + foreach my $word (@_) { # Perl bug -- seems to occasionally insert extra elements when # traversing array (scalar(@array) doesn't show them, but # foreach(@array) does) (5.00307) @@ -160,8 +166,8 @@ sub find_perl { local *TCF; # Check in relative directories first, so we pick up the current # version of Perl if we're running MakeMaker as part of the main build. - @sdirs = sort { my($absa) = File::Spec->file_name_is_absolute($a); - my($absb) = File::Spec->file_name_is_absolute($b); + @sdirs = sort { my($absa) = $self->file_name_is_absolute($a); + my($absb) = $self->file_name_is_absolute($b); if ($absa && $absb) { return $a cmp $b } else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); } } @$dirs; @@ -187,7 +193,7 @@ sub find_perl { } foreach $dir (@sdirs){ next unless defined $dir; # $self->{PERL_SRC} may be undefined - $inabs++ if File::Spec->file_name_is_absolute($dir); + $inabs++ if $self->file_name_is_absolute($dir); if ($inabs == 1) { # We've covered relative dirs; everything else is an absolute # dir (probably an installed location). First, we'll try potential @@ -196,7 +202,7 @@ sub find_perl { $inabs++; # Should happen above in next $dir, but just in case . . . } foreach $name (@snames){ - if ($name !~ m![/:>\]]!) { push(@cand,File::Spec->catfile($dir,$name)); } + if ($name !~ m![/:>\]]!) { push(@cand,$self->catfile($dir,$name)); } else { push(@cand,$self->fixpath($name,0)); } } } @@ -211,9 +217,9 @@ sub find_perl { $rslt = `\@temp_mmvms.com` ; unlink('temp_mmvms.com'); if ($rslt =~ /VER_OK/) { - print "Using PERL=$name\n" if $trace; - return $name; - } + print "Using PERL=$name\n" if $trace; + return $name; + } } next unless $vmsfile = $self->maybe_command($name); $vmsfile =~ s/;[\d\-]*$//; # Clip off version number; we can use a newer version as well @@ -267,42 +273,6 @@ sub maybe_command { return 0; } -=item maybe_command_in_dirs (override) - -Uses DCL argument quoting on test command line. - -=cut - -sub maybe_command_in_dirs { # $ver is optional argument if looking for perl - my($self, $names, $dirs, $trace, $ver) = @_; - my($name, $dir); - foreach $dir (@$dirs){ - next unless defined $dir; # $self->{PERL_SRC} may be undefined - foreach $name (@$names){ - my($abs,$tryabs); - if (File::Spec->file_name_is_absolute($name)) { - $abs = $name; - } else { - $abs = File::Spec->catfile($dir, $name); - } - print "Checking $abs for $name\n" if ($trace >= 2); - next unless $tryabs = $self->maybe_command($abs); - print "Substituting $tryabs instead of $abs\n" - if ($trace >= 2 and $tryabs ne $abs); - $abs = $tryabs; - if (defined $ver) { - print "Executing $abs\n" if ($trace >= 2); - if (`$abs -e 'require $ver; print "VER_OK\n" ' 2>&1` =~ /VER_OK/) { - print "Using $abs\n" if $trace; - return $abs; - } - } else { # Do not look for perl - return $abs; - } - } - } -} - =item perl_script (override) If name passed in doesn't specify a readable file, appends F<.com> or @@ -332,10 +302,22 @@ sub replace_manpage_separator { $man; } +=item init_DIRFILESEP + +No seperator between a directory path and a filename on VMS. + +=cut + +sub init_DIRFILESEP { + my($self) = shift; + + $self->{DIRFILESEP} = ''; + return 1; +} + + =item init_main (override) -Override DISTVNAME so it uses VERSION_SYM to avoid getting too many -dots in the name. =cut @@ -343,7 +325,34 @@ sub init_main { my($self) = shift; $self->SUPER::init_main; - $self->{DISTVNAME} = "$self->{DISTNAME}-$self->{VERSION_SYM}"; + + $self->{DEFINE} ||= ''; + if ($self->{DEFINE} ne '') { + my(@terms) = split(/\s+/,$self->{DEFINE}); + my(@defs,@udefs); + foreach my $def (@terms) { + next unless $def; + my $targ = \@defs; + if ($def =~ s/^-([DU])//) { # If it was a Unix-style definition + $targ = \@udefs if $1 eq 'U'; + $def =~ s/='(.*)'$/=$1/; # then remove shell-protection '' + $def =~ s/^'(.*)'$/$1/; # from entire term or argument + } + if ($def =~ /=/) { + $def =~ s/"/""/g; # Protect existing " from DCL + $def = qq["$def"]; # and quote to prevent parsing of = + } + push @$targ, $def; + } + + $self->{DEFINE} = ''; + if (@defs) { + $self->{DEFINE} = '/Define=(' . join(',',@defs) . ')'; + } + if (@udefs) { + $self->{DEFINE} .= '/Undef=(' . join(',',@udefs) . ')'; + } + } } =item init_others (override) @@ -351,238 +360,203 @@ sub init_main { Provide VMS-specific forms of various utility commands, then hand off to the default MM_Unix method. +DEV_NULL should probably be overriden with something. + +Also changes EQUALIZE_TIMESTAMP to set revision date of target file to +one second later than source file, since MMK interprets precisely +equal revision dates for a source and target file as a sign that the +target needs to be updated. + =cut sub init_others { my($self) = @_; - $self->{NOOP} = 'Continue'; - $self->{FIRST_MAKEFILE} ||= 'Descrip.MMS'; - $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS'; - $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE}; - $self->{NOECHO} ||= '@ '; - $self->{RM_F} = '$(PERL) -e "foreach (@ARGV) { 1 while ( -d $_ ? rmdir $_ : unlink $_)}"'; - $self->{RM_RF} = '$(PERLRUN) -e "use File::Path; @dirs = map(VMS::Filespec::unixify($_),@ARGV); rmtree(\@dirs,0,0)"'; - $self->{TOUCH} = '$(PERL) -e "$t=time; foreach (@ARGV) { -e $_ ? utime($t,$t,@ARGV) : (open(F,qq(>$_)),close F)}"'; - $self->{CHMOD} = '$(PERL) -e "chmod @ARGV"'; # expect Unix syntax from MakeMaker + $self->{NOOP} = 'Continue'; + $self->{NOECHO} ||= '@ '; + + $self->{MAKEFILE} ||= 'Descrip.MMS'; + $self->{FIRST_MAKEFILE} ||= $self->{MAKEFILE}; + $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS'; + $self->{MAKEFILE_OLD} ||= '$(FIRST_MAKEFILE)_old'; + + $self->{ECHO} ||= '$(PERLRUN) -le "print qq{@ARGV}"'; + $self->{TOUCH} ||= '$(PERLRUN) "-MExtUtils::Command" -e touch'; + $self->{CHMOD} ||= '$(PERLRUN) "-MExtUtils::Command" -e chmod'; + $self->{RM_F} ||= '$(PERLRUN) "-MExtUtils::Command" -e rm_f'; + $self->{RM_RF} ||= '$(PERLRUN) "-MExtUtils::Command" -e rm_rf'; + $self->{TEST_F} ||= '$(PERLRUN) "-MExtUtils::Command" -e test_f'; + $self->{EQUALIZE_TIMESTAMP} ||= '$(PERLRUN) -we "open F,qq{>>$ARGV[1]};close F;utime(0,(stat($ARGV[0]))[9]+1,$ARGV[1])"'; + + $self->{MOD_INSTALL} ||= + $self->oneliner(<<'CODE', ['-MExtUtils::Install']); +install({split(' ',)}, '$(VERBINST)', 0, '$(UNINST)'); +CODE + + $self->{SHELL} ||= 'Posix'; + $self->{CP} = 'Copy/NoConfirm'; $self->{MV} = 'Rename/NoConfirm'; $self->{UMASK_NULL} = '! '; - + $self->SUPER::init_others; + + if ($self->{OBJECT} =~ /\s/) { + $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g; + $self->{OBJECT} = $self->wraplist( + map $self->fixpath($_,0), split /,?\s+/, $self->{OBJECT} + ); + } + + $self->{LDFROM} = $self->wraplist( + map $self->fixpath($_,0), split /,?\s+/, $self->{LDFROM} + ); +} + + +=item init_platform (override) + +Add PERL_VMS, MM_VMS_REVISION and MM_VMS_VERSION. + +MM_VMS_REVISION is for backwards compatibility before MM_VMS had a +$VERSION. + +=cut + +sub init_platform { + my($self) = shift; + + $self->{MM_VMS_REVISION} = $Revision; + $self->{MM_VMS_VERSION} = $VERSION; + $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC}, 'VMS') + if $self->{PERL_SRC}; } + +=item platform_constants + +=cut + +sub platform_constants { + my($self) = shift; + my $make_frag = ''; + + foreach my $macro (qw(PERL_VMS MM_VMS_REVISION MM_VMS_VERSION)) + { + next unless defined $self->{$macro}; + $make_frag .= "$macro = $self->{$macro}\n"; + } + + return $make_frag; +} + + +=item init_VERSION (override) + +Override the *DEFINE_VERSION macros with VMS semantics. Translate the +MAKEMAKER filepath to VMS style. + +=cut + +sub init_VERSION { + my $self = shift; + + $self->SUPER::init_VERSION; + + $self->{DEFINE_VERSION} = '"$(VERSION_MACRO)=""$(VERSION)"""'; + $self->{XS_DEFINE_VERSION} = '"$(XS_VERSION_MACRO)=""$(XS_VERSION)"""'; + $self->{MAKEMAKER} = vmsify($INC{'ExtUtils/MakeMaker.pm'}); +} + + =item constants (override) Fixes up numerous file and directory macros to insure VMS syntax -regardless of input syntax. Also adds a few VMS-specific macros -and makes lists of files comma-separated. +regardless of input syntax. Also makes lists of files +comma-separated. =cut sub constants { my($self) = @_; - my(@m,$def,$macro); # Be kind about case for pollution for (@ARGV) { $_ = uc($_) if /POLLUTE/i; } - $self->{DEFINE} ||= ''; - if ($self->{DEFINE} ne '') { - my(@terms) = split(/\s+/,$self->{DEFINE}); - my(@defs,@udefs); - foreach $def (@terms) { - next unless $def; - my $targ = \@defs; - if ($def =~ s/^-([DU])//) { # If it was a Unix-style definition - if ($1 eq 'U') { $targ = \@udefs; } - $def =~ s/='(.*)'$/=$1/; # then remove shell-protection '' - $def =~ s/^'(.*)'$/$1/; # from entire term or argument - } - if ($def =~ /=/) { - $def =~ s/"/""/g; # Protect existing " from DCL - $def = qq["$def"]; # and quote to prevent parsing of = - } - push @$targ, $def; - } - $self->{DEFINE} = ''; - if (@defs) { - $self->{DEFINE} = '/Define=(' . join(',',@defs) . ')'; - } - if (@udefs) { - $self->{DEFINE} .= '/Undef=(' . join(',',@udefs) . ')'; - } - } - - if ($self->{OBJECT} =~ /\s/) { - $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g; - $self->{OBJECT} = $self->wraplist(map($self->fixpath($_,0),split(/,?\s+/,$self->{OBJECT}))); - } - $self->{LDFROM} = $self->wraplist(map($self->fixpath($_,0),split(/,?\s+/,$self->{LDFROM}))); - - - foreach $macro ( qw [ + # Cleanup paths for directories in MMS macros. + foreach my $macro ( qw [ INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB - INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH + INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN INSTALLSCRIPT INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR PERL_LIB PERL_ARCHLIB - PERL_INC PERL_SRC FULLEXT ] ) { - next unless defined $self->{$macro}; + PERL_INC PERL_SRC ] ) + { + next unless defined $self->{$macro}; next if $macro =~ /MAN/ && $self->{$macro} eq 'none'; - $self->{$macro} = $self->fixpath($self->{$macro},1); - } - $self->{PERL_VMS} = File::Spec->catdir($self->{PERL_SRC},q(VMS)) - if ($self->{PERL_SRC}); - - - - # Fix up file specs - foreach $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKE_APERL_FILE MYEXTLIB] ) { - next unless defined $self->{$macro}; - $self->{$macro} = $self->fixpath($self->{$macro},0); - } - - foreach $macro (qw/ - AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION VERSION_SYM - XS_VERSION - INST_BIN INST_LIB INST_ARCHLIB INST_SCRIPT - INSTALLDIRS - PREFIX SITEPREFIX VENDORPREFIX - INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB - INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH - INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN INSTALLSCRIPT - PERL_LIB PERL_ARCHLIB - SITELIBEXP SITEARCHEXP - LIBPERL_A MYEXTLIB - FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC PERL_VMS - PERL_INC PERL FULLPERL PERLRUN FULLPERLRUN PERLRUNINST - FULLPERLRUNINST ABSPERL ABSPERLRUN ABSPERLRUNINST - PERL_CORE NOECHO NOOP - / ) { - next unless defined $self->{$macro}; - push @m, "$macro = $self->{$macro}\n"; + $self->{$macro} = $self->fixpath($self->{$macro},1); } - - push @m, q[ -VERSION_MACRO = VERSION -DEFINE_VERSION = "$(VERSION_MACRO)=""$(VERSION)""" -XS_VERSION_MACRO = XS_VERSION -XS_DEFINE_VERSION = "$(XS_VERSION_MACRO)=""$(XS_VERSION)""" - -MAKEMAKER = ],File::Spec->catfile($self->{PERL_LIB},'ExtUtils','MakeMaker.pm'),qq[ -MM_VERSION = $ExtUtils::MakeMaker::VERSION -MM_REVISION = $ExtUtils::MakeMaker::Revision -MM_VMS_REVISION = $ExtUtils::MM_VMS::Revision - -# FULLEXT = Pathname for extension directory (eg DBD/Oracle). -# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. -# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) -# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. -]; - - for my $tmp (qw/ - FULLEXT VERSION_FROM OBJECT LDFROM - / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = ",$self->fixpath($self->{$tmp},0),"\n"; + # Cleanup paths for files in MMS macros. + foreach my $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKEFILE_OLD + MAKE_APERL_FILE MYEXTLIB] ) + { + next unless defined $self->{$macro}; + $self->{$macro} = $self->fixpath($self->{$macro},0); } - for my $tmp (qw/ - BASEEXT PARENT_NAME DLBASE INC DEFINE LINKTYPE + # Fixup files for MMS macros + # XXX is this list complete? + for my $macro (qw/ + FULLEXT VERSION_FROM OBJECT LDFROM / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; + next unless defined $self->{$macro}; + $self->{$macro} = $self->fixpath($self->{$macro},0); } - for my $tmp (qw/ XS MAN1PODS MAN3PODS PM /) { - # Where is the space coming from? --jhi - next unless $self ne " " && defined $self->{$tmp}; - my(%tmp,$key); - for $key (keys %{$self->{$tmp}}) { - $tmp{$self->fixpath($key,0)} = $self->fixpath($self->{$tmp}{$key},0); - } - $self->{$tmp} = \%tmp; - } - for my $tmp (qw/ C O_FILES H /) { - next unless defined $self->{$tmp}; - my(@tmp,$val); - for $val (@{$self->{$tmp}}) { - push(@tmp,$self->fixpath($val,0)); - } - $self->{$tmp} = \@tmp; + for my $macro (qw/ XS MAN1PODS MAN3PODS PM /) { + # Where is the space coming from? --jhi + next unless $self ne " " && defined $self->{$macro}; + my %tmp = (); + for my $key (keys %{$self->{$macro}}) { + $tmp{$self->fixpath($key,0)} = + $self->fixpath($self->{$macro}{$key},0); + } + $self->{$macro} = \%tmp; } - push @m,' - -# Handy lists of source code files: -XS_FILES = ',$self->wraplist(sort keys %{$self->{XS}}),' -C_FILES = ',$self->wraplist(@{$self->{C}}),' -O_FILES = ',$self->wraplist(@{$self->{O_FILES}} ),' -H_FILES = ',$self->wraplist(@{$self->{H}}),' -MAN1PODS = ',$self->wraplist(sort keys %{$self->{MAN1PODS}}),' -MAN3PODS = ',$self->wraplist(sort keys %{$self->{MAN3PODS}}),' - -'; - - for my $tmp (qw/ - INST_MAN1DIR MAN1EXT - INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR - INST_MAN3DIR MAN3EXT - INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR - /) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; + for my $macro (qw/ C O_FILES H /) { + next unless defined $self->{$macro}; + my @tmp = (); + for my $val (@{$self->{$macro}}) { + push(@tmp,$self->fixpath($val,0)); + } + $self->{$macro} = \@tmp; } -push @m," -makemakerdflt : all - \$(NOECHO) \$(NOOP) + return $self->SUPER::constants; +} -.SUFFIXES : -.SUFFIXES : \$(OBJ_EXT) .c .cpp .cxx .xs -# Here is the Config.pm that we are using/depend on -CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM) +=item special_targets -# Where to put things: -INST_LIBDIR = $self->{INST_LIBDIR} -INST_ARCHLIBDIR = $self->{INST_ARCHLIBDIR} +Clear the default .SUFFIXES and put in our own list. -INST_AUTODIR = $self->{INST_AUTODIR} -INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR} -"; +=cut - if ($self->has_link_code()) { - push @m,' -INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT)$(LIB_EXT) -INST_DYNAMIC = $(INST_ARCHAUTODIR)$(DLBASE).$(DLEXT) -INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs -'; - } else { - my $shr = $Config{'dbgprefix'} . 'PERLSHR'; - push @m,' -INST_STATIC = -INST_DYNAMIC = -INST_BOOT = -EXPORT_LIST = $(BASEEXT).opt -PERL_ARCHIVE = ',($ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}"),' -'; - } +sub special_targets { + my $self = shift; - $self->{TO_INST_PM} = [ sort keys %{$self->{PM}} ]; - $self->{PM_TO_BLIB} = [ %{$self->{PM}} ]; - push @m,' -TO_INST_PM = ',$self->wraplist(@{$self->{TO_INST_PM}}),' + my $make_frag .= <<'MAKE_FRAG'; +.SUFFIXES : +.SUFFIXES : $(OBJ_EXT) .c .cpp .cxx .xs -PM_TO_BLIB = ',$self->wraplist(@{$self->{PM_TO_BLIB}}),' -'; +MAKE_FRAG - join('',@m); + return $make_frag; } =item cflags (override) @@ -723,78 +697,6 @@ sub const_cccmd { $self->{CONST_CCCMD} = join('',@m); } -=item pm_to_blib (override) - -DCL I accepts a maximum of 255 characters on a command -line, so we write the (potentially) long list of file names -to a temp file, then persuade Perl to read it instead of the -command line to find args. - -=cut - -sub pm_to_blib { - my($self) = @_; - my($autodir) = File::Spec->catdir($self->{INST_LIB},'auto'); - my(%files) = @{$self->{PM_TO_BLIB}}; - - my $m = <<'MAKE_FRAG'; - -# Dummy target to match Unix target name; we use pm_to_blib.ts as -# timestamp file to avoid repeated invocations under VMS -pm_to_blib : pm_to_blib.ts - $(NOECHO) $(NOOP) - -# As always, keep under DCL's 255-char limit -pm_to_blib.ts : $(TO_INST_PM) -MAKE_FRAG - - if( keys %files ) { - $m .= <<'MAKE_FRAG'; - $(NOECHO) $(RM_F) .MM_tmp -MAKE_FRAG - - my $line = ''; - while (my($from, $to) = each %files) { - $line .= " $from $to"; - if (length($line) > 128) { - $m .= sprintf <<'MAKE_FRAG', $line; - $(NOECHO) $(PERL) -e "print '%s'" >>.MM_tmp -MAKE_FRAG - $line = ''; - } - } - $m .= sprintf <<'MAKE_FRAG', $line if $line; - $(NOECHO) $(PERL) -e "print '%s'" >>.MM_tmp -MAKE_FRAG - - $m .= sprintf <<'MAKE_FRAG', $autodir; - $(PERLRUN) "-MExtUtils::Install" -e "pm_to_blib({split(' ',)},'%s','$(PM_FILTER)')" <.MM_tmp - $(NOECHO) $(RM_F) .MM_tmp -MAKE_FRAG - - } - $m .= <<'MAKE_FRAG'; - $(NOECHO) $(TOUCH) pm_to_blib.ts -MAKE_FRAG - - return $m; -} - -=item tool_autosplit (override) - -Use VMS-style quoting on command line. - -=cut - -sub tool_autosplit { - my($self, %attribs) = @_; - my($asl) = ""; - $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN}; - q{ -# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto -AUTOSPLITFILE = $(PERLRUN) -e "use AutoSplit;}.$asl.q{autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;" -}; -} =item tool_sxubpp (override) @@ -805,9 +707,10 @@ Use VMS-style quoting on xsubpp command line. sub tool_xsubpp { my($self) = @_; return '' unless $self->needs_linking; - my($xsdir) = File::Spec->catdir($self->{PERL_LIB},'ExtUtils'); + my($xsdir) = $self->catdir($self->{PERL_LIB},'ExtUtils'); # drop back to old location if xsubpp is not in new location yet - $xsdir = File::Spec->catdir($self->{PERL_SRC},'ext') unless (-f File::Spec->catfile($xsdir,'xsubpp')); + $xsdir = $self->catdir($self->{PERL_SRC},'ext') + unless (-f $self->catfile($xsdir,'xsubpp')); my(@tmdeps) = '$(XSUBPPDIR)typemap'; if( $self->{TYPEMAPS} ){ my $typemap; @@ -831,7 +734,7 @@ sub tool_xsubpp { (!exists($self->{XSOPT}) || $self->{XSOPT} !~ /linenumbers/)) { unshift(@tmargs,'-nolinenumbers'); } - my $xsubpp_version = $self->xsubpp_version(File::Spec->catfile($xsdir,'xsubpp')); + my $xsubpp_version = $self->xsubpp_version($self->catfile($xsdir,'xsubpp')); # What are the correct thresholds for version 1 && 2 Paul? if ( $xsubpp_version > 1.923 ){ @@ -877,7 +780,7 @@ sub xsubpp_version print "Running: $command\n" if $Verbose; $version = `$command` ; if ($?) { - use vmsish 'status'; + use ExtUtils::MakeMaker::vmsish 'status'; warn "Running '$command' exits with status $?"; } chop $version ; @@ -907,7 +810,7 @@ EOM print "Running: $command\n" if $Verbose; my $text = `$command` ; if ($?) { - use vmsish 'status'; + use ExtUtils::MakeMaker::vmsish 'status'; warn "Running '$command' exits with status $?"; } unlink $file ; @@ -924,68 +827,68 @@ EOM =item tools_other (override) -Adds a few MM[SK] macros, and shortens some the installatin commands, -in order to stay under DCL's 255-character limit. Also changes -EQUALIZE_TIMESTAMP to set revision date of target file to one second -later than source file, since MMK interprets precisely equal revision -dates for a source and target file as a sign that the target needs -to be updated. +Throw in some dubious extra macros for Makefile args. + +Also keep around the old $(SAY) macro in case somebody's using it. =cut sub tools_other { my($self) = @_; - qq! + + # XXX Are these necessary? Does anyone override them? They're longer + # than just typing the literal string. + my $extra_tools = <<'EXTRA_TOOLS'; + # Assumes \$(MMS) invokes MMS or MMK # (It is assumed in some cases later that the default makefile name # (Descrip.MMS for MM[SK]) is used.) USEMAKEFILE = /Descrip= USEMACROS = /Macro=( MACROEND = ) -MAKEFILE = Descrip.MMS -SHELL = Posix -TOUCH = $self->{TOUCH} -CHMOD = $self->{CHMOD} -CP = $self->{CP} -MV = $self->{MV} -RM_F = $self->{RM_F} -RM_RF = $self->{RM_RF} -SAY = Write Sys\$Output -UMASK_NULL = $self->{UMASK_NULL} -MKPATH = Create/Directory -EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])" -!. ($self->{PARENT} ? '' : -qq!WARN_IF_OLD_PACKLIST = \$(PERL) -e "if (-f \$ARGV[0]){print qq[WARNING: Old package found (\$ARGV[0]); please check for collisions\\n]}" -MOD_INSTALL = \$(PERLRUN) "-MExtUtils::Install" -e "install({split(' ',)},1);" -DOC_INSTALL = \$(PERL) -e "\@ARGV=split(/\\|/,);print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];while(\$key=shift && \$val=shift){print qq[=item *\\n\\nC<\$key: \$val>\\n\\n];}print qq[=back\\n\\n]" -UNINSTALL = \$(PERLRUN) "-MExtUtils::Install" -e "uninstall(\$ARGV[0],1,1);" -!); + +# Just in case anyone is using the old macro. +SAY = $ECHO + +EXTRA_TOOLS + + return $self->SUPER::tools_other . $extra_tools; } -=item dist (override) +=item init_dist (override) -Provide VMSish defaults for some values, then hand off to -default MM_Unix method. +VMSish defaults for some values. -=cut + macro description default -sub dist { - my($self, %attribs) = @_; - $attribs{VERSION} ||= $self->{VERSION_SYM}; - $attribs{NAME} ||= $self->{DISTNAME}; - $attribs{ZIPFLAGS} ||= '-Vu'; - $attribs{COMPRESS} ||= 'gzip'; - $attribs{SUFFIX} ||= '-gz'; - $attribs{SHAR} ||= 'vms_share'; - $attribs{DIST_DEFAULT} ||= 'zipdist'; + ZIPFLAGS flags to pass to ZIP -Vu - # Sanitize these for use in $(DISTVNAME) filespec - $attribs{VERSION} =~ s/[^\w\$]/_/g; - $attribs{NAME} =~ s/[^\w\$]/-/g; + COMPRESS compression command to gzip + use for tarfiles + SUFFIX suffix to put on -gz + compressed files - $attribs{DISTVNAME} ||= '$(DISTNAME)-$(VERSION_SYM)'; + SHAR shar command to use vms_share - return $self->SUPER::dist(%attribs); + DIST_DEFAULT default target to use to tardist + create a distribution + + DISTVNAME Use VERSION_SYM instead of $(DISTNAME)-$(VERSION_SYM) + VERSION for the name + +=cut + +sub init_dist { + my($self) = @_; + $self->{ZIPFLAGS} ||= '-Vu'; + $self->{COMPRESS} ||= 'gzip'; + $self->{SUFFIX} ||= '-gz'; + $self->{SHAR} ||= 'vms_share'; + $self->{DIST_DEFAULT} ||= 'zipdist'; + + $self->SUPER::init_dist; + + $self->{DISTVNAME} = "$self->{DISTNAME}-$self->{VERSION_SYM}"; } =item c_o (override) @@ -1042,62 +945,6 @@ sub xs_o { # many makes are too dumb to use xs_c then c_o '; } -=item top_targets (override) - -Path seperator differences. - -=cut - -sub top_targets { - my($self) = shift; - my(@m); - push @m, ' -all :: pure_all manifypods - $(NOECHO) $(NOOP) - -pure_all :: config pm_to_blib subdirs linkext - $(NOECHO) $(NOOP) - -subdirs :: $(MYEXTLIB) - $(NOECHO) $(NOOP) - -config :: $(MAKEFILE) $(INST_LIBDIR).exists - $(NOECHO) $(NOOP) - -config :: $(INST_ARCHAUTODIR).exists - $(NOECHO) $(NOOP) - -config :: $(INST_AUTODIR).exists - $(NOECHO) $(NOOP) -'; - - push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]); - if (%{$self->{MAN1PODS}}) { - push @m, q[ -config :: $(INST_MAN1DIR).exists - $(NOECHO) $(NOOP) -]; - push @m, $self->dir_target(qw[$(INST_MAN1DIR)]); - } - if (%{$self->{MAN3PODS}}) { - push @m, q[ -config :: $(INST_MAN3DIR).exists - $(NOECHO) $(NOOP) -]; - push @m, $self->dir_target(qw[$(INST_MAN3DIR)]); - } - - push @m, ' -$(O_FILES) : $(H_FILES) -' if @{$self->{O_FILES} || []} && @{$self->{H} || []}; - - push @m, q{ -help : - perldoc ExtUtils::MakeMaker -}; - - join('',@m); -} =item dlsyms (override) @@ -1204,7 +1051,7 @@ INST_DYNAMIC_DEP = $inst_dynamic_dep "; push @m, ' -$(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) +$(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) If F$TrnLNm("',$shr,'").eqs."" Then Define/NoLog/User ',"$shr Sys\$Share:$shr.$Config{'dlext'}",' Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,$(PERL_INC)perlshr_attr.opt/Option @@ -1231,13 +1078,13 @@ BOOTSTRAP = '."$self->{BASEEXT}.bs".' # As MakeMaker mkbootstrap might not write a file (if none is required) # we use touch to prevent make continually trying to remake it. # The DynaLoader only reads a non-empty file. -$(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists - $(NOECHO) $(SAY) "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))" +$(BOOTSTRAP) : $(FIRST_MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR)$(DIRFILESEP).exists + $(NOECHO) $(ECHO) "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))" $(NOECHO) $(PERLRUN) - -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');" $(NOECHO) $(TOUCH) $(MMS$TARGET) -$(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists +$(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(NOECHO) $(RM_RF) $(INST_BOOT) - $(CP) $(BOOTSTRAP) $(INST_BOOT) '; @@ -1261,7 +1108,7 @@ $(INST_STATIC) : my(@m,$lib); push @m,' # Rely on suffix rule for update action -$(OBJECT) : $(INST_ARCHAUTODIR).exists +$(OBJECT) : $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(INST_STATIC) : $(OBJECT) $(MYEXTLIB) '; @@ -1289,56 +1136,6 @@ $(INST_STATIC) : $(OBJECT) $(MYEXTLIB) } -=item manifypods (override) - -Use VMS-style quoting on command line, and VMS logical name -to specify fallback location at build time if we can't find pod2man. - -=cut - - -sub manifypods { - my($self, %attribs) = @_; - return "\nmanifypods :\n\t\$(NOECHO) \$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}}; - my($dist); - my($pod2man_exe); - if (defined $self->{PERL_SRC}) { - $pod2man_exe = File::Spec->catfile($self->{PERL_SRC},'pod','pod2man'); - } else { - $pod2man_exe = File::Spec->catfile($Config{scriptdirexp},'pod2man'); - } - if (not ($pod2man_exe = $self->perl_script($pod2man_exe))) { - # No pod2man but some MAN3PODS to be installed - print <new->parse_from_file($_,$m{$_}) }" -]; - push @m, "\nmanifypods : \$(MAN1PODS) \$(MAN3PODS)\n"; - if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) { - my($pod); - foreach $pod (sort keys %{$self->{MAN1PODS}}) { - push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ]; - push @m, "$pod $self->{MAN1PODS}{$pod}\n"; - } - foreach $pod (sort keys %{$self->{MAN3PODS}}) { - push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ]; - push @m, "$pod $self->{MAN3PODS}{$pod}\n"; - } - } - join('', @m); -} - =item processPL (override) Use VMS-style quoting on command line. @@ -1380,7 +1177,7 @@ sub installbin { my($self) = @_; return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY"; return '' unless @{$self->{EXE_FILES}}; - my(@m, $from, $to, %fromto, @to, $line); + my(@m, $from, $to, %fromto, @to); my(@exefiles) = map { vmsify($_) } @{$self->{EXE_FILES}}; for $from (@exefiles) { my($path) = '$(INST_SCRIPT)' . basename($from); @@ -1395,7 +1192,8 @@ EXE_FILES = @exefiles realclean :: "; - $line = ''; #avoid unitialized var warning + + my $line = ''; foreach $to (@to) { if (length($line) + length($to) > 80) { push @m, "\t\$(RM_F) $line\n"; @@ -1412,7 +1210,7 @@ realclean :: else { ($todir = $to) =~ s/[^\)]+$//; } $todir = $self->fixpath($todir,1); push @m, " -$to : $from \$(MAKEFILE) ${todir}.exists +$to : $from \$(FIRST_MAKEFILE) ${todir}\$(DIRFILESEP).exists \$(CP) $from $to ", $self->dir_target($todir); @@ -1455,13 +1253,8 @@ sub clean { push @m, ' # Delete temporary files but do not touch installed files. We don\'t delete # the Descrip.MMS here so that a later make realclean still has it to use. -clean :: +clean :: clean_subdirs '; - foreach $dir (@{$self->{DIR}}) { # clean subdirectories first - my($vmsdir) = $self->fixpath($dir,1); - push( @m, ' If F$Search("'.$vmsdir.'$(MAKEFILE)").nes."" Then \\',"\n\t", - '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS)$(MMSQUALIFIERS) clean`;"',"\n"); - } push @m, ' $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp '; @@ -1469,24 +1262,28 @@ clean :: # Unlink realclean, $attribs{FILES} is a string here; it may contain # a list or a macro that expands to a list. if ($attribs{FILES}) { - my($word,$key,@filist); - if (ref $attribs{FILES} eq 'ARRAY') { @filist = @{$attribs{FILES}}; } - else { @filist = split /\s+/, $attribs{FILES}; } - foreach $word (@filist) { - if (($key) = $word =~ m#^\$\((.*)\)$# and ref $self->{$key} eq 'ARRAY') { - push(@otherfiles, @{$self->{$key}}); + my @filelist = ref $attribs{FILES} eq 'ARRAY' + ? @{$attribs{FILES}} + : split /\s+/, $attribs{FILES}; + + foreach my $word (@filelist) { + if ($word =~ m#^\$\((.*)\)$# and + ref $self->{$1} eq 'ARRAY') + { + push(@otherfiles, @{$self->{$1}}); } else { push(@otherfiles, $word); } } } - push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld perlmain.c pm_to_blib.ts ]); - push(@otherfiles,File::Spec->catfile('$(INST_ARCHAUTODIR)','extralibs.all')); - my($file,$line); - $line = ''; #avoid unitialized var warning + push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld + perlmain.c pm_to_blib pm_to_blib.ts ]); + push(@otherfiles, $self->catfile('$(INST_ARCHAUTODIR)','extralibs.all')); + # Occasionally files are repeated several times from different sources - { my(%of) = map { ($_,1) } @otherfiles; @otherfiles = keys %of; } + { my(%of) = map { ($_ => 1) } @otherfiles; @otherfiles = keys %of; } - foreach $file (@otherfiles) { + my $line = ''; + foreach my $file (@otherfiles) { $file = $self->fixpath($file); if (length($line) + length($file) > 80) { push @m, "\t\$(RM_RF) $line\n"; @@ -1499,6 +1296,39 @@ clean :: join('', @m); } + +=item clean_subdirs_target + + my $make_frag = $MM->clean_subdirs_target; + +VMS semantics for changing directories and rerunning make very different. + +=cut + +sub clean_subdirs_target { + my($self) = shift; + + # No subdirectories, no cleaning. + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +clean_subdirs : + $(NOECHO) $(NOOP) +NOOP_FRAG + + + my $clean = "clean_subdirs :\n"; + + foreach my $dir (@{$self->{DIR}}) { # clean subdirectories first + $dir = $self->fixpath($dir,1); + + $clean .= sprintf <<'MAKE_FRAG', $dir, $dir; + If F$Search("%s$(FIRST_MAKEFILE)").nes."" Then $(PERLRUN) -e "chdir '%s'; print `$(MMS)$(MMSQUALIFIERS) clean`;" +MAKE_FRAG + } + + return $clean; +} + + =item realclean (override) Guess what we're working around? Also, use MM[SK] for subdirectories. @@ -1514,7 +1344,7 @@ realclean :: clean '); foreach(@{$self->{DIR}}){ my($vmsdir) = $self->fixpath($_,1); - push(@m, ' If F$Search("'."$vmsdir".'$(MAKEFILE)").nes."" Then \\',"\n\t", + push(@m, ' If F$Search("'."$vmsdir".'$(FIRST_MAKEFILE)").nes."" Then \\',"\n\t", '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS)$(MMSQUALIFIERS) realclean`;"',"\n"); } push @m, " \$(RM_RF) \$(INST_AUTODIR) \$(INST_ARCHAUTODIR)\n"; @@ -1523,15 +1353,16 @@ realclean :: clean # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a # combination of macros). In order to stay below DCL's 255 char limit, # we put only 2 on a line. - my($file,$line,$fcnt); - my(@files) = qw{ $(MAKEFILE) $(MAKEFILE)_old }; + my($file,$fcnt); + my(@files) = qw{ $(FIRST_MAKEFILE) $(MAKEFILE_OLD) }; if ($self->has_link_code) { push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) }); } - push(@files, values %{$self->{PM}}); - $line = ''; #avoid unitialized var warning + # Occasionally files are repeated several times from different sources { my(%f) = map { ($_,1) } @files; @files = keys %f; } + + my $line = ''; foreach $file (@files) { $file = $self->fixpath($file); if (length($line) + length($file) > 80 || ++$fcnt >= 2) { @@ -1569,32 +1400,32 @@ realclean :: clean join('', @m); } +=item zipfile_target (o) -=item dist_core (override) +=item tarfile_target (o) -Syntax for invoking F differs from that for Unix F, -so C target actions are VMS-specific. +=item shdist_target (o) -=cut - -sub dist_core { - my($self) = @_; -q[ -dist : $(DIST_DEFAULT) - $(NOECHO) $(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)')" +Syntax for invoking shar, tar and zip differs from that for Unix. -zipdist : $(DISTVNAME).zip - $(NOECHO) $(NOOP) +=cut -tardist : $(DISTVNAME).tar$(SUFFIX) - $(NOECHO) $(NOOP) +sub zipfile_target { + my($self) = shift; + return <<'MAKE_FRAG'; $(DISTVNAME).zip : distdir $(PREOP) $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) [.$(DISTVNAME)...]*.*; $(RM_RF) $(DISTVNAME) $(POSTOP) +MAKE_FRAG +} +sub tarfile_target { + my($self) = shift; + + return <<'MAKE_FRAG'; $(DISTVNAME).tar$(SUFFIX) : distdir $(PREOP) $(TO_UNIX) @@ -1602,13 +1433,19 @@ $(DISTVNAME).tar$(SUFFIX) : distdir $(RM_RF) $(DISTVNAME) $(COMPRESS) $(DISTVNAME).tar $(POSTOP) +MAKE_FRAG +} + +sub shdist_target { + my($self) = shift; + return <<'MAKE_FRAG'; shdist : distdir $(PREOP) - $(SHAR) [.$(DISTVNAME...]*.*; $(DISTVNAME).share + $(SHAR) [.$(DISTVNAME)...]*.*; $(DISTVNAME).share $(RM_RF) $(DISTVNAME) $(POSTOP) -]; +MAKE_FRAG } =item dist_test (override) @@ -1642,18 +1479,18 @@ VMS-style command line quoting in a few cases. sub install { my($self, %attribs) = @_; - my(@m,@docfiles); + my(@m,@exe_files); if ($self->{EXE_FILES}) { my($line,$file) = ('',''); foreach $file (@{$self->{EXE_FILES}}) { $line .= "$file "; if (length($line) > 128) { - push(@docfiles,qq[\t\$(NOECHO) \$(PERL) -e "print '$line'" >>.MM_tmp\n]); + push(@exe_files,qq[\t\$(NOECHO) \$(ECHO) "$line" >>.MM_tmp\n]); $line = ''; } } - push(@docfiles,qq[\t\$(NOECHO) \$(PERL) -e "print '$line'" >>.MM_tmp\n]) if $line; + push(@exe_files,qq[\t\$(NOECHO) \$(ECHO) "$line" >>.MM_tmp\n]) if $line; } push @m, q[ @@ -1670,77 +1507,82 @@ pure_install :: pure_$(INSTALLDIRS)_install $(NOECHO) $(NOOP) doc_install :: doc_$(INSTALLDIRS)_install - $(NOECHO) $(SAY) "Appending installation info to $(INSTALLARCHLIB)perllocal.pod" + $(NOECHO) $(NOOP) pure__install : pure_site_install - $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" + $(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" doc__install : doc_site_install - $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" + $(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" # This hack brought to you by DCL's 255-character command line limit pure_perl_install :: $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read '.File::Spec->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').' '" >.MM_tmp $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write '.File::Spec->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').' '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp - $(MOD_INSTALL) <.MM_tmp - $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; - $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].File::Spec->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[ + $(NOECHO) $(ECHO) "$(INST_LIB) $(INSTALLPRIVLIB) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_ARCHLIB) $(INSTALLARCHLIB) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_BIN) $(INSTALLBIN) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_SCRIPT) $(INSTALLSCRIPT) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_MAN1DIR) $(INSTALLMAN1DIR) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_MAN3DIR) $(INSTALLMAN3DIR) " >>.MM_tmp + $(NOECHO) $(MOD_INSTALL) <.MM_tmp + $(NOECHO) $(RM_F) .MM_tmp + $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[ # Likewise pure_site_install :: $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read '.File::Spec->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').' '" >.MM_tmp $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write '.File::Spec->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').' '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLSITEBIN) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLSITEMAN1DIR) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLSITEMAN3DIR) '" >>.MM_tmp - $(MOD_INSTALL) <.MM_tmp - $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; - $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].File::Spec->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[ + $(NOECHO) $(ECHO) "$(INST_LIB) $(INSTALLSITELIB) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_ARCHLIB) $(INSTALLSITEARCH) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_BIN) $(INSTALLSITEBIN) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_SCRIPT) $(INSTALLSCRIPT) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_MAN1DIR) $(INSTALLSITEMAN1DIR) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_MAN3DIR) $(INSTALLSITEMAN3DIR) " >>.MM_tmp + $(NOECHO) $(MOD_INSTALL) <.MM_tmp + $(NOECHO) $(RM_F) .MM_tmp + $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[ pure_vendor_install :: - $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLVENDORLIB) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLVENDORARCH) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLVENDORBIN) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLVENDORMAN1DIR) '" >>.MM_tmp - $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLVENDORMAN3DIR) '" >>.MM_tmp - $(MOD_INSTALL) <.MM_tmp - $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; + $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read '.File::Spec->catfile('$(VENDORARCHEXP)','auto','$(FULLEXT)','.packlist').' '" >.MM_tmp + $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write '.File::Spec->catfile('$(INSTALLVENDORARCH)','auto','$(FULLEXT)','.packlist').' '" >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_LIB) $(INSTALLVENDORLIB) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_ARCHLIB) $(INSTALLVENDORARCH) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_BIN) $(INSTALLVENDORBIN) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_SCRIPT) $(INSTALLSCRIPT) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_MAN1DIR) $(INSTALLVENDORMAN1DIR) " >>.MM_tmp + $(NOECHO) $(ECHO) "$(INST_MAN3DIR) $(INSTALLVENDORMAN3DIR) " >>.MM_tmp + $(NOECHO) $(MOD_INSTALL) <.MM_tmp + $(NOECHO) $(RM_F) .MM_tmp # Ditto doc_perl_install :: - $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp - $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES)|'" >>.MM_tmp -],@docfiles, -q% $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,);]" >.MM2_tmp - $(NOECHO) $(PERL) -e "print q[print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp - $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp - $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp - $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.File::Spec->catfile($self->{INSTALLARCHLIB},'perllocal.pod').q[ - $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp; + $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{INSTALLARCHLIB}, 'perllocal.pod').q[" + $(NOECHO) $(MKPATH) $(INSTALLARCHLIB) + $(NOECHO) $(ECHO) "installed into|$(INSTALLPRIVLIB)|" >.MM_tmp + $(NOECHO) $(ECHO) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp +],@exe_files, +q[ $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{INSTALLARCHLIB},'perllocal.pod').q[ + $(NOECHO) $(RM_F) .MM_tmp # And again doc_site_install :: - $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp - $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES)|'" >>.MM_tmp -],@docfiles, -q% $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,);]" >.MM2_tmp - $(NOECHO) $(PERL) -e "print q[print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp - $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp - $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp - $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.File::Spec->catfile($self->{INSTALLARCHLIB},'perllocal.pod').q[ - $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp; + $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{INSTALLSITEARCH}, 'perllocal.pod').q[" + $(NOECHO) $(MKPATH) $(INSTALLSITEARCH) + $(NOECHO) $(ECHO) "installed into|$(INSTALLSITELIB)|" >.MM_tmp + $(NOECHO) $(ECHO) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp +],@exe_files, +q[ $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{INSTALLSITEARCH},'perllocal.pod').q[ + $(NOECHO) $(RM_F) .MM_tmp doc_vendor_install :: + $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{INSTALLVENDORARCH}, 'perllocal.pod').q[" + $(NOECHO) $(MKPATH) $(INSTALLVENDORARCH) + $(NOECHO) $(ECHO) "installed into|$(INSTALLVENDORLIB)|" >.MM_tmp + $(NOECHO) $(ECHO) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp +],@exe_files, +q[ $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{INSTALLVENDORARCH},'perllocal.pod').q[ + $(NOECHO) $(RM_F) .MM_tmp ]; @@ -1749,16 +1591,16 @@ uninstall :: uninstall_from_$(INSTALLDIRS)dirs $(NOECHO) $(NOOP) uninstall_from_perldirs :: - $(NOECHO) $(UNINSTALL) ].File::Spec->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[ - $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes." - $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove" - $(NOECHO) $(SAY) "the appropriate files. Sorry for the inconvenience." + $(NOECHO) $(UNINSTALL) ].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[ + $(NOECHO) $(ECHO) "Uninstall is now deprecated and makes no actual changes." + $(NOECHO) $(ECHO) "Please check the list above carefully for errors, and manually remove" + $(NOECHO) $(ECHO) "the appropriate files. Sorry for the inconvenience." uninstall_from_sitedirs :: - $(NOECHO) $(UNINSTALL) ],File::Spec->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist'),"\n",q[ - $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes." - $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove" - $(NOECHO) $(SAY) "the appropriate files. Sorry for the inconvenience." + $(NOECHO) $(UNINSTALL) ],$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist'),"\n",q[ + $(NOECHO) $(ECHO) "Uninstall is now deprecated and makes no actual changes." + $(NOECHO) $(ECHO) "Please check the list above carefully for errors, and manually remove" + $(NOECHO) $(ECHO) "the appropriate files. Sorry for the inconvenience." ]; join('',@m); @@ -1797,7 +1639,7 @@ $(OBJECT) : $(PERL_INC)util.h, $(PERL_INC)vmsish.h, $(PERL_INC)warnings.h if ($self->{PERL_SRC}) { my(@macros); - my($mmsquals) = '$(USEMAKEFILE)[.vms]$(MAKEFILE)'; + my($mmsquals) = '$(USEMAKEFILE)[.vms]$(FIRST_MAKEFILE)'; push(@macros,'__AXP__=1') if $Config{'archname'} eq 'VMS_AXP'; push(@macros,'DECC=1') if $Config{'vms_cc_type'} eq 'decc'; push(@macros,'GNUC=1') if $Config{'vms_cc_type'} eq 'gcc'; @@ -1851,15 +1693,15 @@ $(OBJECT) : $(FIRST_MAKEFILE) push @m,q[ # We take a very conservative approach here, but it\'s worth it. -# We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping. -$(MAKEFILE) : Makefile.PL $(CONFIGDEP) - $(NOECHO) $(SAY) "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)" - $(NOECHO) $(SAY) "Cleaning current config before rebuilding $(MAKEFILE) ..." - - $(MV) $(MAKEFILE) $(MAKEFILE)_old - - $(MMS)$(MMSQUALIFIERS) $(USEMAKEFILE)$(MAKEFILE)_old clean +# We move $(FIRST_MAKEFILE) to $(MAKEFILE_OLD) here to avoid gnu make looping. +$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP) + $(NOECHO) $(ECHO) "$(FIRST_MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)" + $(NOECHO) $(ECHO) "Cleaning current config before rebuilding $(FIRST_MAKEFILE) ..." + - $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) + - $(MMS)$(MMSQUALIFIERS) $(USEMAKEFILE)$(MAKEFILE_OLD) clean $(PERLRUN) Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[ - $(NOECHO) $(SAY) "$(MAKEFILE) has been rebuilt." - $(NOECHO) $(SAY) "Please run $(MMS) to build the extension." + $(NOECHO) $(ECHO) "$(FIRST_MAKEFILE) has been rebuilt." + $(NOECHO) $(ECHO) "Please run $(MMS) to build the extension." ]; join('',@m); @@ -1899,10 +1741,10 @@ testdb :: testdb_\$(LINKTYPE) "; foreach(@{$self->{DIR}}){ my($vmsdir) = $self->fixpath($_,1); - push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", + push(@m, ' If F$Search("',$vmsdir,'$(FIRST_MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", '; print `$(MMS)$(MMSQUALIFIERS) $(PASTHRU2) test`'."\n"); } - push(@m, "\t\$(NOECHO) \$(SAY) \"No tests defined for \$(NAME) extension.\"\n") + push(@m, "\t\$(NOECHO) \$(ECHO) \"No tests defined for \$(NAME) extension.\"\n") unless $tests or -f "test.pl" or @{$self->{DIR}}; push(@m, "\n"); @@ -1949,7 +1791,7 @@ use vars qw(%olbs); sub makeaperl { my($self, %attribs) = @_; - my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = + my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmpdir, $libperl) = @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)}; my(@m); push @m, " @@ -1963,10 +1805,10 @@ MAP_TARGET = $target unless ($self->{MAKEAPERL}) { push @m, q{ $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) - $(NOECHO) $(SAY) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)" + $(NOECHO) $(ECHO) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)" $(NOECHO) $(PERLRUNINST) \ Makefile.PL DIR=}, $dir, q{ \ - MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ + FIRST_MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ MAKEAPERL=1 NORECURS=1 }; push @m, map(q[ \\\n\t\t"$_"], @ARGV),q{ @@ -2091,23 +1933,23 @@ $(MAP_TARGET) :: $(MAKE_APERL_FILE) $shrtarget =~ s/^([^.]*)/$1Shr/; $shrtarget = $targdir . $shrtarget; $target = "Perlshr.$Config{'dlext'}" unless $target; - $tmp = "[]" unless $tmp; - $tmp = $self->fixpath($tmp,1); + $tmpdir = "[]" unless $tmpdir; + $tmpdir = $self->fixpath($tmpdir,1); if (@optlibs) { $extralist = join(' ',@optlibs); } else { $extralist = ''; } # Let ExtUtils::Liblist find the necessary libs for us (but skip PerlShr) # that's what we're building here). push @optlibs, grep { !/PerlShr/i } split ' ', +($self->ext())[2]; if ($libperl) { - unless (-f $libperl || -f ($libperl = File::Spec->catfile($Config{'installarchlib'},'CORE',$libperl))) { + unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) { print STDOUT "Warning: $libperl not found\n"; undef $libperl; } } unless ($libperl) { if (defined $self->{PERL_SRC}) { - $libperl = File::Spec->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}"); - } elsif (-f ($libperl = File::Spec->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) { + $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}"); + } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) { } else { print STDOUT "Warning: $libperl not found If you're going to build a static perl binary, make sure perl is installed @@ -2127,41 +1969,43 @@ MAP_LIBPERL = ",$self->fixpath($libperl,0),' '; - push @m,"\n${tmp}Makeaperl.Opt : \$(MAP_EXTRA)\n"; + push @m,"\n${tmpdir}Makeaperl.Opt : \$(MAP_EXTRA)\n"; foreach (@optlibs) { push @m,' $(NOECHO) $(PERL) -e "print q{',$_,'}" >>$(MMS$TARGET)',"\n"; } - push @m,"\n${tmp}PerlShr.Opt :\n\t"; + push @m,"\n${tmpdir}PerlShr.Opt :\n\t"; push @m,'$(NOECHO) $(PERL) -e "print q{$(MAP_SHRTARGET)}" >$(MMS$TARGET)',"\n"; -push @m,' + push @m,' $(MAP_SHRTARGET) : $(MAP_LIBPERL) Makeaperl.Opt ',"${libperldir}Perlshr_Attr.Opt",' $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_LIBPERL), Makeaperl.Opt/Option ',"${libperldir}Perlshr_Attr.Opt/Option",' -$(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",' - $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option - $(NOECHO) $(SAY) "To install the new ""$(MAP_TARGET)"" binary, say" - $(NOECHO) $(SAY) " $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)" - $(NOECHO) $(SAY) "To remove the intermediate files, say - $(NOECHO) $(SAY) " $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(MAKEFILE) map_clean" +$(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}PerlShr.Opt",' + $(MAP_LINKCMD) ',"${tmpdir}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option + $(NOECHO) $(ECHO) "To install the new ""$(MAP_TARGET)"" binary, say" + $(NOECHO) $(ECHO) " $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(FIRST_MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)" + $(NOECHO) $(ECHO) "To remove the intermediate files, say + $(NOECHO) $(ECHO) " $(MMS)$(MMSQUALIFIERS)$(USEMAKEFILE)$(FIRST_MAKEFILE) map_clean" '; - push @m,"\n${tmp}perlmain.c : \$(MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmp}Writemain.tmp\n"; + push @m,"\n${tmpdir}perlmain.c : \$(FIRST_MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmpdir}Writemain.tmp\n"; push @m, "# More from the 255-char line length limit\n"; foreach (@staticpkgs) { - push @m,' $(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmp}Writemain.tmp\n]; + push @m,' $(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmpdir}Writemain.tmp\n]; } - push @m,' - $(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" ',$tmp,'Writemain.tmp >$(MMS$TARGET) - $(NOECHO) $(RM_F) ',"${tmp}Writemain.tmp\n"; + + push @m, sprintf <<'MAKE_FRAG', $tmpdir, $tmpdir; + $(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" %sWritemain.tmp >$(MMS$TARGET) + $(NOECHO) $(RM_F) %sWritemain.tmp +MAKE_FRAG push @m, q[ # Still more from the 255-char line length limit doc_inst_perl : - $(NOECHO) $(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp - $(NOECHO) $(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp - $(NOECHO) $(PERL) -pl040 -e " " ].File::Spec->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp - $(NOECHO) $(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp - $(DOC_INSTALL) <.MM_tmp >>].File::Spec->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ - $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; + $(NOECHO) $(ECHO) "Perl binary $(MAP_TARGET)|" >.MM_tmp + $(NOECHO) $(ECHO) "MAP_STATIC|$(MAP_STATIC)|" >>.MM_tmp + $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp + $(NOECHO) $(ECHO) -e "MAP_LIBPERL|$(MAP_LIBPERL)|" >>.MM_tmp + $(NOECHO) $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ + $(NOECHO) $(RM_F) .MM_tmp ]; push @m, " @@ -2176,8 +2020,8 @@ clean :: map_clean \$(NOECHO) \$(NOOP) map_clean : - \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE) - \$(RM_F) ${tmp}Makeaperl.Opt ${tmp}PerlShr.Opt \$(MAP_TARGET) + \$(RM_F) ${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}perlmain.c \$(FIRST_MAKEFILE) + \$(RM_F) ${tmpdir}Makeaperl.Opt ${tmpdir}PerlShr.Opt \$(MAP_TARGET) "; join '', @m; @@ -2219,6 +2063,11 @@ used instead. sub prefixify { my($self, $var, $sprefix, $rprefix, $default) = @_; + + # Translate $(PERLPREFIX) to a real path. + $rprefix = $self->eliminate_macros($rprefix); + $rprefix = VMS::Filespec::vmspath($rprefix) if $rprefix; + $default = VMS::Filespec::vmsify($default) unless $default =~ /\[.*\]/; @@ -2238,7 +2087,7 @@ sub prefixify { print STDERR " prefixify $var => $path\n" if $Verbose >= 2; print STDERR " from $sprefix to $rprefix\n" if $Verbose >= 2; - my($path_vol, $path_dirs) = File::Spec->splitpath( $path ); + my($path_vol, $path_dirs) = $self->splitpath( $path ); if( $path_vol eq $Config{vms_prefix}.':' ) { print STDERR " $Config{vms_prefix}: seen\n" if $Verbose >= 2; @@ -2275,19 +2124,230 @@ sub _prefixify_default { sub _catprefix { my($self, $rprefix, $default) = @_; - my($rvol, $rdirs) = File::Spec->splitpath($rprefix); + my($rvol, $rdirs) = $self->splitpath($rprefix); if( $rvol ) { - return File::Spec->catpath($rvol, - File::Spec->catdir($rdirs, $default), + return $self->catpath($rvol, + $self->catdir($rdirs, $default), '' ) } else { - return File::Spec->catdir($rdirs, $default); + return $self->catdir($rdirs, $default); } } +=item oneliner (o) + +=cut + +sub oneliner { + my($self, $cmd, $switches) = @_; + $switches = [] unless defined $switches; + + # Strip leading and trailing newlines + $cmd =~ s{^\n+}{}; + $cmd =~ s{\n+$}{}; + + $cmd = $self->quote_literal($cmd); + $cmd = $self->escape_newlines($cmd); + + # Switches must be quoted else they will be lowercased. + $switches = join ' ', map { qq{"$_"} } @$switches; + + return qq{\$(PERLRUN) $switches -e $cmd}; +} + + +=item B (o) + +perl trips up on "" thinking its an input redirect. So we use the +native Write sys$output instead. + +=cut + +sub echo { + my($self, $text, $file, $appending) = @_; + $appending ||= 0; + + die "The VMS version of echo() cannot currently append" if $appending; + + my @cmds = ("\$(NOECHO) Assign $file Sys\$Output"); + push @cmds, map { '$(NOECHO) Write Sys$Output '.$self->quote_literal($_) } + split /\n/, $text; + push @cmds, '$(NOECHO) Deassign Sys$Output'; + return @cmds; +} + + +=item quote_literal + +=cut + +sub quote_literal { + my($self, $text) = @_; + + # I believe this is all we should need. + $text =~ s{"}{""}g; + + return qq{"$text"}; +} + +=item escape_newlines + +=cut + +sub escape_newlines { + my($self, $text) = @_; + + $text =~ s{\n}{-\n}g; + + return $text; +} + +=item max_exec_len + +256 characters. + +=cut + +sub max_exec_len { + my $self = shift; + + return $self->{_MAX_EXEC_LEN} ||= 256; +} + +=item init_linker (o) + +=cut + +sub init_linker { + my $self = shift; + $self->{EXPORT_LIST} ||= '$(BASEEXT).opt'; + + my $shr = $Config{dbgprefix} . 'PERLSHR'; + $self->{PERL_ARCHIVE} ||= $ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}"; + + $self->{PERL_ARCHIVE_AFTER} ||= ''; +} + +=item eliminate_macros + +Expands MM[KS]/Make macros in a text string, using the contents of +identically named elements of C<%$self>, and returns the result +as a file specification in Unix syntax. + +NOTE: This is the cannonical version of the method. The version in +File::Spec::VMS is deprecated. + +=cut + +sub eliminate_macros { + my($self,$path) = @_; + return '' unless $path; + $self = {} unless ref $self; + + if ($path =~ /\s/) { + return join ' ', map { $self->eliminate_macros($_) } split /\s+/, $path; + } + + my($npath) = unixify($path); + # sometimes unixify will return a string with an off-by-one trailing null + $npath =~ s{\0$}{}; + + my($complex) = 0; + my($head,$macro,$tail); + + # perform m##g in scalar context so it acts as an iterator + while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#gs) { + if (defined $self->{$2}) { + ($head,$macro,$tail) = ($1,$2,$3); + if (ref $self->{$macro}) { + if (ref $self->{$macro} eq 'ARRAY') { + $macro = join ' ', @{$self->{$macro}}; + } + else { + print "Note: can't expand macro \$($macro) containing ",ref($self->{$macro}), + "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n"; + $macro = "\cB$macro\cB"; + $complex = 1; + } + } + else { ($macro = unixify($self->{$macro})) =~ s#/\Z(?!\n)##; } + $npath = "$head$macro$tail"; + } + } + if ($complex) { $npath =~ s#\cB(.*?)\cB#\${$1}#gs; } + $npath; +} + +=item fixpath + +Catchall routine to clean up problem MM[SK]/Make macros. Expands macros +in any directory specification, in order to avoid juxtaposing two +VMS-syntax directories when MM[SK] is run. Also expands expressions which +are all macro, so that we can tell how long the expansion is, and avoid +overrunning DCL's command buffer when MM[KS] is running. + +If optional second argument has a TRUE value, then the return string is +a VMS-syntax directory specification, if it is FALSE, the return string +is a VMS-syntax file specification, and if it is not specified, fixpath() +checks to see whether it matches the name of a directory in the current +default directory, and returns a directory or file specification accordingly. + +NOTE: This is the cannonical version of the method. The version in +File::Spec::VMS is deprecated. + +=cut + +sub fixpath { + my($self,$path,$force_path) = @_; + return '' unless $path; + $self = bless {} unless ref $self; + my($fixedpath,$prefix,$name); + + if ($path =~ /\s/) { + return join ' ', + map { $self->fixpath($_,$force_path) } + split /\s+/, $path; + } + + if ($path =~ m#^\$\([^\)]+\)\Z(?!\n)#s || $path =~ m#[/:>\]]#) { + if ($force_path or $path =~ /(?:DIR\)|\])\Z(?!\n)/) { + $fixedpath = vmspath($self->eliminate_macros($path)); + } + else { + $fixedpath = vmsify($self->eliminate_macros($path)); + } + } + elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#s)) && $self->{$prefix}) { + my($vmspre) = $self->eliminate_macros("\$($prefix)"); + # is it a dir or just a name? + $vmspre = ($vmspre =~ m|/| or $prefix =~ /DIR\Z(?!\n)/) ? vmspath($vmspre) : ''; + $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name; + $fixedpath = vmspath($fixedpath) if $force_path; + } + else { + $fixedpath = $path; + $fixedpath = vmspath($fixedpath) if $force_path; + } + # No hints, so we try to guess + if (!defined($force_path) and $fixedpath !~ /[:>(.\]]/) { + $fixedpath = vmspath($fixedpath) if -d $fixedpath; + } + + # Trim off root dirname if it's had other dirs inserted in front of it. + $fixedpath =~ s/\.000000([\]>])/$1/; + # Special case for VMS absolute directory specs: these will have had device + # prepended during trip through Unix syntax in eliminate_macros(), since + # Unix syntax has no way to express "absolute from the top of this device's + # directory tree". + if ($path =~ /^[\[>][^.\-]/) { $fixedpath =~ s/^[^\[<]+//; } + + return $fixedpath; +} + + =back =cut diff --git a/lib/ExtUtils/MM_Win32.pm b/lib/ExtUtils/MM_Win32.pm index 03af82e..da1440f 100644 --- a/lib/ExtUtils/MM_Win32.pm +++ b/lib/ExtUtils/MM_Win32.pm @@ -1,5 +1,7 @@ package ExtUtils::MM_Win32; +use strict; + =head1 NAME @@ -15,8 +17,6 @@ See ExtUtils::MM_Unix for a documentation of the methods provided there. This package overrides the implementation of these methods, not the semantics. -=over 4 - =cut use Config; @@ -24,12 +24,12 @@ use File::Basename; use File::Spec; use ExtUtils::MakeMaker qw( neatvalue ); -use vars qw(@ISA $VERSION $BORLAND $GCC $DMAKE $NMAKE $PERLMAKE); +use vars qw(@ISA $VERSION $BORLAND $GCC $DMAKE $NMAKE); require ExtUtils::MM_Any; require ExtUtils::MM_Unix; @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); -$VERSION = '1.05'; +$VERSION = '1.06'; $ENV{EMXSHELL} = 'sh'; # to run `commands` @@ -37,7 +37,15 @@ $BORLAND = 1 if $Config{'cc'} =~ /^bcc/i; $GCC = 1 if $Config{'cc'} =~ /^gcc/i; $DMAKE = 1 if $Config{'make'} =~ /^dmake/i; $NMAKE = 1 if $Config{'make'} =~ /^nmake/i; -$PERLMAKE = 1 if $Config{'make'} =~ /^pmake/i; + + +=head2 Overridden methods + +=over 4 + +=item B + +=cut sub dlsyms { my($self,%attribs) = @_; @@ -47,7 +55,6 @@ sub dlsyms { my($funclist) = $attribs{FUNCLIST} || $self->{FUNCLIST} || []; my($imports) = $attribs{IMPORTS} || $self->{IMPORTS} || {}; my(@m); - (my $boot = $self->{NAME}) =~ s/:/_/g; if (not $self->{SKIPHASH}{'dynamic'}) { push(@m," @@ -69,12 +76,30 @@ $self->{BASEEXT}.def: Makefile.PL join('',@m); } +=item replace_manpage_separator + +Changes the path separator with . + +=cut + sub replace_manpage_separator { my($self,$man) = @_; $man =~ s,/+,.,g; $man; } + +=item B + +Since Windows has nothing as simple as an executable bit, we check the +file extension. + +The PATHEXT env variable will be used to get a list of extensions that +might indicate a command, otherwise .com, .exe, .bat and .cmd will be +used by default. + +=cut + sub maybe_command { my($self,$file) = @_; my @e = exists($ENV{'PATHEXT'}) @@ -96,313 +121,179 @@ sub maybe_command { } -sub find_perl { - my($self, $ver, $names, $dirs, $trace) = @_; - $trace ||= 0; +=item B - my($name, $dir); - if ($trace >= 2){ - print "Looking for perl $ver by these names: -@$names -in these dirs: -@$dirs -"; - } - foreach $dir (@$dirs){ - next unless defined $dir; # $self->{PERL_SRC} may be undefined - foreach $name (@$names){ - my ($abs, $val); - if (File::Spec->file_name_is_absolute($name)) { # /foo/bar - $abs = $name; - } elsif (File::Spec->canonpath($name) eq - File::Spec->canonpath(basename($name))) # foo - { - $abs = File::Spec->catfile($dir, $name); - } else { # foo/bar - $abs = File::Spec->canonpath( - File::Spec->catfile(File::Spec->curdir, $name) - ); - } - print "Checking $abs\n" if ($trace >= 2); - next unless $self->maybe_command($abs); - print "Executing $abs\n" if ($trace >= 2); - (my($safe_abs) = $abs) =~ s{(\s)}{\\$1}g; - $val = `$safe_abs -e "require $ver;" 2>&1`; - if ($? == 0) { - print "Using PERL=$abs\n" if $trace; - return $abs; - } elsif ($trace >= 2) { - print "Result: `$val'\n"; - } - } - } - print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n"; - 0; # false and not empty -} +The Win9x shell does not expand globs and I'll play it safe and assume +other Windows variants don't either. + +So we do it for them. +=cut -# This code was taken out of MM_Unix to avoid loading File::Glob -# unless necessary. sub find_tests { return join(' ', ); } -sub init_others -{ - my ($self) = @_; - $self->SUPER::init_others; - $self->{'TOUCH'} = '$(PERLRUN) -MExtUtils::Command -e touch'; - $self->{'CHMOD'} = '$(PERLRUN) -MExtUtils::Command -e chmod'; - $self->{'CP'} = '$(PERLRUN) -MExtUtils::Command -e cp'; - $self->{'RM_F'} = '$(PERLRUN) -MExtUtils::Command -e rm_f'; - $self->{'RM_RF'} = '$(PERLRUN) -MExtUtils::Command -e rm_rf'; - $self->{'MV'} = '$(PERLRUN) -MExtUtils::Command -e mv'; - $self->{'NOOP'} = 'rem'; - $self->{'TEST_F'} = '$(PERLRUN) -MExtUtils::Command -e test_f'; - $self->{'LD'} = $Config{'ld'} || 'link'; - $self->{'AR'} = $Config{'ar'} || 'lib'; - $self->{'LDLOADLIBS'} ||= $Config{'libs'}; - # -Lfoo must come first for Borland, so we put it in LDDLFLAGS - if ($BORLAND) { - my $libs = $self->{'LDLOADLIBS'}; - my $libpath = ''; - while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) { - $libpath .= ' ' if length $libpath; - $libpath .= $1; - } - $self->{'LDLOADLIBS'} = $libs; - $self->{'LDDLFLAGS'} ||= $Config{'lddlflags'}; - $self->{'LDDLFLAGS'} .= " $libpath"; - } - $self->{'DEV_NULL'} = '> NUL'; +=item B + +Using \ for Windows. + +=cut + +sub init_DIRFILESEP { + my($self) = shift; + + # gotta be careful this isn't interpreted as an escape. + $self->{DIRFILESEP} = '^\\'; } +=item B + +Override some of the Unix specific commands with portable +ExtUtils::Command ones. + +Also provide defaults for LD and AR in case the %Config values aren't +set. -=item constants (o) +LDLOADLIBS's default is changed to $Config{libs}. -Initializes lots of constants and .SUFFIXES and .PHONY +Adjustments are made for Borland's quirks needing -L to come first. =cut -sub constants { - my($self) = @_; - my(@m,$tmp); - - for $tmp (qw/ - AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION - VERSION_SYM XS_VERSION - INST_BIN INST_LIB INST_ARCHLIB INST_SCRIPT - INSTALLDIRS - PREFIX SITEPREFIX VENDORPREFIX - INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB - INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH - INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN INSTALLSCRIPT - PERL_LIB PERL_ARCHLIB - SITELIBEXP SITEARCHEXP - LIBPERL_A MYEXTLIB - FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC - PERL_INC PERL FULLPERL PERLRUN FULLPERLRUN PERLRUNINST - FULLPERLRUNINST ABSPERL ABSPERLRUN ABSPERLRUNINST - FULL_AR PERL_CORE - - / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; +sub init_others { + my ($self) = @_; + + # Used in favor of echo because echo won't strip quotes. :( + $self->{ECHO} ||= '$(PERLRUN) -le "print qq{@ARGV}"'; + $self->{TOUCH} ||= '$(PERLRUN) -MExtUtils::Command -e touch'; + $self->{CHMOD} ||= '$(PERLRUN) -MExtUtils::Command -e chmod'; + $self->{CP} ||= '$(PERLRUN) -MExtUtils::Command -e cp'; + $self->{RM_F} ||= '$(PERLRUN) -MExtUtils::Command -e rm_f'; + $self->{RM_RF} ||= '$(PERLRUN) -MExtUtils::Command -e rm_rf'; + $self->{MV} ||= '$(PERLRUN) -MExtUtils::Command -e mv'; + $self->{NOOP} ||= 'rem'; + $self->{TEST_F} ||= '$(PERLRUN) -MExtUtils::Command -e test_f'; + $self->{DEV_NULL} ||= '> NUL'; + + # technically speaking, these should be in init_main() + $self->{LD} ||= $Config{ld} || 'link'; + $self->{AR} ||= $Config{ar} || 'lib'; + + $self->SUPER::init_others; + + $self->{LDLOADLIBS} ||= $Config{libs}; + # -Lfoo must come first for Borland, so we put it in LDDLFLAGS + if ($BORLAND) { + my $libs = $self->{LDLOADLIBS}; + my $libpath = ''; + while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) { + $libpath .= ' ' if length $libpath; + $libpath .= $1; + } + $self->{LDLOADLIBS} = $libs; + $self->{LDDLFLAGS} ||= $Config{lddlflags}; + $self->{LDDLFLAGS} .= " $libpath"; } - push @m, qq{ -VERSION_MACRO = VERSION -DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\" -XS_VERSION_MACRO = XS_VERSION -XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\" -}; + return 1; +} - push @m, qq{ -MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'} -MM_VERSION = $ExtUtils::MakeMaker::VERSION -}; - push @m, q{ -# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). -# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) -# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) -# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. -}; +=item init_platform (o) - for $tmp (qw/ - FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT - LDFROM LINKTYPE - / ) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; - } +Add MM_Win32_VERSION. - push @m, " -# Handy lists of source code files: -XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})." -C_FILES = ".join(" \\\n\t", @{$self->{C}})." -O_FILES = ".join(" \\\n\t", @{$self->{O_FILES}})." -H_FILES = ".join(" \\\n\t", @{$self->{H}})." -MAN1PODS = ".join(" \\\n\t", sort keys %{$self->{MAN1PODS}})." -MAN3PODS = ".join(" \\\n\t", sort keys %{$self->{MAN3PODS}})." -"; - - for $tmp (qw/ - INST_MAN1DIR MAN1EXT - INSTALLMAN1DIR INSTALLSITEMAN1DIR INSTALLVENDORMAN1DIR - INST_MAN3DIR MAN3EXT - INSTALLMAN3DIR INSTALLSITEMAN3DIR INSTALLVENDORMAN3DIR - /) { - next unless defined $self->{$tmp}; - push @m, "$tmp = $self->{$tmp}\n"; - } +=item platform_constants (o) - push @m, qq{ -.USESHELL : -} if $DMAKE; +=cut - push @m, q{ -.NO_CONFIG_REC: Makefile -} if $ENV{CLEARCASE_ROOT}; +sub init_platform { + my($self) = shift; - # why not q{} ? -- emacs - push @m, qq{ -# work around a famous dec-osf make(1) feature(?): -makemakerdflt: all + $self->{MM_Win32_VERSION} = $VERSION; +} -.SUFFIXES: .xs .c .C .cpp .cxx .cc \$(OBJ_EXT) +sub platform_constants { + my($self) = shift; + my $make_frag = ''; -# Nick wanted to get rid of .PRECIOUS. I don't remember why. I seem to -# recall, that some make implementations will delete the Makefile when we -# rebuild it. Because we call false(1) when we rebuild it. So make(1) is -# not completely wrong when it does so. Our milage may vary. -# .PRECIOUS: Makefile # seems to be not necessary anymore + foreach my $macro (qw(MM_Win32_VERSION)) + { + next unless defined $self->{$macro}; + $make_frag .= "$macro = $self->{$macro}\n"; + } -.PHONY: all config static dynamic test linkext manifest + return $make_frag; +} -# Where is the Config information that we are using/depend on -CONFIGDEP = \$(PERL_ARCHLIB)\\Config.pm \$(PERL_INC)\\config.h -}; - my @parentdir = split(/::/, $self->{PARENT_NAME}); - push @m, q{ -# Where to put things: -INST_LIBDIR = }. File::Spec->catdir('$(INST_LIB)',@parentdir) .q{ -INST_ARCHLIBDIR = }. File::Spec->catdir('$(INST_ARCHLIB)',@parentdir) .q{ +=item special_targets (o) -INST_AUTODIR = }. File::Spec->catdir('$(INST_LIB)','auto','$(FULLEXT)') .q{ -INST_ARCHAUTODIR = }. File::Spec->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)') .q{ -}; +Add .USESHELL target for dmake. - if ($self->has_link_code()) { - push @m, ' -INST_STATIC = $(INST_ARCHAUTODIR)\$(BASEEXT)$(LIB_EXT) -INST_DYNAMIC = $(INST_ARCHAUTODIR)\$(DLBASE).$(DLEXT) -INST_BOOT = $(INST_ARCHAUTODIR)\$(BASEEXT).bs -'; - } else { - push @m, ' -INST_STATIC = -INST_DYNAMIC = -INST_BOOT = -'; - } +=cut - $tmp = $self->export_list; - push @m, " -EXPORT_LIST = $tmp -"; - $tmp = $self->perl_archive; - push @m, " -PERL_ARCHIVE = $tmp -"; +sub special_targets { + my($self) = @_; - push @m, q{ -TO_INST_PM = }.join(" \\\n\t", sort keys %{$self->{PM}}).q{ + my $make_frag = $self->SUPER::special_targets; -PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{ -}; + $make_frag .= <<'MAKE_FRAG' if $DMAKE; +.USESHELL : +MAKE_FRAG - join('',@m); + return $make_frag; } =item static_lib (o) -Defines how to produce the *.a (or equivalent) files. +Changes how to run the linker. + +The rest is duplicate code from MM_Unix. Should move the linker code +to its own method. =cut sub static_lib { my($self) = @_; -# Come to think of it, if there are subdirs with linkcode, we still have no INST_STATIC -# return '' unless $self->needs_linking(); #might be because of a subdir - return '' unless $self->has_link_code; my(@m); push(@m, <<'END'); -$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)\.exists +$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(RM_RF) $@ END + # If this extension has its own library (eg SDBM_File) # then copy that to $(INST_STATIC) and add $(OBJECT) into it. - push(@m, "\t$self->{CP} \$(MYEXTLIB) \$\@\n") if $self->{MYEXTLIB}; + push @m, <<'MAKE_FRAG' if $self->{MYEXTLIB}; + $(CP) $(MYEXTLIB) $@ +MAKE_FRAG push @m, q{ $(AR) }.($BORLAND ? '$@ $(OBJECT:^"+")' : ($GCC ? '-ru $@ $(OBJECT)' : '-out:$@ $(OBJECT)')).q{ - }.$self->{NOECHO}.q{echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld - $(CHMOD) 755 $@ + $(CHMOD) $(PERM_RWX) $@ + $(NOECHO) $(ECHO) "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld }; -# Old mechanism - still available: + # Old mechanism - still available: + push @m, <<'MAKE_FRAG' if $self->{PERL_SRC} && $self->{EXTRALIBS}; + $(NOECHO) $(ECHO) "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs +MAKE_FRAG - push @m, "\t$self->{NOECHO}".q{echo "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs}."\n\n" - if $self->{PERL_SRC}; - - push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); - join('', "\n",@m); + push @m, "\n", $self->dir_target('$(INST_ARCHAUTODIR)'); + join('', @m); } -=item dynamic_bs (o) - -Defines targets for bootstrap files. - -=cut - -sub dynamic_bs { - my($self, %attribs) = @_; - return ' -BOOTSTRAP = -' unless $self->has_link_code(); - - return ' -BOOTSTRAP = '."$self->{BASEEXT}.bs".' - -# As Mkbootstrap might not write a file (if none is required) -# we use touch to prevent make continually trying to remake it. -# The DynaLoader only reads a non-empty file. -$(BOOTSTRAP): '."$self->{MAKEFILE} $self->{BOOTDEP}".' $(INST_ARCHAUTODIR)\.exists - '.$self->{NOECHO}.'echo "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))" - '.$self->{NOECHO}.'$(PERLRUN) \ - -MExtUtils::Mkbootstrap \ - -e "Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');" - '.$self->{NOECHO}.'$(TOUCH) $(BOOTSTRAP) - $(CHMOD) 644 $@ - -$(INST_BOOT): $(BOOTSTRAP) $(INST_ARCHAUTODIR)\.exists - '."$self->{NOECHO}$self->{RM_RF}".' $(INST_BOOT) - -'.$self->{CP}.' $(BOOTSTRAP) $(INST_BOOT) - $(CHMOD) 644 $@ -'; -} =item dynamic_lib (o) -Defines how to produce the *.so (or equivalent) files. +Complicated stuff for Win32 that I don't understand. :( =cut @@ -434,7 +325,7 @@ sub dynamic_lib { OTHERLDFLAGS = '.$otherldflags.' INST_DYNAMIC_DEP = '.$inst_dynamic_dep.' -$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)\.exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) +$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DIRFILESEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) '); if ($GCC) { push(@m, @@ -456,13 +347,20 @@ $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)\.exists .q{$(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)}); } push @m, ' - $(CHMOD) 755 $@ + $(CHMOD) $(PERM_RWX) $@ '; push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); join('',@m); } +=item clean + +Clean out some extra dll.{base,exp} files which might be generated by +gcc. Otherwise, take out all *.pdb files. + +=cut + sub clean { my ($self) = shift; @@ -476,309 +374,114 @@ END return $s; } +=item init_linker +=cut -sub perl_archive -{ - my ($self) = @_; - return '$(PERL_INC)\\'.$Config{'libperl'}; -} +sub init_linker { + my $self = shift; -sub export_list -{ - my ($self) = @_; - return "$self->{BASEEXT}.def"; + $self->{PERL_ARCHIVE} = "\$(PERL_INC)\\$Config{libperl}"; + $self->{PERL_ARCHIVE_AFTER} = ''; + $self->{EXPORT_LIST} = '$(BASEEXT).def'; } =item perl_script -Takes one argument, a file name, and returns the file name, if the -argument is likely to be a perl script. On MM_Unix this is true for -any ordinary, readable file. +Checks for the perl program under several common perl extensions. =cut sub perl_script { my($self,$file) = @_; return $file if -r $file && -f _; - return "$file.pl" if -r "$file.pl" && -f _; + return "$file.pl" if -r "$file.pl" && -f _; + return "$file.plx" if -r "$file.plx" && -f _; return "$file.bat" if -r "$file.bat" && -f _; return; } -=item pm_to_blib - -Defines target that copies all files in the hash PM to their -destination and autosplits them. See L - -=cut - -sub pm_to_blib { - my $self = shift; - my($autodir) = File::Spec->catdir('$(INST_LIB)','auto'); - return q{ -pm_to_blib: $(TO_INST_PM) - }.$self->{NOECHO}.q{$(PERLRUNINST) -MExtUtils::Install \ - -e "pm_to_blib(}. - ($NMAKE ? 'qw[ <{NOECHO}.q{$(TOUCH) $@ -}; -} - -=item tool_autosplit (override) +=item xs_o (o) -Use Win32 quoting on command line. +This target is stubbed out. Not sure why. =cut -sub tool_autosplit{ - my($self, %attribs) = @_; - my($asl) = ""; - $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN}; - q{ -# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto -AUTOSPLITFILE = $(PERLRUN) -MAutoSplit }.$asl.q{ -e "autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1);" -}; +sub xs_o { + return '' } -=item tools_other (o) -Win32 overrides. +=item pasthru (o) -Defines SHELL, LD, TOUCH, CP, MV, RM_F, RM_RF, CHMOD, UMASK_NULL in -the Makefile. Also defines the perl programs MKPATH, -WARN_IF_OLD_PACKLIST, MOD_INSTALL. DOC_INSTALL, and UNINSTALL. +All we send is -nologo to nmake to prevent it from printing its damned +banner. =cut -sub tools_other { +sub pasthru { my($self) = shift; - my @m; - my $bin_sh = $Config{sh} || 'cmd /c'; - push @m, qq{ -SHELL = $bin_sh -} unless $DMAKE; # dmake determines its own shell - - for (qw/ CHMOD CP LD MV NOOP RM_F RM_RF TEST_F TOUCH UMASK_NULL DEV_NULL/ ) { - push @m, "$_ = $self->{$_}\n"; - } - - push @m, q{ -# The following is a portable way to say mkdir -p -# To see which directories are created, change the if 0 to if 1 -MKPATH = $(PERLRUN) -MExtUtils::Command -e mkpath - -# This helps us to minimize the effect of the .exists files A yet -# better solution would be to have a stable file in the perl -# distribution with a timestamp of zero. But this solution doesn't -# need any changes to the core distribution and works with older perls -EQUALIZE_TIMESTAMP = $(PERLRUN) -MExtUtils::Command -e eqtime -}; - - - return join "", @m if $self->{PARENT}; - - push @m, q{ -# Here we warn users that an old packlist file was found somewhere, -# and that they should call some uninstall routine -WARN_IF_OLD_PACKLIST = $(PERL) -lwe "exit unless -f $$ARGV[0];" \\ --e "print 'WARNING: I have found an old package in';" \\ --e "print ' ', $$ARGV[0], '.';" \\ --e "print 'Please make sure the two installations are not conflicting';" - -UNINST=0 -VERBINST=1 - -MOD_INSTALL = $(PERL) -I$(INST_LIB) -I$(PERL_LIB) -MExtUtils::Install \ --e "install({ @ARGV },'$(VERBINST)',0,'$(UNINST)');" - -DOC_INSTALL = $(PERL) -e "$$\=\"\n\n\";" \ --e "print '=head2 ', scalar(localtime), ': C<', shift, '>', ' L<', $$arg=shift, '|', $$arg, '>';" \ --e "print '=over 4';" \ --e "while (defined($$key = shift) and defined($$val = shift)) { print '=item *';print 'C<', \"$$key: $$val\", '>'; }" \ --e "print '=back';" - -UNINSTALL = $(PERL) -MExtUtils::Install \ --e "uninstall($$ARGV[0],1,1); print \"\nUninstall is deprecated. Please check the";" \ --e "print \" packlist above carefully.\n There may be errors. Remove the\";" \ --e "print \" appropriate files manually.\n Sorry for the inconveniences.\n\"" -}; - - return join "", @m; + return "PASTHRU = " . ($NMAKE ? "-nologo" : ""); } -=item xs_o (o) - -Defines suffix rules to go from XS to object files directly. This is -only intended for broken make implementations. - -=cut - -sub xs_o { # many makes are too dumb to use xs_c then c_o - my($self) = shift; - return '' -} -=item top_targets (o) +=item oneliner (o) -Defines the targets all, subdirs, config, and O_FILES +These are based on what command.com does on Win98. They may be wrong +for other Windows shells, I don't know. =cut -sub top_targets { -# --- Target Sections --- - - my($self) = shift; - my(@m); - - push @m, ' -all :: pure_all manifypods - '.$self->{NOECHO}.'$(NOOP) -' - unless $self->{SKIPHASH}{'all'}; - - push @m, ' -pure_all :: config pm_to_blib subdirs linkext - '.$self->{NOECHO}.'$(NOOP) - -subdirs :: $(MYEXTLIB) - '.$self->{NOECHO}.'$(NOOP) - -config :: '.$self->{MAKEFILE}.' $(INST_LIBDIR)\.exists - '.$self->{NOECHO}.'$(NOOP) +sub oneliner { + my($self, $cmd, $switches) = @_; + $switches = [] unless defined $switches; -config :: $(INST_ARCHAUTODIR)\.exists - '.$self->{NOECHO}.'$(NOOP) + # Strip leading and trailing newlines + $cmd =~ s{^\n+}{}; + $cmd =~ s{\n+$}{}; -config :: $(INST_AUTODIR)\.exists - '.$self->{NOECHO}.'$(NOOP) -'; - - push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]); - - if (%{$self->{MAN1PODS}}) { - push @m, qq[ -config :: \$(INST_MAN1DIR)\\.exists - $self->{NOECHO}\$(NOOP) - -]; - push @m, $self->dir_target(qw[$(INST_MAN1DIR)]); - } - if (%{$self->{MAN3PODS}}) { - push @m, qq[ -config :: \$(INST_MAN3DIR)\\.exists - $self->{NOECHO}\$(NOOP) + $cmd = $self->quote_literal($cmd); + $cmd = $self->escape_newlines($cmd); -]; - push @m, $self->dir_target(qw[$(INST_MAN3DIR)]); - } - - push @m, ' -$(O_FILES): $(H_FILES) -' if @{$self->{O_FILES} || []} && @{$self->{H} || []}; - - push @m, q{ -help: - perldoc ExtUtils::MakeMaker -}; + $switches = join ' ', @$switches; - join('',@m); + return qq{\$(PERLRUN) $switches -e $cmd}; } -=item manifypods (o) -We don't want manpage process. +sub quote_literal { + my($self, $text) = @_; -=cut + # I don't know if this is correct, but it seems to work on + # Win98's command.com + $text =~ s{"}{\\"}g; -sub manifypods { - my($self) = shift; - return "\nmanifypods :\n\t$self->{NOECHO}\$(NOOP)\n"; + return qq{"$text"}; } -=item dist_ci (o) -Same as MM_Unix version (changes command-line quoting). +sub escape_newlines { + my($self, $text) = @_; -=cut + # Escape newlines + $text =~ s{\n}{\\\n}g; -sub dist_ci { - my($self) = shift; - my @m; - push @m, q{ -ci : - $(PERLRUN) -MExtUtils::Manifest=maniread \\ - -e "@all = keys %{ maniread() };" \\ - -e "print(\"Executing $(CI) @all\n\"); system(\"$(CI) @all\");" \\ - -e "print(\"Executing $(RCS_LABEL) ...\n\"); system(\"$(RCS_LABEL) @all\");" -}; - join "", @m; + return $text; } -=item dist_core (o) -Same as MM_Unix version (changes command-line quoting). +=item max_exec_len -=cut - -sub dist_core { - my($self) = shift; - my @m; - push @m, q{ -dist : $(DIST_DEFAULT) - }.$self->{NOECHO}.q{$(PERL) -le "print \"Warning: Makefile possibly out of date with $$vf\" if " \ - -e "-e ($$vf=\"$(VERSION_FROM)\") and -M $$vf < -M \"}.$self->{MAKEFILE}.q{\";" - -tardist : $(DISTVNAME).tar$(SUFFIX) - -zipdist : $(DISTVNAME).zip - -$(DISTVNAME).tar$(SUFFIX) : distdir - $(PREOP) - $(TO_UNIX) - $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME) - $(RM_RF) $(DISTVNAME) - $(COMPRESS) $(DISTVNAME).tar - $(POSTOP) - -$(DISTVNAME).zip : distdir - $(PREOP) - $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME) - $(RM_RF) $(DISTVNAME) - $(POSTOP) - -uutardist : $(DISTVNAME).tar$(SUFFIX) - uuencode $(DISTVNAME).tar$(SUFFIX) \\ - $(DISTVNAME).tar$(SUFFIX) > \\ - $(DISTVNAME).tar$(SUFFIX)_uu - -shdist : distdir - $(PREOP) - $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar - $(RM_RF) $(DISTVNAME) - $(POSTOP) -}; - join "", @m; -} - -=item pasthru (o) - -Defines the string that is passed to recursive make calls in -subdirectories. +Using 31K, a safe number gotten from Windows 2000. =cut -sub pasthru { - my($self) = shift; - return "PASTHRU = " . ($NMAKE ? "-nologo" : ""); +sub max_exec_len { + my $self = shift; + + return $self->{_MAX_EXEC_LEN} ||= 31 * 1024; } diff --git a/lib/ExtUtils/MM_Win95.pm b/lib/ExtUtils/MM_Win95.pm index 010900f..1854d5d 100644 --- a/lib/ExtUtils/MM_Win95.pm +++ b/lib/ExtUtils/MM_Win95.pm @@ -5,7 +5,11 @@ $VERSION = 0.02; require ExtUtils::MM_Win32; @ISA = qw(ExtUtils::MM_Win32); -use Config; + +use Config; +my $DMAKE = 1 if $Config{'make'} =~ /^dmake/i; +my $NMAKE = 1 if $Config{'make'} =~ /^nmake/i; + =head1 NAME @@ -20,6 +24,18 @@ ExtUtils::MM_Win95 - method to customize MakeMaker for Win9X This is a subclass of ExtUtils::MM_Win32 containing changes necessary to get MakeMaker playing nice with command.com and other Win9Xisms. +=head2 Overriden methods + +Most of these make up for limitations in the Win9x command shell. +Namely the lack of && and that a chdir is global, so you have to chdir +back at the end. + +=over 4 + +=item dist_test + +&& and chdir problem. + =cut sub dist_test { @@ -34,38 +50,174 @@ disttest : distdir }; } +=item subdir_x + +&& and chdir problem. + +Also, dmake has an odd way of making a command series silent. + +=cut + +sub subdir_x { + my($self, $subdir) = @_; + + # Win-9x has nasty problem in command.com that can't cope with + # &&. Also, Dmake has an odd way of making a commandseries silent: + if ($DMAKE) { + return sprintf <<'EOT', $subdir; + +subdirs :: +@[ + cd %s + $(MAKE) all $(PASTHRU) + cd .. +] +EOT + } + else { + return sprintf <<'EOT', $subdir; + +subdirs :: + $(NOECHO)cd %s + $(NOECHO)$(MAKE) all $(PASTHRU) + $(NOECHO)cd .. +EOT + } +} + +=item xs_c + +The && problem. + +=cut + sub xs_c { my($self) = shift; return '' unless $self->needs_linking(); ' .xs.c: - $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\ - $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c + $(PERLRUN) $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c ' } + +=item xs_cpp + +The && problem + +=cut + sub xs_cpp { my($self) = shift; return '' unless $self->needs_linking(); ' .xs.cpp: - $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\ - $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.cpp + $(PERLRUN) $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.cpp '; } -# many makes are too dumb to use xs_c then c_o +=item xs_o + +The && problem. + +=cut + sub xs_o { my($self) = shift; return '' unless $self->needs_linking(); - # having to choose between .xs -> .c -> .o and .xs -> .o confuses dmake - return '' if $Config{make} eq 'dmake'; ' .xs$(OBJ_EXT): - $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\ - $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c + $(PERLRUN) $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c '; } +=item clean_subdirs_target + +&& and chdir problem. + +=cut + +sub clean_subdirs_target { + my($self) = shift; + + # No subdirectories, no cleaning. + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +clean_subdirs : + $(NOECHO)$(NOOP) +NOOP_FRAG + + + my $clean = "clean_subdirs :\n"; + + for my $dir (@{$self->{DIR}}) { + $clean .= sprintf <<'MAKE_FRAG', $dir; + cd %s + $(TEST_F) $(FIRST_MAKEFILE) + $(MAKE) clean + cd .. +MAKE_FRAG + } + + return $clean; +} + + +=item realclean_subdirs_target + +&& and chdir problem. + +=cut + +sub realclean_subdirs_target { + my $self = shift; + + return <<'NOOP_FRAG' unless @{$self->{DIR}}; +realclean_subdirs : + $(NOECHO)$(NOOP) +NOOP_FRAG + + my $rclean = "realclean_subdirs :\n"; + + foreach my $dir (@{$self->{DIR}}){ + $rclean .= sprintf <<'RCLEAN', $dir; + -cd %s + -$(PERLRUN) -e "exit unless -f shift; system q{$(MAKE) realclean}" $(FIRST_MAKEFILE) + -cd .. +RCLEAN + + } + + return $rclean; +} + + +=item max_exec_len + +Setting to 2500, a value obtained by experimentation. + +=cut + +sub max_exec_len { + my $self = shift; + + return $self->{_MAX_EXEC_LEN} ||= 2500; +} + +=back + + +=head1 AUTHOR + +Code originally inside MM_Win32. Original author unknown. + +Currently maintained by Michael G Schwern . + +Send patches and ideas to >. + +See http://www.makemaker.org. + +=cut + + 1; diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index 901bd13..87a388a 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -57,109 +57,31 @@ sub WriteMakefile { # Basic signatures of the attributes WriteMakefile takes. Each is the # reference type. Empty value indicate it takes a non-reference # scalar. -my %Att_Sigs = -( - ABSTRACT => '', - ABSTRACT_FROM => '', - AUTHOR => '', - BINARY_LOCATION => '', +my %Att_Sigs; +my %Special_Sigs = ( C => 'array', - CCFLAGS => '', CONFIG => 'array', CONFIGURE => 'code', - DEFINE => '', DIR => 'array', - DISTNAME => '', DL_FUNCS => 'hash', DL_VARS => 'array', EXCLUDE_EXT => 'array', EXE_FILES => 'array', - FIRST_MAKEFILE => '', - FULLPERL => '', - FULLPERLRUN => '', - FULLPERLRUNINST => '', FUNCLIST => 'array', H => 'array', IMPORTS => 'hash', - INC => '', INCLUDE_EXT => 'array', - INSTALLARCHLIB => '', - INSTALLBIN => '', - INSTALLDIRS => '', - INSTALLMAN1DIR => '', - INSTALLMAN3DIR => '', - INSTALLPRIVLIB => '', - INSTALLSCRIPT => '', - INSTALLSITEARCH => '', - INSTALLSITEBIN => '', - INSTALLSITELIB => '', - INSTALLSITEMAN1DIR => '', - INSTALLSITEMAN3DIR => '', - INSTALLVENDORARCH => '', - INSTALLVENDORBIN => '', - INSTALLVENDORLIB => '', - INSTALLVENDORMAN1DIR => '', - INSTALLVENDORMAN3DIR => '', - INST_ARCHLIB => '', - INST_BIN => '', - INST_LIB => '', - INST_MAN1DIR => '', - INST_MAN3DIR => '', - INST_SCRIPT => '', - _KEEP_AFTER_FLUSH => '', - LDDLFLAGS => '', - LDFROM => '', - LIB => '', - LIBPERL_A => '', LIBS => ['array',''], - LINKTYPE => '', - MAKEAPERL => '', - MAKEFILE => '', MAN1PODS => 'hash', MAN3PODS => 'hash', - MAP_TARGET => '', - MYEXTLIB => '', - NAME => '', - NEEDS_LINKING => '', - NOECHO => '', - NORECURS => '', - NO_VC => '', - OBJECT => '', - OPTIMIZE => '', - PERL => '', - PERL_CORE => '', - PERLMAINCC => '', - PERL_ARCHLIB => '', - PERL_LIB => '', - PERL_MALLOC_OK => '', - PERLRUN => '', - PERLRUNINST => '', - PERL_SRC => '', - PERM_RW => '', - PERM_RWX => '', PL_FILES => 'hash', PM => 'hash', PMLIBDIRS => 'array', - PM_FILTER => '', - POLLUTE => '', - PPM_INSTALL_EXEC => '', - PPM_INSTALL_SCRIPT => '', - PREFIX => '', - PREREQ_FATAL => '', PREREQ_PM => 'hash', - PREREQ_PRINT => '', - PRINT_PREREQ => '', - SITEPREFIX => '', SKIP => 'array', TYPEMAPS => 'array', - VENDORPREFIX => '', - VERBINST => '', - VERSION => '', - VERSION_FROM => '', XS => 'hash', - XSOPT => '', - XSPROTOARG => '', - XS_VERSION => '', + _KEEP_AFTER_FLUSH => '', clean => 'hash', depend => 'hash', @@ -172,6 +94,9 @@ my %Att_Sigs = tool_autosplit => 'hash', ); +@Att_Sigs{keys %Recognized_Att_Keys} = ('') x keys %Recognized_Att_Keys; +@Att_Sigs{keys %Special_Sigs} = values %Special_Sigs; + sub _verify_att { my($att) = @_; @@ -198,17 +123,24 @@ sub _verify_att { } sub prompt ($;$) { - my($mess,$def)=@_; - $ISA_TTY = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ; # Pipe? + my($mess, $def) = @_; Carp::confess("prompt function called without an argument") unless defined $mess; + + my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ; + my $dispdef = defined $def ? "[$def] " : " "; $def = defined $def ? $def : ""; - my $ans; + local $|=1; local $\; print "$mess $dispdef"; - if ($ISA_TTY && !$ENV{PERL_MM_USE_DEFAULT}) { + + my $ans; + if ($ENV{PERL_MM_USE_DEFAULT} || (!$isa_tty && eof STDIN)) { + print "$def\n"; + } + else { $ans = ; if( defined $ans ) { chomp $ans; @@ -217,9 +149,7 @@ sub prompt ($;$) { print "\n"; } } - else { - print "$def\n"; - } + return (!defined $ans || $ans eq '') ? $def : $ans; } @@ -256,22 +186,24 @@ sub eval_in_x { } } + +# package name for the classes into which the first object will be blessed +my $PACKNAME = 'PACK000'; + sub full_setup { $Verbose ||= 0; - # package name for the classes into which the first object will be blessed - $PACKNAME = "PACK000"; - my @attrib_help = qw/ AUTHOR ABSTRACT ABSTRACT_FROM BINARY_LOCATION C CAPI CCFLAGS CONFIG CONFIGURE DEFINE DIR DISTNAME DL_FUNCS DL_VARS - EXCLUDE_EXT EXE_FILES FIRST_MAKEFILE + EXCLUDE_EXT EXE_FILES FIRST_MAKEFILE FULLPERL FULLPERLRUN FULLPERLRUNINST FUNCLIST H IMPORTS INST_ARCHLIB INST_SCRIPT INST_BIN INST_LIB INST_MAN1DIR INST_MAN3DIR INSTALLDIRS - PREFIX SITEPREFIX VENDORPREFIX + DESTDIR PREFIX + PERLPREFIX SITEPREFIX VENDORPREFIX INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN @@ -282,7 +214,8 @@ sub full_setup { PERL_LIB PERL_ARCHLIB SITELIBEXP SITEARCHEXP INC INCLUDE_EXT LDFROM LIB LIBPERL_A LIBS - LINKTYPE MAKEAPERL MAKEFILE MAN1PODS MAN3PODS MAP_TARGET MYEXTLIB + LINKTYPE MAKEAPERL MAKEFILE_OLD MAN1PODS MAN3PODS MAP_TARGET + MYEXTLIB PERL_MALLOC_OK NAME NEEDS_LINKING NOECHO NORECURS NO_VC OBJECT OPTIMIZE PERL PERLMAINCC PERLRUN PERLRUNINST PERL_CORE @@ -310,16 +243,24 @@ sub full_setup { @MM_Sections = qw( - post_initialize const_config constants tool_autosplit tool_xsubpp - tools_other dist macro depend cflags const_loadlibs const_cccmd + post_initialize const_config constants platform_constants + tool_autosplit tool_xsubpp tools_other + + makemakerdflt + + dist macro depend cflags const_loadlibs const_cccmd post_constants pasthru - c_o xs_c xs_o top_targets linkext dlsyms dynamic dynamic_bs + special_targets + c_o xs_c xs_o + top_targets linkext dlsyms dynamic dynamic_bs dynamic_lib static static_lib manifypods processPL installbin subdirs - clean realclean dist_basics dist_core dist_dir dist_test dist_ci + clean_subdirs clean realclean_subdirs realclean + metafile metafile_addtomanifest + dist_basics dist_core distdir dist_test dist_ci install force perldepend makefile staticmake test ppd ); # loses section ordering @@ -352,6 +293,9 @@ sub full_setup { exe_ext full_ar ); + # 5.5.3 doesn't have any concept of vendor libs + push @Get_from_Config, qw( vendorarchexp vendorlibexp ) if $] >= 5.006; + foreach my $item (@attrib_help){ $Recognized_Att_Keys{$item} = 1; } @@ -371,11 +315,6 @@ sub full_setup { MAP_TARGET INST_MAN1DIR INST_MAN3DIR PERL_SRC PERL FULLPERL ); - - my @keep = qw/ - NEEDS_LINKING HAS_LINK_CODE - /; - @Keep_after_flush{@keep} = (1) x @keep; } sub writeMakefile { @@ -402,6 +341,11 @@ sub new { my($class,$self) = @_; my($key); + # Store the original args passed to WriteMakefile() + foreach my $k (keys %$self) { + $self->{ARGS}{$k} = $self->{$k}; + } + if ("@ARGV" =~ /\bPREREQ_PRINT\b/) { require Data::Dumper; print Data::Dumper->Dump([$self->{PREREQ_PM}], [qw(PREREQ_PM)]); @@ -427,10 +371,15 @@ sub new { my(%unsatisfied) = (); foreach my $prereq (sort keys %{$self->{PREREQ_PM}}) { - eval "require $prereq"; + # 5.8.0 has a bug with require Foo::Bar alone in an eval, so an + # extra statement is a workaround. + eval "require $prereq; 0"; my $pr_version = $prereq->VERSION || 0; + # convert X.Y_Z alpha version #s to X.YZ for easier comparisons + $pr_version =~ s/(\d+)\.(\d+)_(\d+)/$1.$2$3/; + if ($@) { warn sprintf "Warning: prerequisite %s %s not found.\n", $prereq, $self->{PREREQ_PM}{$prereq} @@ -484,7 +433,7 @@ sub new { for $key (@Prepend_parent) { next unless defined $self->{PARENT}{$key}; $self->{$key} = $self->{PARENT}{$key}; - unless ($^O eq 'VMS' && $key =~ /PERL$/) { + unless ($Is_VMS && $key =~ /PERL$/) { $self->{$key} = $self->catdir("..",$self->{$key}) unless $self->file_name_is_absolute($self->{$key}); } else { @@ -520,7 +469,16 @@ sub new { ($self->{NAME_SYM} = $self->{NAME}) =~ s/\W+/_/g; - $self->init_main(); + $self->init_main; + $self->init_VERSION; + $self->init_dist; + $self->init_INST; + $self->init_INSTALL; + $self->init_dirscan; + $self->init_xs; + $self->init_PERL; + $self->init_DIRFILESEP; + $self->init_linker; if (! $self->{PERL_SRC} ) { require VMS::Filespec if $Is_VMS; @@ -547,8 +505,8 @@ END } } - $self->init_dirscan(); $self->init_others(); + $self->init_platform(); $self->init_PERM(); my($argv) = neatvalue(\@ARGV); $argv =~ s/^\[/(/; @@ -569,6 +527,8 @@ END END foreach my $key (sort keys %initial_att){ + next if $key eq 'ARGS'; + my($v) = neatvalue($initial_att{$key}); $v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/; $v =~ tr/\n/ /s; @@ -583,6 +543,7 @@ END END if (scalar(keys %configure_att) > 0) { foreach my $key (sort keys %configure_att){ + next if $key eq 'ARGS'; my($v) = neatvalue($configure_att{$key}); $v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/; $v =~ tr/\n/ /s; @@ -604,7 +565,7 @@ END delete $self->{SKIP}; # free memory if ($self->{PARENT}) { - for (qw/install dist dist_basics dist_core dist_dir dist_test dist_ci/) { + for (qw/install dist dist_basics dist_core distdir dist_test dist_ci/) { $self->{SKIPHASH}{$_} = 1; } } @@ -616,6 +577,10 @@ END } foreach my $section ( @MM_Sections ){ + # Support for new foo_target() methods. + my $method = $section; + $method .= '_target' unless $self->can($method); + print "Processing Makefile '$section' section\n" if ($Verbose >= 2); my($skipit) = $self->skipcheck($section); if ($skipit){ @@ -624,7 +589,7 @@ END my(%a) = %{$self->{$section} || {}}; push @{$self->{RESULT}}, "\n# --- MakeMaker $section section:"; push @{$self->{RESULT}}, "# " . join ", ", %a if $Verbose && %a; - push @{$self->{RESULT}}, $self->nicetext($self->$section( %a )); + push @{$self->{RESULT}}, $self->nicetext($self->$method( %a )); } } @@ -638,13 +603,14 @@ sub WriteEmptyMakefile { my %att = @_; my $self = MM->new(\%att); - if (-f "$self->{MAKEFILE}.old") { - chmod 0666, "$self->{MAKEFILE}.old"; - unlink "$self->{MAKEFILE}.old" or warn "unlink $self->{MAKEFILE}.old: $!"; + if (-f $self->{MAKEFILE_OLD}) { + chmod 0666, $self->{MAKEFILE_OLD}; + unlink $self->{MAKEFILE_OLD} or warn "unlink $self->{MAKEFILE_OLD}: $!"; + } + if ( -f $self->{MAKEFILE} ) { + _rename($self->{MAKEFILE}, $self->{MAKEFILE_OLD}) + or warn "rename $self->{MAKEFILE} => $self->{MAKEFILE_OLD}: $!" } - rename $self->{MAKEFILE}, "$self->{MAKEFILE}.old" - or warn "rename $self->{MAKEFILE} $self->{MAKEFILE}.old: $!" - if -f $self->{MAKEFILE}; open MF, '>'.$self->{MAKEFILE} or die "open $self->{MAKEFILE} for write: $!"; print MF <<'EOP'; all: @@ -693,7 +659,9 @@ sub parse_args{ (getpwuid($>))[7] ]ex; } - $self->{uc($name)} = $value; + + # Remember the original args passed it. It will be useful later. + $self->{ARGS}{uc $name} = $self->{uc $name} = $value; } # catch old-style 'potential_libs' and inform user how to 'upgrade' @@ -738,6 +706,7 @@ sub parse_args{ } foreach my $mmkey (sort keys %$self){ + next if $mmkey eq 'ARGS'; print STDOUT " $mmkey => ", neatvalue($self->{$mmkey}), "\n" if $Verbose; print STDOUT "'$mmkey' is not a known MakeMaker parameter name.\n" unless exists $Recognized_Att_Keys{$mmkey}; @@ -749,7 +718,11 @@ sub check_hints { my($self) = @_; # We allow extension-specific hints files. - return unless -d "hints"; + require File::Spec; + my $curdir = File::Spec->curdir; + + my $hint_dir = File::Spec->catdir($curdir, "hints"); + return unless -d $hint_dir; # First we look for the best hintsfile we have my($hint)="${^O}_$Config{osvers}"; @@ -759,11 +732,11 @@ sub check_hints { # Also try without trailing minor version numbers. while (1) { - last if -f "hints/$hint.pl"; # found + last if -f File::Spec->catfile($hint_dir, "$hint.pl"); # found } continue { last unless $hint =~ s/_[^_]*$//; # nothing to cut off } - my $hint_file = "hints/$hint.pl"; + my $hint_file = File::Spec->catfile($hint_dir, "$hint.pl"); return unless -f $hint_file; # really there @@ -775,11 +748,16 @@ sub _run_hintfile { local($self) = shift; # make $self available to the hint file. my($hint_file) = shift; - local $@; + local($@, $!); print STDERR "Processing hints file $hint_file\n"; - my $ret = do "./$hint_file"; - unless( defined $ret ) { - print STDERR $@ if $@; + + # Just in case the ./ isn't on the hint file, which File::Spec can + # often strip off, we bung the curdir into @INC + local @INC = (File::Spec->curdir, @INC); + my $ret = do $hint_file; + if( !defined $ret ) { + my $error = $@ || $!; + print STDERR $error; } } @@ -883,18 +861,31 @@ sub flush { close FH; my($finalname) = $self->{MAKEFILE}; - rename("MakeMaker.tmp", $finalname); + _rename("MakeMaker.tmp", $finalname) or + warn "rename MakeMaker.tmp => $finalname: $!"; chmod 0644, $finalname unless $Is_VMS; + my %keep = map { ($_ => 1) } qw(NEEDS_LINKING HAS_LINK_CODE); + if ($self->{PARENT} && !$self->{_KEEP_AFTER_FLUSH}) { foreach (keys %$self) { # safe memory - delete $self->{$_} unless $Keep_after_flush{$_}; + delete $self->{$_} unless $keep{$_}; } } system("$Config::Config{eunicefix} $finalname") unless $Config::Config{eunicefix} eq ":"; } + +# This is a rename for OS's where the target must be unlinked first. +sub _rename { + my($src, $dest) = @_; + chmod 0666, $dest; + unlink $dest; + return rename $src, $dest; +} + + # The following mkbootstrap() is only for installations that are calling # the pre-4.1 mkbootstrap() from their old Makefiles. This MakeMaker # writes Makefiles, that use ExtUtils::Mkbootstrap directly. @@ -961,7 +952,7 @@ __END__ =head1 NAME -ExtUtils::MakeMaker - create an extension Makefile +ExtUtils::MakeMaker - Create a module Makefile =head1 SYNOPSIS @@ -986,24 +977,7 @@ Makefiles with a single invocation of WriteMakefile(). =head2 How To Write A Makefile.PL -The short answer is: Don't. - - Always begin with h2xs. - Always begin with h2xs! - ALWAYS BEGIN WITH H2XS! - -even if you're not building around a header file, and even if you -don't have an XS component. - -Run h2xs(1) before you start thinking about writing a module. For so -called pm-only modules that consist of C<*.pm> files only, h2xs has -the C<-X> switch. This will generate dummy files of all kinds that are -useful for the module developer. - -The medium answer is: - - use ExtUtils::MakeMaker; - WriteMakefile( NAME => "Foo::Bar" ); +See ExtUtils::MakeMaker::Tutorial. The long answer is the rest of the manpage :-) @@ -1077,7 +1051,7 @@ INSTALLDIRS according to the following table: INSTALLDIRS set to perl site vendor - PREFIX SITEPREFIX VENDORPREFIX + PERLPREFIX SITEPREFIX VENDORPREFIX INST_ARCHLIB INSTALLARCHLIB INSTALLSITEARCH INSTALLVENDORARCH INST_LIB INSTALLPRIVLIB INSTALLSITELIB INSTALLVENDORLIB INST_BIN INSTALLBIN INSTALLSITEBIN INSTALLVENDORBIN @@ -1357,6 +1331,17 @@ be determined by some evaluation method. Something like C<"-DHAVE_UNISTD_H"> +=item DESTDIR + +This is the root directory into which the code will be installed. It +I. For example, if your code +would normally go into /usr/local/lib/perl you could set DESTDIR=/tmp +and installation would go into /tmp/usr/local/lib/perl. + +This is primarily of use for people who repackage Perl modules. + +From the GNU Makefile conventions. + =item DIR Ref to array of subdirectories containing Makefile.PLs e.g. [ 'sdbm' @@ -1364,8 +1349,24 @@ Ref to array of subdirectories containing Makefile.PLs e.g. [ 'sdbm' =item DISTNAME -Your name for distributing the package (by tar file). This defaults to -NAME above. +A safe filename for the package. + +Defaults to NAME above but with :: replaced with -. + +For example, Foo::Bar becomes Foo-Bar. + +=item DISTVNAME + +Your name for distributing the package with the version number +included. This is used by 'make dist' to name the resulting archive +file. + +Defaults to DISTNAME-VERSION. + +For example, version 1.04 of Foo::Bar becomes Foo-Bar-1.04. + +On some OS's where . has special meaning VERSION_SYM may be used in +place of VERSION. =item DL_FUNCS @@ -1409,9 +1410,13 @@ again. =item FIRST_MAKEFILE -The name of the Makefile to be produced. Defaults to the contents of -MAKEFILE, but can be overridden. This is used for the second Makefile -that will be produced for the MAP_TARGET. +The name of the Makefile to be produced. This is used for the second +Makefile that will be produced for the MAP_TARGET. + +Defaults to 'Makefile' or 'Descrip.MMS' on VMS. + +(Note: we couldn't use MAKEFILE because dmake uses this for something +else). =item FULLPERL @@ -1576,6 +1581,12 @@ Directory, where executable files should be installed during testing. make install will copy the files in INST_SCRIPT to INSTALLSCRIPT. +=item LD + +Program to be used to link libraries for dynamic loading. + +Defaults to $Config{ld}. + =item LDDLFLAGS Any special flags that might need to be passed to ld to create a @@ -1636,9 +1647,12 @@ Boolean which tells MakeMaker, that it should include the rules to make a perl. This is handled automatically as a switch by MakeMaker. The user normally does not need it. -=item MAKEFILE +=item MAKEFILE_OLD + +When 'make clean' or similar is run, the $(FIRST_MAKEFILE) will be +backed up at this location. -The name of the Makefile to be produced. +Defaults to $(FIRST_MAKEFILE).old or $(FIRST_MAKEFILE)_old on VMS. =item MAN1PODS @@ -1680,9 +1694,12 @@ this boolean variable yourself. =item NOECHO -Defaults to C<@>. By setting it to an empty string you can generate a -Makefile that echos all commands. Mainly used in debugging MakeMaker -itself. +Command so make does not print the literal commands its running. + +By setting it to an empty string you can generate a Makefile that +prints all commands. Mainly used in debugging MakeMaker itself. + +Defaults to C<@>. =item NORECURS @@ -1766,6 +1783,16 @@ nullifies many advantages of Perl's malloc(), such as better usage of system resources, error detection, memory usage reporting, catchable failure of memory allocations, etc. +=item PERLPREFIX + +Directory under which core modules are to be installed. + +Defaults to $Config{installprefixexp} falling back to +$Config{installprefix}, $Config{prefixexp} or $Config{prefix} should +$Config{installprefixexp} not exist. + +Overridden by PREFIX. + =item PERLRUN Use this instead of $(PERL) when you wish to run perl. It will set up @@ -1882,8 +1909,6 @@ which should be sensible for your platform. If you specify LIB or any INSTALL* variables they will not be effected by the PREFIX. -Defaults to $Config{installprefixexp}. - =item PREREQ_FATAL Bool. If this parameter is true, failing to have the required modules @@ -1924,11 +1949,13 @@ RedHatism for C. The output format is different, though: =item SITEPREFIX -Like PREFIX, but only for the site install locations. +Like PERLPREFIX, but only for the site install locations. + +Defaults to $Config{siteprefixexp}. Perls prior to 5.6.0 didn't have +an explicit siteprefix in the Config. In those cases +$Config{installprefix} will be used. -Defaults to PREFIX (if set) or $Config{siteprefixexp}. Perls prior to -5.6.0 didn't have an explicit siteprefix in the Config. In those -cases $Config{installprefix} will be used. +Overridable by PREFIX =item SKIP @@ -1948,9 +1975,11 @@ typemap has lowest precedence. =item VENDORPREFIX -Like PREFIX, but only for the vendor install locations. +Like PERLPREFIX, but only for the vendor install locations. + +Defaults to $Config{vendorprefixexp}. -Defaults to PREFIX (if set) or $Config{vendorprefixexp} +Overridable by PREFIX =item VERBINST @@ -2001,6 +2030,11 @@ would have to do something like See attribute C below. +=item VERSION_SYM + +A sanitized VERSION with . replaced by _. For places where . has +special meaning (some filesystems, RCS labels, etc...) + =item XS Hashref of .xs files. MakeMaker will default this. e.g. @@ -2293,9 +2327,33 @@ in a subdirectory of some other distribution, or is listed as a dependency in a CPAN::Bundle, but the functionality is supported by different means on the current architecture). +=head2 Other Handy Functions + +=over 4 + +=item prompt + + my $value = prompt($message); + my $value = prompt($message, $default); + +The C function provides an easy way to request user input +used to write a makefile. It displays the $message as a prompt for +input. If a $default is provided it will be used as a default. The +function returns the $value selected by the user. + +If C detects that it is not running interactively and there +is nothing on STDIN or if the PERL_MM_USE_DEFAULT environment variable +is set to true, the $default will be used without prompting. This +prevents automated processes from blocking on user input. + +If no $default is provided an empty string will be used instead. + +=back + + =head1 ENVIRONMENT -=over 8 +=over 4 =item PERL_MM_OPT @@ -2331,4 +2389,12 @@ generated Makefile along with your report. For more up-to-date information, see http://www.makemaker.org. +=head1 LICENSE + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +See F + + =cut diff --git a/lib/ExtUtils/MakeMaker/FAQ.pod b/lib/ExtUtils/MakeMaker/FAQ.pod new file mode 100644 index 0000000..6d7ba70 --- /dev/null +++ b/lib/ExtUtils/MakeMaker/FAQ.pod @@ -0,0 +1,199 @@ +package ExtUtils::MakeMaker::FAQ; + +our $VERSION = '0.02'; + +1; +__END__ + +=head1 NAME + +ExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker + +=head1 DESCRIPTION + +FAQs, tricks and tips for C. + +=head2 Philosophy and History + +=over 4 + +=item Why not just use ? + +Why did MakeMaker reinvent the build configuration wheel? Why not +just use autoconf or automake or ppm or Ant or ... + +There are many reasons, but the major one is cross-platform +compatibility. + +Perl is one of the most ported pieces of software ever. It works on +operating systems I've never even heard of (see perlport for details). +It needs a build tool that can work on all those platforms and with +any wacky C compilers they might have. + +No such build tool existed at the time and I only know of one now +(Module::Build). + + +=item What's Module::Build and how does it relate to MakeMaker? + +Module::Build is a project by Ken Williams to supplant MakeMaker. +Its primary advantages are: + +=over 8 + +=item * pure perl. no make, no shell commands + +=item * easier to customize + +=item * cleaner internals + +=item * less cruft + +=back + +Module::Build is the official heir apparent to MakeMaker and we +encourage people to work on M::B rather than spending time improving +MakeMaker. + +=back + +=head2 XS + +=over 4 + +=item How do I make two or more XS files coexist in the same directory? + +Sometimes you need to have two and more XS files in the same package. +One way to go is to put them into separate directories, but sometimes +this is not the most suitable solution. The following technique allows +you to put two (and more) XS files in the same directory. + +Let's assume that we have a package C, which includes +C and C modules each having a separate XS +file. First we use the following I: + + use ExtUtils::MakeMaker; + + WriteMakefile( + NAME => 'Cool::Foo', + VERSION_FROM => 'Foo.pm', + OBJECT => q/$(O_FILES)/, + # ... other attrs ... + ); + +Notice the C attribute. MakeMaker generates the following +variables in I: + + # Handy lists of source code files: + XS_FILES= Bar.xs \ + Foo.xs + C_FILES = Bar.c \ + Foo.c + O_FILES = Bar.o \ + Foo.o + +Therefore we can use the C variable to tell MakeMaker to use +these objects into the shared library. + +That's pretty much it. Now write I and I, I +and I, where I bootstraps the shared library and +I simply loading I. + +The only issue left is to how to bootstrap I. This is done +from I: + + MODULE = Cool::Foo PACKAGE = Cool::Foo + + BOOT: + # boot the second XS file + boot_Cool__Bar(aTHX_ cv); + +If you have more than two files, this is the place where you should +boot extra XS files from. + +The following four files sum up all the details discussed so far. + + Foo.pm: + ------- + package Cool::Foo; + + require DynaLoader; + + our @ISA = qw(DynaLoader); + our $VERSION = '0.01'; + bootstrap Cool::Foo $VERSION; + + 1; + + Bar.pm: + ------- + package Cool::Bar; + + use Cool::Foo; # bootstraps Bar.xs + + 1; + + Foo.xs: + ------- + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + MODULE = Cool::Foo PACKAGE = Cool::Foo + + BOOT: + # boot the second XS file + boot_Cool__Bar(aTHX_ cv); + + MODULE = Cool::Foo PACKAGE = Cool::Foo PREFIX = cool_foo_ + + void + cool_foo_perl_rules() + + CODE: + fprintf(stderr, "Cool::Foo says: Perl Rules\n"); + + Bar.xs: + ------- + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + MODULE = Cool::Bar PACKAGE = Cool::Bar PREFIX = cool_bar_ + + void + cool_bar_perl_rules() + + CODE: + fprintf(stderr, "Cool::Bar says: Perl Rules\n"); + +And of course a very basic test: + + test.pl: + -------- + use Test; + BEGIN { plan tests => 1 }; + use Cool::Foo; + use Cool::Bar; + Cool::Foo::perl_rules(); + Cool::Bar::perl_rules(); + ok 1; + +This tip has been brought to you by Nick Ing-Simmons and Stas Bekman. + +=back + +=head1 PATCHING + +If you have a question you'd like to see added to the FAQ (whether or +not you have the answer) please send it to makemaker@perl.org. + +=head1 AUTHOR + +The denizens of makemaker@perl.org. + +=head1 SEE ALSO + +L + +=cut diff --git a/lib/ExtUtils/MakeMaker/Tutorial.pod b/lib/ExtUtils/MakeMaker/Tutorial.pod new file mode 100644 index 0000000..bbc794a --- /dev/null +++ b/lib/ExtUtils/MakeMaker/Tutorial.pod @@ -0,0 +1,124 @@ +package ExtUtils::MakeMaker::Tutorial; + +use vars qw($VERSION); +$VERSION = 0.01; + + +=head1 NAME + +ExtUtils::MakeMaker::Tutorial - Writing a module with MakeMaker + +=head1 SYNOPSIS + + use ExtUtils::MakeMaker; + + WriteMakefile( + NAME => 'Your::Module', + VERSION_FROM => 'lib/Your/Module.pm' + ); + +=head1 DESCRIPTION + +This is a short tutorial on writing a simple module with MakeMaker. + +=head2 The Mantra + +MakeMaker modules are installed using this simple mantra + + perl Makefile.PL + make + make test + make install + +There are lots more commands and options, but the above will do it. + +=head2 The Layout + +The basic layout of a module looks something like this. + + Makefile.PL + MANIFEST + lib/Your/Module.pm + +That's all that's strictly necessary. There's additional files you might +want to add: + + lib/Your/Other/Module.pm + t/some_test.t + t/some_other_test.t + Changes + README + INSTALL + MANIFEST.SKIP + bin/some_program + +=over 4 + +=item Makefile.PL + +When you run Makefile.PL, it makes a Makefile. That's the whole point of +MakeMaker. The Makefile.PL is a simple module which loads +ExtUtils::MakeMaker and runs the WriteMakefile() function with a few +simple arguments. + +Here's an example of what you need for a simple module: + + use ExtUtils::MakeMaker; + + WriteMakefile( + NAME => 'Your::Module', + VERSION_FROM => 'lib/Your/Module.pm' + ); + +NAME is the top-level namespace of your module. VERSION_FROM is the file +which contains the $VERSION variable for the entire distribution. Typically +this is the same as your top-level module. + + +=item MANIFEST + +A simple listing of all the files in your distribution. + + Makefile.PL + MANIFEST + lib/Your/Module.pm + + +=item lib/ + +This is the directory where your .pm files go. They are layed out +according to namespace. So Foo::Bar is lib/Foo/Bar.pm. + + +=item t/ + +Tests for your modules go here. Each test filename ends with a .t. +So t/foo.t. 'make test' will run these tests. The directory is flat, +you cannot, for example, have t/foo/bar.t run by 'make test'. + + +=item Changes + +A log of changes you've made to this module. + + +=item README + +=item INSTALL + +=item MANIFEST.SKIP + +=item bin/ + +=back + +=head1 SEE ALSO + +L gives stylistic help writing a module. + +There are modules to help you through the process of writing a module: +L, L, L + +=cut + +1; diff --git a/lib/ExtUtils/MakeMaker/vmsish.pm b/lib/ExtUtils/MakeMaker/vmsish.pm new file mode 100644 index 0000000..5380ba5 --- /dev/null +++ b/lib/ExtUtils/MakeMaker/vmsish.pm @@ -0,0 +1,40 @@ +package ExtUtils::MakeMaker::vmsish; + +use vars qw($VERSION); +$VERSION = 0.01; + +my $IsVMS = $^O eq 'VMS'; + +require vmsish if $IsVMS; + + +sub import { + return unless $IsVMS; + + shift; + unshift @_, 'vmsish'; + + goto &vmsish::import; +} + +1; + + +=head1 NAME + +ExtUtils::MakeMaker::vmsish - Platform agnostic vmsish.pm + +=head1 SYNOPSIS + + use just like vmsish.pm + +=head1 DESCRIPTION + +Until 5.8.0, vmsish.pm is only installed on VMS. This means any code +which has 'use vmsish' in it won't even compile outside VMS. This +makes ExtUtils::MM_VMS very hard to test. + +ExtUtils::MakeMaker::vmsish is just a very thin wrapper around vmsish +which works just like it on VMS and everywhere else it does nothing. + +=cut diff --git a/lib/ExtUtils/Manifest.pm b/lib/ExtUtils/Manifest.pm index 7ca5bdd..df4cb9e 100644 --- a/lib/ExtUtils/Manifest.pm +++ b/lib/ExtUtils/Manifest.pm @@ -14,21 +14,78 @@ use vars qw($VERSION @ISA @EXPORT_OK $VERSION = 1.38; @ISA=('Exporter'); -@EXPORT_OK = ('mkmanifest', 'manicheck', 'fullcheck', 'filecheck', - 'skipcheck', 'maniread', 'manicopy'); +@EXPORT_OK = qw(mkmanifest + manicheck filecheck fullcheck skipcheck + manifind maniread manicopy maniadd + ); $Is_MacOS = $^O eq 'MacOS'; -$Is_VMS = $^O eq 'VMS'; +$Is_VMS = $^O eq 'VMS'; require VMS::Filespec if $Is_VMS; -$Debug = $ENV{PERL_MM_MANIFEST_DEBUG} || 0; +$Debug = $ENV{PERL_MM_MANIFEST_DEBUG} || 0; $Verbose = defined $ENV{PERL_MM_MANIFEST_VERBOSE} ? $ENV{PERL_MM_MANIFEST_VERBOSE} : 1; $Quiet = 0; $MANIFEST = 'MANIFEST'; -$DEFAULT_MSKIP = (File::Spec->splitpath($INC{"ExtUtils/Manifest.pm"}))[1]. + +my $manifest_mod = $INC{"ExtUtils/Manifest.pm"} || + ($Is_VMS ? $INC{'extutils/manifest.pm'} : ''); +$DEFAULT_MSKIP = (File::Spec->splitpath($manifest_mod))[1]. "$MANIFEST.SKIP"; + +=head1 NAME + +ExtUtils::Manifest - utilities to write and check a MANIFEST file + +=head1 SYNOPSIS + + use ExtUtils::Manifest qw(...funcs to import...); + + mkmanifest(); + + my @missing_files = manicheck; + my @skipped = skipcheck; + my @extra_files = filecheck; + my($missing, $extra) = fullcheck; + + my $found = manifind(); + + my $manifest = maniread(); + + manicopy($read,$target); + + maniadd({$file => $comment, ...}); + + +=head1 DESCRIPTION + +=head2 Functions + +ExtUtils::Manifest exports no functions by default. The following are +exported on request + +=over 4 + +=item mkmanifest + + mkmanifest(); + +Writes all files in and below the current directory to your F. +It works similar to + + find . > MANIFEST + +All files that match any regular expression in a file F +(if it exists) are ignored. + +Any existing F file will be saved as F. Lines +from the old F file is preserved, including any comments +that are found in the existing F file in the new one. + +=cut + sub mkmanifest { my $manimiss = 0; my $read = (-r 'MANIFEST' && maniread()) or $manimiss++; @@ -72,6 +129,16 @@ sub clean_up_filename { return $filename; } + +=item manifind + + my $found = manifind(); + +returns a hash reference. The keys of the hash are the files found +below the current directory. + +=cut + sub manifind { my $p = shift || {}; my $found = {}; @@ -98,18 +165,66 @@ sub manifind { return $found; } -sub fullcheck { - return [_check_files()], [_check_manifest()]; -} + +=item manicheck + + my @missing_files = manicheck(); + +checks if all the files within a C in the current directory +really do exist. If C and the tree below the current +directory are in sync it exits silently, returning an empty list. +Otherwise it returns a list of files which are listed in the +C but missing from the directory, and by default also +outputs these names to STDERR. + +=cut sub manicheck { return _check_files(); } + +=item filecheck + + my @extra_files = filecheck(); + +finds files below the current directory that are not mentioned in the +C file. An optional file C will be +consulted. Any file matching a regular expression in such a file will +not be reported as missing in the C file. The list of any +extraneous files found is returned, and by default also reported to +STDERR. + +=cut + sub filecheck { return _check_manifest(); } + +=item fullcheck + + my($missing, $extra) = fullcheck(); + +does both a manicheck() and a filecheck(), returning then as two array +refs. + +=cut + +sub fullcheck { + return [_check_files()], [_check_manifest()]; +} + + +=item skipcheck + + my @skipped = skipcheck(); + +lists all the files that are skipped due to your C +file. + +=cut + sub skipcheck { my($p) = @_; my $found = manifind(); @@ -173,6 +288,18 @@ sub _check_manifest { } +=item maniread + + my $manifest = maniread(); + my $manifest = maniread($manifest_file); + +reads a named C file (defaults to C in the current +directory) and returns a HASH reference with files being the keys and +comments being the values of the HASH. Blank lines and lines which +start with C<#> in the C file are discarded. + +=cut + sub maniread { my ($mfile) = @_; $mfile ||= $MANIFEST; @@ -234,6 +361,23 @@ sub _maniskip { return sub { $_[0] =~ qr{$opts$regex} }; } +=item manicopy + + manicopy($src, $dest_dir); + manicopy($src, $dest_dir, $how); + +copies the files that are the keys in the HASH I<%$src> to the +$dest_dir. The HASH reference $read is typically returned by the +maniread() function. This function is useful for producing a directory +tree identical to the intended distribution tree. The third parameter +$how can be used to specify a different methods of "copying". Valid +values are C, which actually copies the files, C which creates +hard links, and C which mostly links the files but copies any +symbolic link to make a tree without any symbolic link. Best is the +default. + +=cut + sub manicopy { my($read,$target,$how)=@_; croak "manicopy() called without target argument" unless defined $target; @@ -372,90 +516,48 @@ sub _unmacify { $file; } -1; - -__END__ - -=head1 NAME - -ExtUtils::Manifest - utilities to write and check a MANIFEST file - -=head1 SYNOPSIS - - require ExtUtils::Manifest; - - ExtUtils::Manifest::mkmanifest; - ExtUtils::Manifest::manicheck; +=item maniadd - ExtUtils::Manifest::filecheck; + maniadd({ $file => $comment, ...}); - ExtUtils::Manifest::fullcheck; +Adds an entry to an existing F. - ExtUtils::Manifest::skipcheck; +$file will be normalized (ie. Unixified). B - ExtUtils::Manifest::manifind(); +=cut - ExtUtils::Manifest::maniread($file); +sub maniadd { + my($additions) = shift; - ExtUtils::Manifest::manicopy($read,$target,$how); + _normalize($additions); -=head1 DESCRIPTION + my $manifest = maniread(); + open(MANIFEST, ">>$MANIFEST") or die "Could not open $MANIFEST: $!"; + while( my($file, $comment) = each %$additions ) { + $comment ||= ''; + printf MANIFEST "%-40s%s\n", $file, $comment unless + exists $manifest->{$file}; + } + close MANIFEST; +} -mkmanifest() writes all files in and below the current directory to a -file named in the global variable $ExtUtils::Manifest::MANIFEST (which -defaults to C) in the current directory. It works similar to - - find . -print - -but in doing so checks each line in an existing C file and -includes any comments that are found in the existing C file -in the new one. Anything between white space and an end of line within -a C file is considered to be a comment. Filenames and -comments are separated by one or more TAB characters in the -output. All files that match any regular expression in a file -C (if such a file exists) are ignored. - -manicheck() checks if all the files within a C in the current -directory really do exist. If C and the tree below the current -directory are in sync it exits silently, returning an empty list. Otherwise -it returns a list of files which are listed in the C but missing -from the directory, and by default also outputs these names to STDERR. - -filecheck() finds files below the current directory that are not -mentioned in the C file. An optional file C -will be consulted. Any file matching a regular expression in such a -file will not be reported as missing in the C file. The list of -any extraneous files found is returned, and by default also reported to -STDERR. +# UNIMPLEMENTED +sub _normalize { + return; +} -fullcheck() does both a manicheck() and a filecheck(), returning references -to two arrays, the first for files manicheck() found to be missing, the -seond for unexpeced files found by filecheck(). -skipcheck() lists all the files that are skipped due to your -C file. +=back -manifind() returns a hash reference. The keys of the hash are the -files found below the current directory. +=head2 MANIFEST -maniread($file) reads a named C file (defaults to -C in the current directory) and returns a HASH reference -with files being the keys and comments being the values of the HASH. -Blank lines and lines which start with C<#> in the C file -are discarded. +Anything between white space and an end of line within a C +file is considered to be a comment. Filenames and comments are +separated by one or more TAB characters in the output. -C copies the files that are the keys in -the HASH I<%$read> to the named target directory. The HASH reference -$read is typically returned by the maniread() function. This -function is useful for producing a directory tree identical to the -intended distribution tree. The third parameter $how can be used to -specify a different methods of "copying". Valid values are C, -which actually copies the files, C which creates hard links, and -C which mostly links the files but copies any symbolic link to -make a tree without any symbolic link. Best is the default. -=head1 MANIFEST.SKIP +=head2 MANIFEST.SKIP The file MANIFEST.SKIP may contain regular expressions of files that should be ignored by mkmanifest() and filecheck(). The regular @@ -467,6 +569,7 @@ expression to start with a sharp character. A typical example: \bRCS\b \bCVS\b ,v$ + \B\.svn\b # Makemaker generated files and dirs. ^MANIFEST\. @@ -485,12 +588,12 @@ used, similar to the example above. If you want nothing skipped, simply make an empty MANIFEST.SKIP file. -=head1 EXPORT_OK +=head2 EXPORT_OK C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>, C<&maniread>, and C<&manicopy> are exportable. -=head1 GLOBAL VARIABLES +=head2 GLOBAL VARIABLES C<$ExtUtils::Manifest::MANIFEST> defaults to C. Changing it results in both a different C and a different @@ -554,3 +657,5 @@ L which has handy targets for most of the functionality. Andreas Koenig > =cut + +1; diff --git a/lib/ExtUtils/NOTES b/lib/ExtUtils/NOTES new file mode 100644 index 0000000..837167c --- /dev/null +++ b/lib/ExtUtils/NOTES @@ -0,0 +1,102 @@ +The Simplified MakeMaker class hierarchy +**************************************** + +What most people need to know. + +(Subclasses on top.) + + MY + | + ExtUtils::MakeMaker + | + ExtUtils::MM_{Current OS} + | + ExtUtils::MM_Unix + | + ExtUtils::MM_Any + +The object actually used is of the class MY which allows you to +override bits of MakeMaker inside your Makefile.PL by declaring +MY::foo() methods. + + +The Real MakeMaker class hierarchy +********************************** + +You wish it was that simple. + +Here's how it really works. + + PACK### (created each call to ExtUtils::MakeMaker->new) + . | + (mixin) | + . | + MY (created by ExtUtils::MY) | + | | + ExtUtils::MY MM (created by ExtUtils::MM) + | | | + ExtUtils::MM ExtUtils::MM_{Current OS} + | | . + | | + ExtUtils::Liblist ExtUtils::MakeMaker . + | + ExtUtils::Liblist::Kid . + + (variable subclass) + + . + + ExtUtils::MM_{NonUnix}. . . . . . . . . . . . . . . . + | + ExtUtils::MM_Unix . . . . . . . . . . . . . . . . . . + | + ExtUtils::MM_Any + + +NOTE: Yes, this is a mess. See +http://archive.develooper.com/makemaker@perl.org/msg00134.html +for some history. + +NOTE: When ExtUtils::MM is loaded it chooses a superclass for MM from +amongst the ExtUtils::MM_* modules based on the current operating +system. + +NOTE: ExtUtils::MM_{Current OS} represents one of the ExtUtils::MM_* +modules except ExtUtils::MM_Any. + +NOTE: ExtUtils::MM_{NonUnix} represents all of the ExtUtils::MM_* +modules except ExtUtils::MM_Any and ExtUtils::MM_Unix. + +NOTE: The main object used by MakeMaker is a PACK### object, *not* +ExtUtils::MakeMaker. It is, effectively, a subclass of MY, +ExtUtils::Makemaker, ExtUtils::Liblist and an ExtUtils::MM_* class +appropriate for your operating system. + +NOTE: The methods in MY are simply copied into PACK### rather than +MY being a superclass of PACK###. I don't remember the rationale. + +NOTE: ExtUtils::Liblist should be removed from the inheritence hiearchy +and simply be called as functions. + +NOTE: Modules like File::Spec and Exporter have been omitted for clarity. + + +The MM_* hierarchy +****************** + + MM_Win95 MM_NW5 + \ / +MM_BeOS MM_Cygwin MM_OS2 MM_VMS MM_Win32 MM_DOS MM_MacOS MM_UWIN + \ | | | / / / / + --------------------------------------------------------- + | | + MM_Unix | + | | + MM_Any + +NOTE: Each direct MM_Unix subclass is also an MM_Any subclass. This +is a temporary hack because MM_Unix overrides some MM_Any methods with +Unix specific code. It allows the non-Unix modules to see the +original MM_Any implementations. + +NOTE: Modules like File::Spec and Exporter have been omitted for clarity. diff --git a/lib/ExtUtils/PATCHING b/lib/ExtUtils/PATCHING new file mode 100644 index 0000000..2170be2 --- /dev/null +++ b/lib/ExtUtils/PATCHING @@ -0,0 +1,155 @@ +This is a short set of guidelines for those patching +ExtUtils::MakeMaker. Its not an iron-clad set of rules, but just +things which make life easier when reading and integrating a patch. + +Lots of information can be found in makemaker.org. + +MakerMaker is being maintained until something else can replace it. +Bugs will be fixed and compatibility improved, but I would like to +avoid new features. If you want to add something to MakeMaker, +consider instead working on Module::Build, MakeMaker's heir apparent. + + +Patching details + +- Please use unified diffs. (diff -u) + +- Patches against the latest development snapshot from makemaker.org are + preferred. Patches against the latest CPAN version are ok, too. + +- Post your patch to makemaker@perl.org. + + +Code formatting + +- No literal tabs (except where necessary inside Makefile code, obviously). + +- 4 character indentation. + +- this_style is prefered instead of studlyCaps. + +- Private subroutine names (ie. those used only in the same package + they're declared in) should start with an underscore (_sekret_method). + +- Protected subroutines (ie. ones intended to be used by other modules in + ExtUtils::*) should be named normally (no leading underscore) but + documented as protected (see Documentation below). + +- Do not use indirect object syntax (ie. new Foo::Bar (@args)) + +- make variables use dollar signs like Perl scalars. This causes problems + when you have to mix them both in a string. If you find yourself + backwacking lots of dollar signs because you have one interpolated + perl variable, like this: + + return <<'EOT' + +subdirs :: + \$(NOECHO)cd $subdir && \$(MAKE) -f \$(FIRST_MAKEFILE) all \$(PASTHRU) +EOT + + or are switching quoting contexts: + + return <_foo_bar + + Blah blah blah + + =end private + + =cut + + sub _foo_bar { + ... + +- If you're overriding a method, document that its an override and + *why* its being overridden. Don't repeat the original documentation. diff --git a/lib/ExtUtils/README b/lib/ExtUtils/README new file mode 100644 index 0000000..95f66e9 --- /dev/null +++ b/lib/ExtUtils/README @@ -0,0 +1,28 @@ +This is a CPAN distribution of the venerable MakeMaker module. + + +PLEASE NOTE: This distribution does not include the xsubpp or typemap +programs. They are extremely specific to your version or Perl, so +MakeMaker will simply use the one which came with your copy of Perl. +Do not delete your old ExtUtils/ directory. + + +Known Problems: + +(See http://rt.cpan.org for a full list of open problems.) + +ActivePerl likely broken if installed in C:\Program Files or other +prefix with a space in the name. + +manifypods target produces command lines too long for some systems + +Using the MMS utility on VMS causes lots of extra newlines. Unknown +why this is so, might be a bug in MMS. Problem not seen with MMK. + +ActivePerl/Win95 disttest produces "File creation error" from somewhere +in running Makefile.PL after check_manifest() is run. Don't know why. + + +See TODO for details. + +Please report any bugs via http://rt.cpan.org or to makemaker@perl.org. diff --git a/lib/ExtUtils/TODO b/lib/ExtUtils/TODO new file mode 100644 index 0000000..342ce9e --- /dev/null +++ b/lib/ExtUtils/TODO @@ -0,0 +1,49 @@ +Rethink MM_Win32 tests. + +Investigate one method per make target. + +Test MM_Any and pull some redundant tests out of MM_*.t + +Create a way to init MM objects. (XXX What's wrong with MakeMaker->new?) + +Move instmodsh to utils/ in the core. + +Handle config files (ie. /etc) and their special PREFIX needs +(ie. PREFIX=/usr, INSTALLCONFIGDIR=/etc). + +Make sure PDL builds + +Fix find_perl on Amiga trg@privat.utfors.se + +Fix appending of .. when DIRS contains directories not immediately +below the cwd. + +Fill in the IMPORTS docs. + +Document "make install UNINST=1" + +Remove tar -I Sun-ism from instmodsh. + +Consider adding a timeout option to prompt() and env variable. + +Unify VMS->find_perl + +Consider if VMS->find_perl needs to have pieces put into maybe_command() + +Consider if shell escaping all macro data is a good idea. + +Move Win32->init_others() ExtUtils::Command overrides into MM_Any. + +Figure out and document the 4th arg to ExtUtils::Install::install() + +Consider if adding a nativize() routine to replace macify() and +fixpath() is useful. + +Eliminate the above from inside FS::VMS->catfile and catdir. Make into +MM_VMS wrappers. + +Add "NO_META" to stop autogeneration (and auto overwrite) of META.yml. + +Test ExtUtils::Command::MM + +Finish ExtUtils::MakeMaker::Tutorial \ No newline at end of file diff --git a/lib/ExtUtils/t/00compile.t b/lib/ExtUtils/t/00compile.t new file mode 100644 index 0000000..19cddc5 --- /dev/null +++ b/lib/ExtUtils/t/00compile.t @@ -0,0 +1,53 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use File::Find; +use File::Spec; +use Test::More; + +my $Has_Test_Pod; +BEGIN { + $Has_Test_Pod = eval 'use Test::Pod 0.95; 1'; +} + +my(@modules); + +chdir File::Spec->catdir(File::Spec->updir, 'lib'); +find( sub { + return if /~$/; + if( $File::Find::dir =~ /^blib|t$/ ) { + $File::Find::prune = 1; + return; + } + push @modules, $File::Find::name if /\.pm$/; + }, 'ExtUtils' +); + +plan tests => scalar @modules * 2; +foreach my $file (@modules) { + local @INC = @INC; + unshift @INC, File::Spec->curdir; + + # This piece of insanity brought to you by non-case preserving + # file systems! We have extutils/command.pm, %INC has + # ExtUtils/Command.pm + # Furthermore, 5.8.0 has a bug about require alone in an eval. Thus + # the extra statement. + eval q{ require($file); 1 } unless grep { lc $file =~ lc $_ } keys %INC; + is( $@, '', "require $file" ); + + SKIP: { + skip "Test::Pod not installed", 1 unless $Has_Test_Pod; + pod_file_ok($file); + } + +} diff --git a/lib/ExtUtils/t/00setup_dummy.t b/lib/ExtUtils/t/00setup_dummy.t index 2d5b1ee..f7f50fc 100644 --- a/lib/ExtUtils/t/00setup_dummy.t +++ b/lib/ExtUtils/t/00setup_dummy.t @@ -22,6 +22,12 @@ package Big::Dummy; $VERSION = 0.01; +=head1 NAME + +Big::Dummy - Try "our" hot dog's + +=cut + 1; END @@ -33,7 +39,9 @@ printf "Current package is: %s\n", __PACKAGE__; WriteMakefile( NAME => 'Big::Dummy', VERSION_FROM => 'lib/Big/Dummy.pm', - PREREQ_PM => {}, + PREREQ_PM => { strict => 0 }, + ABSTRACT_FROM => 'lib/Big/Dummy.pm', + AUTHOR => 'Michael G Schwern ', ); END diff --git a/lib/ExtUtils/t/Command.t b/lib/ExtUtils/t/Command.t index ff9eec1..7f1a97c 100644 --- a/lib/ExtUtils/t/Command.t +++ b/lib/ExtUtils/t/Command.t @@ -12,98 +12,121 @@ BEGIN { chdir 't'; BEGIN { - 1 while unlink 'ecmdfile'; - # forcibly remove ecmddir/temp2, but don't import mkpath - use File::Path (); - File::Path::rmtree( 'ecmddir' ); + 1 while unlink 'ecmdfile', 'newfile'; + # forcibly remove ecmddir/temp2, but don't import mkpath + use File::Path (); + File::Path::rmtree( 'ecmddir' ); } BEGIN { - use Test::More tests => 24; - use File::Spec; + use Test::More tests => 27; + use File::Spec; } -{ - # bad neighbor, but test_f() uses exit() - *CORE::GLOBAL::exit = ''; # quiet 'only once' warning. - *CORE::GLOBAL::exit = sub { return @_ }; - - use_ok( 'ExtUtils::Command' ); +BEGIN { + # bad neighbor, but test_f() uses exit() + *CORE::GLOBAL::exit = ''; # quiet 'only once' warning. + *CORE::GLOBAL::exit = sub { return @_ }; + use_ok( 'ExtUtils::Command' ); +} - # get a file in the current directory, replace last char with wildcard - my $file; - { - local *DIR; - opendir(DIR, File::Spec->curdir()); - while ($file = readdir(DIR)) { - $file =~ s/\.\z// if $^O eq 'VMS'; - last if $file =~ /^\w/; - } - } +{ + # get a file in the current directory, replace last char with wildcard + my $file; + { + local *DIR; + opendir(DIR, File::Spec->curdir()); + while ($file = readdir(DIR)) { + $file =~ s/\.\z// if $^O eq 'VMS'; + last if $file =~ /^\w/; + } + closedir DIR; + } # % means 'match one character' on VMS. Everything else is ? my $match_char = $^O eq 'VMS' ? '%' : '?'; - ($ARGV[0] = $file) =~ s/.\z/$match_char/; + ($ARGV[0] = $file) =~ s/.\z/$match_char/; - # this should find the file - ExtUtils::Command::expand_wildcards(); + # this should find the file + ExtUtils::Command::expand_wildcards(); - is( scalar @ARGV, 1, 'found one file' ); - like( $ARGV[0], qr/$file/, 'expanded wildcard ? successfully' ); + is( scalar @ARGV, 1, 'found one file' ); + like( $ARGV[0], qr/$file/, 'expanded wildcard ? successfully' ); - # try it with the asterisk now - ($ARGV[0] = $file) =~ s/.{3}\z/\*/; - ExtUtils::Command::expand_wildcards(); + # try it with the asterisk now + ($ARGV[0] = $file) =~ s/.{3}\z/\*/; + ExtUtils::Command::expand_wildcards(); - ok( (grep { qr/$file/ } @ARGV), 'expanded wildcard * successfully' ); + ok( (grep { qr/$file/ } @ARGV), 'expanded wildcard * successfully' ); - # concatenate this file with itself - # be extra careful the regex doesn't match itself + # concatenate this file with itself + # be extra careful the regex doesn't match itself use TieOut; - my $out = tie *STDOUT, 'TieOut'; - my $self = $0; - unless (-f $self) { - my ($vol, $dirs, $file) = File::Spec->splitpath($self); - my @dirs = File::Spec->splitdir($dirs); - unshift(@dirs, File::Spec->updir); - $dirs = File::Spec->catdir(@dirs); - $self = File::Spec->catpath($vol, $dirs, $file); - } - @ARGV = ($self, $self); - - cat(); - is( scalar( $$out =~ s/use_ok\( 'ExtUtils::Command'//g), 2, - 'concatenation worked' ); - - # the truth value here is reversed -- Perl true is C false - @ARGV = ( 'ecmdfile' ); - ok( test_f(), 'testing non-existent file' ); - - @ARGV = ( 'ecmdfile' ); - cmp_ok( ! test_f(), '==', (-f 'ecmdfile'), 'testing non-existent file' ); - - # these are destructive, have to keep setting @ARGV - @ARGV = ( 'ecmdfile' ); - touch(); - - @ARGV = ( 'ecmdfile' ); - ok( test_f(), 'now creating that file' ); - - @ARGV = ( 'ecmdfile' ); - ok( -e $ARGV[0], 'created!' ); - - my ($now) = time; - utime ($now, $now, $ARGV[0]); + my $out = tie *STDOUT, 'TieOut'; + my $self = $0; + unless (-f $self) { + my ($vol, $dirs, $file) = File::Spec->splitpath($self); + my @dirs = File::Spec->splitdir($dirs); + unshift(@dirs, File::Spec->updir); + $dirs = File::Spec->catdir(@dirs); + $self = File::Spec->catpath($vol, $dirs, $file); + } + @ARGV = ($self, $self); + + cat(); + is( scalar( $$out =~ s/use_ok\( 'ExtUtils::Command'//g), 2, + 'concatenation worked' ); + + # the truth value here is reversed -- Perl true is C false + @ARGV = ( 'ecmdfile' ); + ok( test_f(), 'testing non-existent file' ); + + @ARGV = ( 'ecmdfile' ); + cmp_ok( ! test_f(), '==', (-f 'ecmdfile'), 'testing non-existent file' ); + + # these are destructive, have to keep setting @ARGV + @ARGV = ( 'ecmdfile' ); + touch(); + + @ARGV = ( 'ecmdfile' ); + ok( test_f(), 'now creating that file' ); + + @ARGV = ( 'ecmdfile' ); + ok( -e $ARGV[0], 'created!' ); + + my ($now) = time; + utime ($now, $now, $ARGV[0]); sleep 2; - # Just checking modify time stamp, access time stamp is set - # to the beginning of the day in Win95. + # Just checking modify time stamp, access time stamp is set + # to the beginning of the day in Win95. # There's a small chance of a 1 second flutter here. my $stamp = (stat($ARGV[0]))[9]; - cmp_ok( abs($now - $stamp), '<=', 1, 'checking modify time stamp' ) || + cmp_ok( abs($now - $stamp), '<=', 1, 'checking modify time stamp' ) || diag "mtime == $stamp, should be $now"; + @ARGV = qw(newfile); + touch(); + + my $new_stamp = (stat('newfile'))[9]; + cmp_ok( abs($new_stamp - $stamp), '>=', 2, 'newer file created' ); + + @ARGV = qw(newfile ecmdfile); + eqtime(); + + $stamp = (stat('ecmdfile'))[9]; + cmp_ok( abs($new_stamp - $stamp), '<=', 1, 'eqtime' ); + + # eqtime use to clear the contents of the file being equalized! + open(FILE, '>>ecmdfile') || die $!; + print FILE "Foo"; + close FILE; + + @ARGV = qw(newfile ecmdfile); + eqtime(); + ok( -s 'ecmdfile', "eqtime doesn't clear the file being equalized" ); + SKIP: { if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos' || $^O eq 'cygwin' || @@ -113,21 +136,21 @@ BEGIN { } # change a file to execute-only - @ARGV = ( 0100, 'ecmdfile' ); + @ARGV = ( '0100', 'ecmdfile' ); ExtUtils::Command::chmod(); is( ((stat('ecmdfile'))[2] & 07777) & 0700, 0100, 'change a file to execute-only' ); # change a file to read-only - @ARGV = ( 0400, 'ecmdfile' ); + @ARGV = ( '0400', 'ecmdfile' ); ExtUtils::Command::chmod(); is( ((stat('ecmdfile'))[2] & 07777) & 0700, ($^O eq 'vos' ? 0500 : 0400), 'change a file to read-only' ); # change a file to write-only - @ARGV = ( 0200, 'ecmdfile' ); + @ARGV = ( '0200', 'ecmdfile' ); ExtUtils::Command::chmod(); is( ((stat('ecmdfile'))[2] & 07777) & 0700, @@ -135,58 +158,58 @@ BEGIN { } # change a file to read-write - @ARGV = ( 0600, 'ecmdfile' ); - ExtUtils::Command::chmod(); + @ARGV = ( '0600', 'ecmdfile' ); + ExtUtils::Command::chmod(); is( ((stat('ecmdfile'))[2] & 07777) & 0700, ($^O eq 'vos' ? 0700 : 0600), 'change a file to read-write' ); - # mkpath - @ARGV = ( File::Spec->join( 'ecmddir', 'temp2' ) ); - ok( ! -e $ARGV[0], 'temp directory not there yet' ); + # mkpath + @ARGV = ( File::Spec->join( 'ecmddir', 'temp2' ) ); + ok( ! -e $ARGV[0], 'temp directory not there yet' ); - mkpath(); - ok( -e $ARGV[0], 'temp directory created' ); + mkpath(); + ok( -e $ARGV[0], 'temp directory created' ); - # copy a file to a nested subdirectory - unshift @ARGV, 'ecmdfile'; - cp(); + # copy a file to a nested subdirectory + unshift @ARGV, 'ecmdfile'; + cp(); - ok( -e File::Spec->join( 'ecmddir', 'temp2', 'ecmdfile' ), 'copied okay' ); + ok( -e File::Spec->join( 'ecmddir', 'temp2', 'ecmdfile' ), 'copied okay' ); - # cp should croak if destination isn't directory (not a great warning) - @ARGV = ( 'ecmdfile' ) x 3; - eval { cp() }; + # cp should croak if destination isn't directory (not a great warning) + @ARGV = ( 'ecmdfile' ) x 3; + eval { cp() }; - like( $@, qr/Too many arguments/, 'cp croaks on error' ); + like( $@, qr/Too many arguments/, 'cp croaks on error' ); - # move a file to a subdirectory - @ARGV = ( 'ecmdfile', 'ecmddir' ); - mv(); + # move a file to a subdirectory + @ARGV = ( 'ecmdfile', 'ecmddir' ); + mv(); - ok( ! -e 'ecmdfile', 'moved file away' ); - ok( -e File::Spec->join( 'ecmddir', 'ecmdfile' ), 'file in new location' ); + ok( ! -e 'ecmdfile', 'moved file away' ); + ok( -e File::Spec->join( 'ecmddir', 'ecmdfile' ), 'file in new location' ); - # mv should also croak with the same wacky warning - @ARGV = ( 'ecmdfile' ) x 3; + # mv should also croak with the same wacky warning + @ARGV = ( 'ecmdfile' ) x 3; - eval { mv() }; - like( $@, qr/Too many arguments/, 'mv croaks on error' ); + eval { mv() }; + like( $@, qr/Too many arguments/, 'mv croaks on error' ); - # remove some files - my @files = @ARGV = ( File::Spec->catfile( 'ecmddir', 'ecmdfile' ), - File::Spec->catfile( 'ecmddir', 'temp2', 'ecmdfile' ) ); - rm_f(); + # remove some files + my @files = @ARGV = ( File::Spec->catfile( 'ecmddir', 'ecmdfile' ), + File::Spec->catfile( 'ecmddir', 'temp2', 'ecmdfile' ) ); + rm_f(); - ok( ! -e $_, "removed $_ successfully" ) for (@ARGV); + ok( ! -e $_, "removed $_ successfully" ) for (@ARGV); - # rm_f dir - @ARGV = my $dir = File::Spec->catfile( 'ecmddir' ); - rm_rf(); - ok( ! -e $dir, "removed $dir successfully" ); + # rm_f dir + @ARGV = my $dir = File::Spec->catfile( 'ecmddir' ); + rm_rf(); + ok( ! -e $dir, "removed $dir successfully" ); } END { - 1 while unlink 'ecmdfile'; - File::Path::rmtree( 'ecmddir' ); + 1 while unlink 'ecmdfile', 'newfile'; + File::Path::rmtree( 'ecmddir' ); } diff --git a/lib/ExtUtils/t/INST.t b/lib/ExtUtils/t/INST.t index d6780ac..5c4aaeb 100644 --- a/lib/ExtUtils/t/INST.t +++ b/lib/ExtUtils/t/INST.t @@ -60,7 +60,7 @@ is( $mm->{VERSION}, 0.01, 'VERSION' ); my $config_prefix = $Config{installprefixexp} || $Config{installprefix} || $Config{prefixexp} || $Config{prefix}; -is( $mm->{PREFIX}, $config_prefix, 'PREFIX' ); +is( $mm->{PERLPREFIX}, '$(DESTDIR)'.$config_prefix, 'PERLPREFIX' ); is( !!$mm->{PERL_CORE}, !!$ENV{PERL_CORE}, 'PERL_CORE' ); diff --git a/lib/ExtUtils/t/INST_PREFIX.t b/lib/ExtUtils/t/INST_PREFIX.t index 8af8c30..99c1ae0 100644 --- a/lib/ExtUtils/t/INST_PREFIX.t +++ b/lib/ExtUtils/t/INST_PREFIX.t @@ -16,7 +16,7 @@ BEGIN { } use strict; -use Test::More tests => 26; +use Test::More tests => 38; use MakeMaker::Test::Utils; use ExtUtils::MakeMaker; use File::Spec; @@ -38,15 +38,15 @@ my $Updir = File::Spec->updir; ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) || diag("chdir failed: $!"); -my $PREFIX = File::Spec->catdir('foo', 'bar'); my $stdout = tie *STDOUT, 'TieOut' or die; + my $mm = WriteMakefile( NAME => 'Big::Dummy', VERSION_FROM => 'lib/Big/Dummy.pm', PREREQ_PM => {}, PERL_CORE => $ENV{PERL_CORE}, - PREFIX => $PREFIX, ); + like( $stdout->read, qr{ Writing\ $Makefile\ for\ Big::Liar\n Big::Liar's\ vars\n @@ -54,15 +54,43 @@ like( $stdout->read, qr{ INST_ARCHLIB\ =\ \S+\n Writing\ $Makefile\ for\ Big::Dummy\n }x ); -undef $stdout; -untie *STDOUT; isa_ok( $mm, 'ExtUtils::MakeMaker' ); is( $mm->{NAME}, 'Big::Dummy', 'NAME' ); is( $mm->{VERSION}, 0.01, 'VERSION' ); -is( $mm->{PREFIX}, $PREFIX, 'PREFIX' ); +foreach my $prefix (qw(PREFIX PERLPREFIX SITEPREFIX VENDORPREFIX)) { + unlike( $mm->{$prefix}, qr/\$\(PREFIX\)/ ); + like( $mm->{$prefix}, qr/^\$\(DESTDIR\)/, + "\$(DESTDIR) prepended to $prefix" ); +} + + +my $PREFIX = File::Spec->catdir('foo', 'bar'); +$mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + PREREQ_PM => {}, + PERL_CORE => $ENV{PERL_CORE}, + PREFIX => $PREFIX, +); +like( $stdout->read, qr{ + Writing\ $Makefile\ for\ Big::Liar\n + Big::Liar's\ vars\n + INST_LIB\ =\ \S+\n + INST_ARCHLIB\ =\ \S+\n + Writing\ $Makefile\ for\ Big::Dummy\n +}x ); +undef $stdout; +untie *STDOUT; + +is( $mm->{PREFIX}, '$(DESTDIR)'.$PREFIX, 'PREFIX' ); + +foreach my $prefix (qw(PERLPREFIX SITEPREFIX VENDORPREFIX)) { + is( $mm->{$prefix}, '$(DESTDIR)$(PREFIX)', + "\$(PREFIX) overrides $prefix" ); +} is( !!$mm->{PERL_CORE}, !!$ENV{PERL_CORE}, 'PERL_CORE' ); @@ -80,36 +108,28 @@ is( $mm_perl_src, $perl_src, 'PERL_SRC' ); # Every INSTALL* variable must start with some PREFIX. -my @Perl_Install = qw(archlib privlib bin script - man1dir man3dir); -my @Site_Install = qw(sitearch sitelib sitebin - siteman1dir siteman3dir); -my @Vend_Install = qw(vendorarch vendorlib vendorbin - vendorman1dir vendorman3dir); - -foreach my $var (@Perl_Install) { - my $prefix = $Is_VMS ? '[.foo.bar' : File::Spec->catdir(qw(foo bar)); - - # support for man page skipping - $prefix = 'none' if $var =~ /man/ && !$Config{"install$var"}; - like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, "PREFIX + $var" ); -} +my %Install_Vars = ( + PERL => [qw(archlib privlib bin man1dir man3dir script)], + SITE => [qw(sitearch sitelib sitebin siteman1dir siteman3dir)], + VENDOR => [qw(vendorarch vendorlib vendorbin vendorman1dir vendorman3dir)] +); -foreach my $var (@Site_Install) { - my $prefix = $Is_VMS ? '[.foo.bar' : File::Spec->catdir(qw(foo bar)); +while( my($type, $vars) = each %Install_Vars) { - like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, - "SITEPREFIX + $var" ); -} + SKIP: foreach my $var (@$vars) { + skip "VMS must expand macros in INSTALL* vars", scalar @$vars + if $Is_VMS; -foreach my $var (@Vend_Install) { - my $prefix = $Is_VMS ? '[.foo.bar' : File::Spec->catdir(qw(foo bar)); + my $prefix = '$('.$type.'PREFIX)'; - like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, - "VENDORPREFIX + $var" ); + # support for man page skipping + $prefix = 'none' if $type eq 'PERL' && + $var =~ /man/ && + !$Config{"install$var"}; + like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, "$prefix + $var" ); + } } - # Check that when installman*dir isn't set in Config no man pages # are generated. { diff --git a/lib/ExtUtils/t/Install.t b/lib/ExtUtils/t/Install.t new file mode 100644 index 0000000..042412b --- /dev/null +++ b/lib/ExtUtils/t/Install.t @@ -0,0 +1,68 @@ +#!/usr/bin/perl -w + +# Test ExtUtils::Install. + +BEGIN { + if( $ENV{PERL_CORE} ) { + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; +use TieOut; +use File::Path; +use File::Spec; + +use Test::More tests => 18; + +BEGIN { use_ok('ExtUtils::Install') } + +# Check exports. +foreach my $func (qw(install uninstall pm_to_blib install_default)) { + can_ok(__PACKAGE__, $func); +} + + +chdir 'Big-Dummy'; + +my $stdout = tie *STDOUT, 'TieOut'; +pm_to_blib( { 'lib/Big/Dummy.pm' => 'blib/lib/Big/Dummy.pm' }, + 'blib/lib/auto' + ); +ok( -d 'blib/lib', 'pm_to_blib created blib dir' ); +ok( -r 'blib/lib/Big/Dummy.pm', ' copied .pm file' ); +ok( -r 'blib/lib/auto', ' created autosplit dir' ); +is( $stdout->read, "cp lib/Big/Dummy.pm blib/lib/Big/Dummy.pm\n" ); + +pm_to_blib( { 'lib/Big/Dummy.pm' => 'blib/lib/Big/Dummy.pm' }, + 'blib/lib/auto' + ); +ok( -d 'blib/lib', 'second run, blib dir still there' ); +ok( -r 'blib/lib/Big/Dummy.pm', ' .pm file still there' ); +ok( -r 'blib/lib/auto', ' autosplit still there' ); +is( $stdout->read, "Skip blib/lib/Big/Dummy.pm (unchanged)\n" ); + + +install( { 'blib/lib' => 'install-test/lib/perl', + read => 'install-test/packlist', + write => 'install-test/packlist' + } ); +ok( -d 'install-test/lib/perl', 'install made dir' ); +ok( -r 'install-test/lib/perl/Big/Dummy.pm', ' .pm file installed' ); +ok( -r 'install-test/packlist', ' packlist exists' ); + +open(PACKLIST, 'install-test/packlist' ); +my %packlist = map { chomp; ($_ => 1) } ; +close PACKLIST; + +# On case-insensitive filesystems (ie. VMS), the keys of the packlist might +# be lowercase. :( +my $native_dummy = File::Spec->catfile(qw(install-test lib perl Big Dummy.pm)); +is( keys %packlist, 1 ); +is( lc((keys %packlist)[0]), lc $native_dummy, 'packlist written' ); + +END { rmtree 'blib' } diff --git a/lib/ExtUtils/t/Liblist.t b/lib/ExtUtils/t/Liblist.t new file mode 100644 index 0000000..2ba1653 --- /dev/null +++ b/lib/ExtUtils/t/Liblist.t @@ -0,0 +1,35 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + unshift @INC, '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; +use Test::More tests => 6; +use Data::Dumper; + +BEGIN { + use_ok( 'ExtUtils::Liblist' ); +} + +ok( defined &ExtUtils::Liblist::ext, + 'ExtUtils::Liblist::ext() defined for backwards compat' ); + +{ + my @warn; + local $SIG{__WARN__} = sub {push @warn, [@_]}; + + my @out = ExtUtils::Liblist->ext('-ln0tt43r3_perl'); + is( @out, 4, 'enough output' ); + unlike( $out[2], qr/-ln0tt43r3_perl/, 'bogus library not added' ); + ok( @warn, 'had warning'); + + is( grep(/\QNote (probably harmless): No library found for \E(-l)?n0tt43r3_perl/, map { @$_ } @warn), 1 ) || diag Dumper @warn; +} diff --git a/lib/ExtUtils/t/MM_BeOS.t b/lib/ExtUtils/t/MM_BeOS.t index 870e8d4..3161176 100644 --- a/lib/ExtUtils/t/MM_BeOS.t +++ b/lib/ExtUtils/t/MM_BeOS.t @@ -40,9 +40,16 @@ use File::Basename; require_ok( 'ExtUtils::MM_BeOS' ); -# perl_archive() + +# init_linker { - my $libperl = $Config{libperl} || 'libperl.a'; - is( MM->perl_archive(), File::Spec->catfile('$(PERL_INC)', $libperl ), - 'perl_archive() should respect libperl setting' ); + my $libperl = File::Spec->catfile('$(PERL_INC)', + $Config{libperl} || 'libperl.a' ); + my $export = ''; + my $after = ''; + $MM->init_linker; + + is( $MM->{PERL_ARCHIVE}, $libperl, 'PERL_ARCHIVE' ); + is( $MM->{PERL_ARCHIVE_AFTER}, $after, 'PERL_ARCHIVE_AFTER' ); + is( $MM->{EXPORT_LIST}, $export, 'EXPORT_LIST' ); } diff --git a/lib/ExtUtils/t/MM_Cygwin.t b/lib/ExtUtils/t/MM_Cygwin.t index 03641d3..bc4165e 100644 --- a/lib/ExtUtils/t/MM_Cygwin.t +++ b/lib/ExtUtils/t/MM_Cygwin.t @@ -11,6 +11,7 @@ BEGIN { } chdir 't'; +use strict; use Test::More; BEGIN { @@ -33,83 +34,81 @@ is( MM->canonpath('/a/../../c'), $path, 'canonpath() method should work just like the one in File::Spec' ); # test cflags, with the fake package below -my $args = bless({ +my $MM = bless({ CFLAGS => 'fakeflags', CCFLAGS => '', -}, MM); +}, 'MM'); # with CFLAGS set, it should be returned -is( $args->cflags(), 'fakeflags', +is( $MM->cflags(), 'fakeflags', 'cflags() should return CFLAGS member data, if set' ); -delete $args->{CFLAGS}; +delete $MM->{CFLAGS}; # ExtUtils::MM_Cygwin::cflags() calls this, fake the output { local $SIG{__WARN__} = sub { - # no warnings 'redefine'; warn @_ unless $_[0] =~ /^Subroutine .* redefined/; }; - sub ExtUtils::MM_Unix::cflags { return $_[1] }; + *ExtUtils::MM_Unix::cflags = sub { return $_[1] }; } # respects the config setting, should ignore whitespace around equal sign my $ccflags = $Config{useshrplib} eq 'true' ? ' -DUSEIMPORTLIB' : ''; { - local $args->{NEEDS_LINKING} = 1; - $args->cflags(<{NEEDS_LINKING} = 1; + $MM->cflags(<{CFLAGS}, qr/OPTIMIZE = opt/, '... should set OPTIMIZE' ); -like( $args->{CFLAGS}, qr/PERLTYPE = pt/, '... should set PERLTYPE' ); -like( $args->{CFLAGS}, qr/CCFLAGS = $ccflags/, '... should set CCFLAGS' ); +like( $MM->{CFLAGS}, qr/OPTIMIZE = opt/, '... should set OPTIMIZE' ); +like( $MM->{CFLAGS}, qr/PERLTYPE = pt/, '... should set PERLTYPE' ); +like( $MM->{CFLAGS}, qr/CCFLAGS = $ccflags/, '... should set CCFLAGS' ); # test manifypods -$args = bless({ +$MM = bless({ NOECHO => 'noecho', MAN3PODS => {}, MAN1PODS => {}, MAKEFILE => 'Makefile', }, 'MM'); -like( $args->manifypods(), qr/pure_all\n\tnoecho/, +unlike( $MM->manifypods(), qr/foo/, 'manifypods() should return without PODS values set' ); -$args->{MAN3PODS} = { foo => 1 }; -my $out = tie *STDOUT, 'FakeOut'; -{ - local $SIG{__WARN__} = sub { - # no warnings 'redefine'; - warn @_ unless $_[0] =~ /used only once/; - }; - no warnings 'once'; - local *MM::perl_script = sub { return }; - my $res = $args->manifypods(); - like( $$out, qr/could not locate your pod2man/, - '... should warn if pod2man cannot be located' ); - like( $res, qr/POD2MAN_EXE = -S pod2man/, - '... should use default pod2man target' ); - like( $res, qr/pure_all.+foo/, '... should add MAN3PODS targets' ); -} +$MM->{MAN3PODS} = { foo => 'foo.1' }; +my $res = $MM->manifypods(); +like( $res, qr/pure_all.*foo.*foo.1/s, '... should add MAN3PODS targets' ); + SKIP: { skip "Only relevent in the core", 2 unless $ENV{PERL_CORE}; - $args->{PERL_SRC} = File::Spec->updir; - $args->{MAN1PODS} = { bar => 1 }; - $$out = ''; - $res = $args->manifypods(); + $MM->{PERL_SRC} = File::Spec->updir; + $MM->{MAN1PODS} = { bar => 1 }; + my $out = tie *STDOUT, 'FakeOut'; + $res = $MM->manifypods(); is( $$out, '', '... should not warn if PERL_SRC provided' ); like( $res, qr/bar \\\n\t1 \\\n\tfoo/, '... should join MAN1PODS and MAN3PODS'); } -# test perl_archive -my $libperl = $Config{libperl} || 'libperl.a'; -$libperl =~ s/\.a/.dll.a/; -is( $args->perl_archive(), "\$(PERL_INC)/$libperl", - 'perl_archive() should respect libperl setting' ); + +# init_linker +{ + my $libperl = $Config{libperl} || 'libperl.a'; + $libperl =~ s/\.a/.dll.a/ if $] >= 5.007; + $libperl = "\$(PERL_INC)/$libperl"; + + my $export = ''; + my $after = ''; + $MM->init_linker; + + is( $MM->{PERL_ARCHIVE}, $libperl, 'PERL_ARCHIVE' ); + is( $MM->{PERL_ARCHIVE_AFTER}, $after, 'PERL_ARCHIVE_AFTER' ); + is( $MM->{EXPORT_LIST}, $export, 'EXPORT_LIST' ); +} + package FakeOut; diff --git a/lib/ExtUtils/t/MM_NW5.t b/lib/ExtUtils/t/MM_NW5.t index d2046ee..13359d1 100644 --- a/lib/ExtUtils/t/MM_NW5.t +++ b/lib/ExtUtils/t/MM_NW5.t @@ -172,19 +172,20 @@ delete $ENV{PATH} unless $had_path; 'clean() Makefile target' ); } -# perl_archive() + +# init_linker { my $libperl = $Config{libperl} || 'libperl.a'; - is( $MM->perl_archive(), File::Spec->catfile('$(PERL_INC)', $libperl ), - 'perl_archive() should respect libperl setting' ); -} + my $export = '$(BASEEXT).def'; + my $after = ''; + $MM->init_linker; -# export_list -{ - my $mm_w32 = bless { BASEEXT => 'someext' }, 'MM'; - is( $mm_w32->export_list(), 'someext.def', 'export_list()' ); + is( $MM->{PERL_ARCHIVE}, $libperl, 'PERL_ARCHIVE' ); + is( $MM->{PERL_ARCHIVE_AFTER}, $after, 'PERL_ARCHIVE_AFTER' ); + is( $MM->{EXPORT_LIST}, $export, 'EXPORT_LIST' ); } + # canonpath() { my $path = 'SYS:/TEMP'; @@ -272,14 +273,6 @@ unlink "${script_name}$script_ext" if -f "${script_name}$script_ext"; # xs_o() should look into that # top_targets() should look into that -# manifypods() -{ - my $mm_w32 = bless { NOECHO => '' }, 'MM'; - like( $mm_w32->manifypods(), - qr/^\nmanifypods :\n\t\$\Q(NOOP)\E\n$/, - 'manifypods() Makefile target' ); -} - # dist_ci() should look into that # dist_core() should look into that diff --git a/lib/ExtUtils/t/MM_OS2.t b/lib/ExtUtils/t/MM_OS2.t index 53b83f3..caf662e 100644 --- a/lib/ExtUtils/t/MM_OS2.t +++ b/lib/ExtUtils/t/MM_OS2.t @@ -247,26 +247,29 @@ ok( ExtUtils::MM_OS2->file_name_is_absolute( '\foo' ), ok( ! ExtUtils::MM_OS2->file_name_is_absolute( 'arduk' ), '... but not for paths with no leading slash or volume' ); -# perl_archive -is( ExtUtils::MM_OS2->perl_archive(), '$(PERL_INC)/libperl$(LIB_EXT)', - 'perl_archive() should return a static string' ); -# perl_archive_after +$mm->init_linker; + +# PERL_ARCHIVE +is( $mm->{PERL_ARCHIVE}, '$(PERL_INC)/libperl$(LIB_EXT)', 'PERL_ARCHIVE' ); + +# PERL_ARCHIVE_AFTER { my $aout = 0; local *OS2::is_aout; *OS2::is_aout = \$aout; - isnt( ExtUtils::MM_OS2->perl_archive_after(), '', - 'perl_archive_after() should return string without $is_aout set' ); + $mm->init_linker; + isnt( $mm->{PERL_ARCHIVE_AFTER}, '', + 'PERL_ARCHIVE_AFTER should be empty without $is_aout set' ); $aout = 1; - is( ExtUtils::MM_OS2->perl_archive_after(), '', + is( $mm->{PERL_ARCHIVE_AFTER}, '', '... and blank string if it is set' ); } -# export_list -is( ExtUtils::MM_OS2::export_list({ BASEEXT => 'foo' }), 'foo.def', - 'export_list() should add .def to BASEEXT member' ); +# EXPORT_LIST +is( $mm->{EXPORT_LIST}, '$(BASEEXT).def', + 'EXPORT_LIST should add .def to BASEEXT member' ); END { use File::Path; diff --git a/lib/ExtUtils/t/MM_Unix.t b/lib/ExtUtils/t/MM_Unix.t index 1e47f1b..1e0e801 100644 --- a/lib/ExtUtils/t/MM_Unix.t +++ b/lib/ExtUtils/t/MM_Unix.t @@ -18,7 +18,7 @@ BEGIN { plan skip_all => 'Non-Unix platform'; } else { - plan tests => 112; + plan tests => 115; } } @@ -79,14 +79,13 @@ foreach ( qw / dist_basics dist_ci dist_core - dist_dir + distdir dist_test dlsyms dynamic dynamic_bs dynamic_lib exescan - export_list extliblist find_perl fixin @@ -103,7 +102,6 @@ foreach ( qw / makeaperl makefile manifypods - maybe_command_in_dirs needs_linking pasthru perldepend @@ -165,10 +163,13 @@ is ($t->has_link_code(),1); is ($t->{HAS_LINK_CODE},1); ############################################################################### # libscan -is ($t->libscan('RCS'),'','libscan on RCS'); -is ($t->libscan('CVS'),'','libscan on CVS'); -is ($t->libscan('SCCS'),'','libscan on SCCS'); -is ($t->libscan('Fatty'),'Fatty','libscan on something not RCS, CVS or SCCS'); +is ($t->libscan('foo/RCS/bar'), '', 'libscan on RCS'); +is ($t->libscan('CVS/bar/car'), '', 'libscan on CVS'); +is ($t->libscan('SCCS'), '', 'libscan on SCCS'); +is ($t->libscan('.svn/something'), '', 'libscan on Subversion'); +is ($t->libscan('foo/b~r'), 'foo/b~r', 'libscan on file with ~'); + +is ($t->libscan('Fatty'), 'Fatty', 'libscan on something not a VC file' ); ############################################################################### # maybe_command @@ -214,6 +215,7 @@ is ($t->perl_script($self_name),$self_name, 'we pass as a perl_script()'); ############################################################################### # perm_rw perm_rwx +$t->init_PERM; is ($t->perm_rw(),'644', 'perm_rw() is 644'); is ($t->perm_rwx(),'755', 'perm_rwx() is 755'); @@ -231,12 +233,13 @@ foreach (qw/ post_constants postamble post_initialize/) is ($t->replace_manpage_separator('Foo/Bar'),'Foo::Bar','manpage_separator'); ############################################################################### -# export_list, perl_archive, perl_archive_after -foreach (qw/ export_list perl_archive perl_archive_after/) - { - is ($t->$_(),'',"$_() is empty string on Unix"); - } +$t->init_linker; +foreach (qw/ EXPORT_LIST PERL_ARCHIVE PERL_ARCHIVE_AFTER /) +{ + ok( exists $t->{$_}, "$_ was defined" ); + is( $t->{$_}, '', "$_ is empty on Unix"); +} { diff --git a/lib/ExtUtils/t/MM_VMS.t b/lib/ExtUtils/t/MM_VMS.t index 303a599..9ae57c6 100644 --- a/lib/ExtUtils/t/MM_VMS.t +++ b/lib/ExtUtils/t/MM_VMS.t @@ -19,7 +19,6 @@ BEGIN { find_perl path maybe_command - maybe_command_in_dirs perl_script file_name_is_absolute replace_manpage_separator @@ -49,7 +48,7 @@ BEGIN { realclean dist_basics dist_core - dist_dir + distdir dist_test install perldepend diff --git a/lib/ExtUtils/t/MM_Win32.t b/lib/ExtUtils/t/MM_Win32.t index 8e2b52c..315b915 100644 --- a/lib/ExtUtils/t/MM_Win32.t +++ b/lib/ExtUtils/t/MM_Win32.t @@ -16,7 +16,7 @@ use Test::More; BEGIN { if ($^O =~ /MSWin32/i) { - plan tests => 40; + plan tests => 42; } else { plan skip_all => 'This is not Win32'; } @@ -84,7 +84,7 @@ delete $ENV{PATHEXT} unless $had_pathext; { my $my_perl = $1 if $^X =~ /(.*)/; # are we in -T or -t? my( $perl, $path ) = fileparse( $my_perl ); - like( $MM->find_perl( $], [ $perl ], [ $path ] ), + like( $MM->find_perl( $], [ $perl ], [ $path ], 0 ), qr/^\Q$my_perl\E$/i, 'find_perl() finds this perl' ); } @@ -122,32 +122,44 @@ delete $ENV{PATHEXT} unless $had_pathext; } # constants() +# XXX this test is probably useless now that we can call individual +# init_* methods and check the keys in $mm_w32 directly { my $mm_w32 = bless { NAME => 'TestMM_Win32', VERSION => '1.00', - VERSION_FROM => 'TestMM_Win32', PM => { 'MM_Win32.pm' => 1 }, }, 'MM'; # XXX Hack until we have a proper init method. # Flesh out some necessary keys in the MM object. - foreach my $key (qw(XS C O_FILES H HTMLLIBPODS HTMLSCRIPTPODS - MAN1PODS MAN3PODS PARENT_NAME)) { - $mm_w32->{$key} = ''; - } + @{$mm_w32}{qw(XS MAN1PODS MAN3PODS)} = ({}) x 3; + @{$mm_w32}{qw(C O_FILES H)} = ([]) x 3; + @{$mm_w32}{qw(PARENT_NAME)} = ('') x 3; + $mm_w32->{FULLEXT} = 'TestMM_Win32'; + $mm_w32->{BASEEXT} = 'TestMM_Win32'; + + $mm_w32->init_VERSION; + $mm_w32->init_linker; + $mm_w32->init_INST; + $mm_w32->init_xs; + my $s_PM = join( " \\\n\t", sort keys %{$mm_w32->{PM}} ); my $k_PM = join( " \\\n\t", %{$mm_w32->{PM}} ); - like( $mm_w32->constants(), - qr|^NAME\ =\ TestMM_Win32\s+VERSION\ =\ 1\.00.+ - MAKEMAKER\ =\ \Q$INC{'ExtUtils/MakeMaker.pm'}\E\s+ - MM_VERSION\ =\ \Q$ExtUtils::MakeMaker::VERSION\E.+ - VERSION_FROM\ =\ TestMM_Win32.+ - TO_INST_PM\ =\ \Q$s_PM\E\s+ - PM_TO_BLIB\ =\ \Q$k_PM\E - |xs, 'constants()' ); - + my $constants = $mm_w32->constants; + + foreach my $regex ( + qr|^NAME \s* = \s* TestMM_Win32 \s* $|xms, + qr|^VERSION \s* = \s* 1\.00 \s* $|xms, + qr|^MAKEMAKER \s* = \s* \Q$INC{'ExtUtils/MakeMaker.pm'}\E \s* $|xms, + qr|^MM_VERSION \s* = \s* \Q$ExtUtils::MakeMaker::VERSION\E \s* $|xms, + qr|^TO_INST_PM \s* = \s* \Q$s_PM\E \s* $|xms, + qr|^PM_TO_BLIB \s* = \s* \Q$k_PM\E \s* $|xms, + ) + { + like( $constants, $regex, 'constants() check' ); + } } # path() @@ -172,17 +184,17 @@ delete $ENV{PATH} unless $had_path; 'clean() Makefile target' ); } -# perl_archive() +# init_linker { - my $libperl = $Config{libperl} || 'libperl.a'; - is( $MM->perl_archive(), File::Spec->catfile('$(PERL_INC)', $libperl ), - 'perl_archive() should respect libperl setting' ); -} - -# export_list -{ - my $mm_w32 = bless { BASEEXT => 'someext' }, 'MM'; - is( $mm_w32->export_list(), 'someext.def', 'export_list()' ); + my $libperl = File::Spec->catfile('$(PERL_INC)', + $Config{libperl} || 'libperl.a'); + my $export = '$(BASEEXT).def'; + my $after = ''; + $MM->init_linker; + + is( $MM->{PERL_ARCHIVE}, $libperl, 'PERL_ARCHIVE' ); + is( $MM->{PERL_ARCHIVE_AFTER}, $after, 'PERL_ARCHIVE_AFTER' ); + is( $MM->{EXPORT_LIST}, $export, 'EXPORT_LIST' ); } # canonpath() @@ -234,52 +246,9 @@ EOSCRIPT unlink "${script_name}$script_ext" if -f "${script_name}$script_ext"; -# pm_to_blib() -{ - like( $MM->pm_to_blib(), - qr/^pm_to_blib: \Q$(TO_INST_PM)\E.+\Q$(TOUCH) \E\$@\s+$/ms, - 'pm_to_blib' ); -} - -# tool_autosplit() -{ - my %attribs = ( MAXLEN => 255 ); - like( $MM->tool_autosplit( %attribs ), - qr/^\#\ Usage:\ \$\(AUTOSPLITFILE\) - \ FileToSplit\ AutoDirToSplitInto.+ - AUTOSPLITFILE\ =\ \$\(PERLRUN\)\ .+ - \$AutoSplit::Maxlen=$attribs{MAXLEN}; - /xms, - 'tool_autosplit()' ); -} - -# tools_other() -{ - ( my $mm_w32 = bless { }, 'MM' )->init_others(); - - my $bin_sh = ( $Config{make} =~ /^dmake/i - ? "" : ($Config{sh} || 'cmd /c') . "\n" ); - $bin_sh = "SHELL = $bin_sh" if $bin_sh; - - my $tools = join "\n", map "$_ = $mm_w32->{ $_ }" - => qw(CHMOD CP LD MV NOOP RM_F RM_RF TEST_F TOUCH UMASK_NULL DEV_NULL); - - like( $mm_w32->tools_other(), - qr/^\Q$bin_sh$tools/m, - 'tools_other()' ); -}; - # xs_o() should look into that # top_targets() should look into that -# manifypods() -{ - my $mm_w32 = bless { NOECHO => '' }, 'MM'; - like( $mm_w32->manifypods(), - qr/^\nmanifypods :\n\t\$\Q(NOOP)\E\n$/, - 'manifypods() Makefile target' ); -} - # dist_ci() should look into that # dist_core() should look into that diff --git a/lib/ExtUtils/t/Manifest.t b/lib/ExtUtils/t/Manifest.t index 7a488be..4d76b94 100644 --- a/lib/ExtUtils/t/Manifest.t +++ b/lib/ExtUtils/t/Manifest.t @@ -14,7 +14,7 @@ chdir 't'; use strict; # these files help the test run -use Test::More tests => 33; +use Test::More tests => 37; use Cwd; # these files are needed for the module itself @@ -28,12 +28,12 @@ use File::Path; # keep track of everything added so it can all be deleted my %files; sub add_file { - my ($file, $data) = @_; - $data ||= 'foo'; + my ($file, $data) = @_; + $data ||= 'foo'; unlink $file; # or else we'll get multiple versions on VMS - open( T, '>'.$file) or return; - print T $data; - ++$files{$file}; + open( T, '>'.$file) or return; + print T $data; + ++$files{$file}; close T; } @@ -58,7 +58,7 @@ sub remove_dir { BEGIN { use_ok( 'ExtUtils::Manifest', qw( mkmanifest manicheck filecheck fullcheck - maniread manicopy skipcheck ) ); + maniread manicopy skipcheck maniadd) ); } my $cwd = Cwd::getcwd(); @@ -173,12 +173,21 @@ like( $warn, qr{^Skipping moretest/quux$}i, 'got skipping warning again' ); # There was a bug where entries in MANIFEST would be blotted out # by MANIFEST.SKIP rules. add_file( 'MANIFEST.SKIP' => 'foo' ); -add_file( 'MANIFEST' => 'foobar' ); +add_file( 'MANIFEST' => "foobar\n" ); add_file( 'foobar' => '123' ); ($res, $warn) = catch_warning( \&manicheck ); is( $res, '', 'MANIFEST overrides MANIFEST.SKIP' ); is( $warn, undef, 'MANIFEST overrides MANIFEST.SKIP, no warnings' ); +$files = maniread; +ok( !$files->{wibble}, 'MANIFEST in good state' ); +maniadd({ wibble => undef }); +maniadd({ yarrow => "hock" }); +$files = maniread; +is( $files->{wibble}, '', 'maniadd() with undef comment' ); +is( $files->{yarrow}, 'hock',' with comment' ); +is( $files->{foobar}, '', ' preserved old entries' ); + END { # the args are evaluated in scalar context diff --git a/lib/ExtUtils/t/basic.t b/lib/ExtUtils/t/basic.t index 9080434..4e0a607 100644 --- a/lib/ExtUtils/t/basic.t +++ b/lib/ExtUtils/t/basic.t @@ -14,12 +14,15 @@ BEGIN { } use strict; -use Test::More tests => 17; +use Config; + +use Test::More tests => 48; use MakeMaker::Test::Utils; +use File::Find; use File::Spec; -use TieOut; my $perl = which_perl(); +my $Is_VMS = $^O eq 'VMS'; my $root_dir = 't'; @@ -93,20 +96,93 @@ my $make = make_run(); END { unlink 'MANIFEST'; } + +`$make ppd`; +is( $?, 0, ' exited normally' ); +ok( open(PPD, 'Big-Dummy.ppd'), ' .ppd file generated' ); +my $ppd_html; +{ local $/; $ppd_html = } +close PPD; +like( $ppd_html, qr{^}m, + ' ' ); +like( $ppd_html, qr{^\s*Big-Dummy}m, ' ' ); +like( $ppd_html, qr{^\s*<ABSTRACT>Try "our" hot dog's</ABSTRACT>}m, + ' <ABSTRACT>'); +like( $ppd_html, + qr{^\s*<AUTHOR>Michael G Schwern <schwern\@pobox.com></AUTHOR>}m, + ' <AUTHOR>' ); +like( $ppd_html, qr{^\s*<IMPLEMENTATION>}m, ' <IMPLEMENTATION>'); +like( $ppd_html, qr{^\s*<DEPENDENCY NAME="strict" VERSION="0,0,0,0" />}m, + ' <DEPENDENCY>' ); +like( $ppd_html, qr{^\s*<OS NAME="$Config{osname}" />}m, + ' <OS>' ); +like( $ppd_html, qr{^\s*<ARCHITECTURE NAME="$Config{archname}" />}m, + ' <ARCHITECTURE>'); +like( $ppd_html, qr{^\s*<CODEBASE HREF="" />}m, ' <CODEBASE>'); +like( $ppd_html, qr{^\s*</IMPLEMENTATION>}m, ' </IMPLEMENTATION>'); +like( $ppd_html, qr{^\s*</SOFTPKG>}m, ' </SOFTPKG>'); +END { unlink 'Big-Dummy.ppd' } + + my $test_out = `$make test`; like( $test_out, qr/All tests successful/, 'make test' ); -is( $?, 0 ); +is( $?, 0, ' exited normally' ); # Test 'make test TEST_VERBOSE=1' my $make_test_verbose = make_macro($make, 'test', TEST_VERBOSE => 1); $test_out = `$make_test_verbose`; like( $test_out, qr/ok \d+ - TEST_VERBOSE/, 'TEST_VERBOSE' ); -like( $test_out, qr/All tests successful/, ' successful' ); -is( $?, 0 ); +like( $test_out, qr/All tests successful/, ' successful' ); +is( $?, 0, ' exited normally' ); + + +my $install_out = `$make install`; +is( $?, 0, 'install' ) || diag $install_out; +like( $install_out, qr/^Installing /m ); +like( $install_out, qr/^Writing /m ); + +ok( -r 'dummy-install', ' install dir created' ); +my %files = (); +find( sub { + # do it case-insensitive for non-case preserving OSs + $files{lc $_} = $File::Find::name; +}, 'dummy-install' ); +ok( $files{'dummy.pm'}, ' Dummy.pm installed' ); +ok( $files{'liar.pm'}, ' Liar.pm installed' ); +ok( $files{'.packlist'}, ' packlist created' ); +ok( $files{'perllocal.pod'},' perllocal.pod created' ); + + +SKIP: { + skip "VMS install targets do not preserve PREFIX", 8 if $Is_VMS; + + $install_out = `$make install PREFIX=elsewhere`; + is( $?, 0, 'install with PREFIX override' ) || diag $install_out; + like( $install_out, qr/^Installing /m ); + like( $install_out, qr/^Writing /m ); + + ok( -r 'elsewhere', ' install dir created' ); + %files = (); + find( sub { $files{$_} = $File::Find::name; }, 'elsewhere' ); + ok( $files{'Dummy.pm'}, ' Dummy.pm installed' ); + ok( $files{'Liar.pm'}, ' Liar.pm installed' ); + ok( $files{'.packlist'}, ' packlist created' ); + ok( $files{'perllocal.pod'},' perllocal.pod created' ); +} + my $dist_test_out = `$make disttest`; is( $?, 0, 'disttest' ) || diag($dist_test_out); +# Test META.yml generation +use ExtUtils::Manifest qw(maniread); +ok( -f 'META.yml', 'META.yml written' ); +my $manifest = maniread(); +# VMS is non-case preserving, so we can't know what the MANIFEST will +# look like. :( +_normalize($manifest); +is( $manifest->{'meta.yml'}, 'Module meta-data in YAML' ); + # Make sure init_dirscan doesn't go into the distdir @mpl_out = `$perl Makefile.PL "PREFIX=dummy-install"`; @@ -114,8 +190,7 @@ is( $?, 0, 'disttest' ) || diag($dist_test_out); cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) || diag(@mpl_out); -ok( grep(/^Writing $makefile for Big::Dummy/, - @mpl_out) == 1, +ok( grep(/^Writing $makefile for Big::Dummy/, @mpl_out) == 1, 'init_dirscan skipped distdir') || diag(@mpl_out); @@ -129,3 +204,13 @@ is( $?, 0, 'realclean' ) || diag($realclean_out); open(STDERR, ">&SAVERR") or die $!; close SAVERR; + + +sub _normalize { + my $hash = shift; + + while(my($k,$v) = each %$hash) { + delete $hash->{$k}; + $hash->{lc $k} = $v; + } +} diff --git a/lib/ExtUtils/t/hints.t b/lib/ExtUtils/t/hints.t index 62608d7..b74690f 100644 --- a/lib/ExtUtils/t/hints.t +++ b/lib/ExtUtils/t/hints.t @@ -11,10 +11,16 @@ BEGIN { } chdir 't'; +use File::Spec; + use Test::More tests => 3; +# Having the CWD in @INC masked a bug in finding hint files +my $curdir = File::Spec->curdir; +@INC = grep { $_ ne $curdir && $_ ne '.' } @INC; + mkdir('hints', 0777); -my $hint_file = "hints/$^O.pl"; +my $hint_file = File::Spec->catfile('hints', "$^O.pl"); open(HINT, ">$hint_file") || die "Can't write dummy hints file $hint_file: $!"; print HINT <<'CLOO'; $self->{CCFLAGS} = 'basset hounds got long ears'; diff --git a/lib/ExtUtils/t/oneliner.t b/lib/ExtUtils/t/oneliner.t new file mode 100644 index 0000000..5e0521b --- /dev/null +++ b/lib/ExtUtils/t/oneliner.t @@ -0,0 +1,51 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +chdir 't'; + +use MakeMaker::Test::Utils; +use Test::More tests => 6; +use File::Spec; + +my $TB = Test::More->builder; + +BEGIN { use_ok('ExtUtils::MM') } + +my $mm = bless { NAME => "Foo" }, 'MM'; +isa_ok($mm, 'ExtUtils::MakeMaker'); +isa_ok($mm, 'ExtUtils::MM_Any'); + + +sub try_oneliner { + my($code, $switches, $expect, $name) = @_; + my $cmd = $mm->oneliner($code, $switches); + $cmd =~ s{\$\(PERLRUN\)}{$^X}; + + # VMS likes to put newlines at the end of commands if there isn't + # one already. + $expect =~ s/([^\n])\z/$1\n/ if $^O eq 'VMS'; + + $TB->is_eq(scalar `$cmd`, $expect, $name) || $TB->diag("oneliner:\n$cmd"); +} + +# Lets see how it deals with quotes. +try_oneliner(q{print "foo'o", ' bar"ar'}, [], q{foo'o bar"ar}, 'quotes'); + +# How about dollar signs? +try_oneliner(q{$PATH = 'foo'; print $PATH},[], q{foo}, 'dollar signs' ); + +# switches? +try_oneliner(q{print 'foo'}, ['-l'], "foo\n", 'switches' ); + +# XXX gotta rethink the newline test. The Makefile does newline +# escaping, then the shell. + diff --git a/lib/ExtUtils/t/prefixify.t b/lib/ExtUtils/t/prefixify.t index 0f92a4a..644bc00 100644 --- a/lib/ExtUtils/t/prefixify.t +++ b/lib/ExtUtils/t/prefixify.t @@ -17,18 +17,24 @@ if( $^O eq 'VMS' ) { plan skip_all => 'prefixify works differently on VMS'; } else { - plan tests => 2; + plan tests => 3; } +use Config; use File::Spec; use ExtUtils::MM; my $mm = bless {}, 'MM'; my $default = File::Spec->catdir(qw(this that)); + $mm->prefixify('installbin', 'wibble', 'something', $default); +is( $mm->{INSTALLBIN}, $Config{installbin}, + 'prefixify w/defaults'); +$mm->{ARGS}{PREFIX} = 'foo'; +$mm->prefixify('installbin', 'wibble', 'something', $default); is( $mm->{INSTALLBIN}, File::Spec->catdir('something', $default), - 'prefixify w/defaults'); + 'prefixify w/defaults and PREFIX'); { undef *ExtUtils::MM_Unix::Config; diff --git a/lib/ExtUtils/t/prompt.t b/lib/ExtUtils/t/prompt.t new file mode 100644 index 0000000..ec9aa10 --- /dev/null +++ b/lib/ExtUtils/t/prompt.t @@ -0,0 +1,56 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +use strict; +use Test::More tests => 11; +use ExtUtils::MakeMaker; +use TieOut; +use TieIn; + +eval q{ + prompt(); +}; +like( $@, qr/^Not enough arguments for ExtUtils::MakeMaker::prompt/, + 'no args' ); + +eval { + prompt(undef); +}; +like( $@, qr/^prompt function called without an argument/, + 'undef message' ); + +my $stdout = tie *STDOUT, 'TieOut' or die; + + +$ENV{PERL_MM_USE_DEFAULT} = 1; +is( prompt("Foo?"), '', 'no default' ); +like( $stdout->read, qr/^Foo\?\s*\n$/, ' question' ); + +is( prompt("Foo?", undef), '', 'undef default' ); +like( $stdout->read, qr/^Foo\?\s*\n$/, ' question' ); + +is( prompt("Foo?", 'Bar!'), 'Bar!', 'default' ); +like( $stdout->read, qr/^Foo\? \[Bar!\]\s+Bar!\n$/, ' question' ); + + +SKIP: { + skip "eof() doesn't honor ties in 5.5.3", 3 if $] < 5.006; + + $ENV{PERL_MM_USE_DEFAULT} = 0; + close STDIN; + my $stdin = tie *STDIN, 'TieIn' or die; + $stdin->write("From STDIN"); + ok( !-t STDIN, 'STDIN not a tty' ); + + is( prompt("Foo?", 'Bar!'), 'From STDIN', 'from STDIN' ); + like( $stdout->read, qr/^Foo\? \[Bar!\]\s*$/, ' question' ); +} diff --git a/lib/ExtUtils/t/split_command.t b/lib/ExtUtils/t/split_command.t new file mode 100644 index 0000000..49e2629 --- /dev/null +++ b/lib/ExtUtils/t/split_command.t @@ -0,0 +1,66 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +chdir 't'; + +use ExtUtils::MM; +use MakeMaker::Test::Utils; + +my $Is_VMS = $^O eq 'VMS'; +my $Is_Win32 = $^O eq 'MSWin32'; + +use Test::More tests => 7; + +my $perl = which_perl; +my $mm = bless { NAME => "Foo" }, "MM"; + +# I don't expect anything to have a length shorter than 256 chars. +cmp_ok( $mm->max_exec_len, '>=', 256, 'max_exec_len' ); + +my $echo = $mm->oneliner(q{print @ARGV}, ['-l']); + +# Force a short command length to make testing split_command easier. +$mm->{_MAX_EXEC_LEN} = length($echo) + 15; +is( $mm->max_exec_len, $mm->{_MAX_EXEC_LEN}, ' forced a short max_exec_len' ); + +my @test_args = qw(foo bar baz yar car har ackapicklerootyjamboree); +my @cmds = $mm->split_command($echo, @test_args); +isnt( @cmds, 0 ); + +@results = _run(@cmds); +is( join('', @results), join('', @test_args)); + + +my %test_args = ( foo => 42, bar => 23, car => 'har' ); +$even_args = $mm->oneliner(q{print !(@ARGV % 2)}); +@cmds = $mm->split_command($even_args, %test_args); +isnt( @cmds, 0 ); + +@results = _run(@cmds); +like( join('', @results ), qr/^1+$/, 'pairs preserved' ); + +is( $mm->split_command($echo), 0, 'no args means no commands' ); + + +sub _run { + my @cmds = @_; + + s{\$\(PERLRUN\)}{$perl} foreach @cmds; + if( $Is_VMS ) { + s{-\n}{} foreach @cmds + } + elsif( $Is_Win32 ) { + s{\\\n}{} foreach @cmds; + } + + return map { s/\n+$//; $_ } map { `$_` } @cmds +} diff --git a/t/lib/TieIn.pm b/t/lib/TieIn.pm new file mode 100644 index 0000000..a240867 --- /dev/null +++ b/t/lib/TieIn.pm @@ -0,0 +1,23 @@ +package TieIn; + +sub TIEHANDLE { + bless( \(my $scalar), $_[0]); +} + +sub write { + my $self = shift; + $$self .= join '', @_; +} + +sub READLINE { + my $self = shift; + $$self =~ s/^(.*\n?)//; + return $1; +} + +sub EOF { + my $self = shift; + return !length $$self; +} + +1; -- 2.7.4