| package ExtUtils::MakeMaker::FAQ; |
| |
| our $VERSION = '7.32'; |
| $VERSION = eval $VERSION; |
| |
| 1; |
| __END__ |
| |
| =head1 NAME |
| |
| ExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker |
| |
| =head1 DESCRIPTION |
| |
| FAQs, tricks and tips for C<ExtUtils::MakeMaker>. |
| |
| |
| =head2 Module Installation |
| |
| =over 4 |
| |
| =item How do I install a module into my home directory? |
| |
| If you're not the Perl administrator you probably don't have |
| permission to install a module to its default location. Ways of handling |
| this with a B<lot> less manual effort on your part are L<perlbrew> |
| and L<local::lib>. |
| |
| Otherwise, you can install it for your own use into your home directory |
| like so: |
| |
| # Non-unix folks, replace ~ with /path/to/your/home/dir |
| perl Makefile.PL INSTALL_BASE=~ |
| |
| This will put modules into F<~/lib/perl5>, man pages into F<~/man> and |
| programs into F<~/bin>. |
| |
| To ensure your Perl programs can see these newly installed modules, |
| set your C<PERL5LIB> environment variable to F<~/lib/perl5> or tell |
| each of your programs to look in that directory with the following: |
| |
| use lib "$ENV{HOME}/lib/perl5"; |
| |
| or if $ENV{HOME} isn't set and you don't want to set it for some |
| reason, do it the long way. |
| |
| use lib "/path/to/your/home/dir/lib/perl5"; |
| |
| =item How do I get MakeMaker and Module::Build to install to the same place? |
| |
| Module::Build, as of 0.28, supports two ways to install to the same |
| location as MakeMaker. |
| |
| We highly recommend the install_base method, its the simplest and most |
| closely approximates the expected behavior of an installation prefix. |
| |
| 1) Use INSTALL_BASE / C<--install_base> |
| |
| MakeMaker (as of 6.31) and Module::Build (as of 0.28) both can install |
| to the same locations using the "install_base" concept. See |
| L<ExtUtils::MakeMaker/INSTALL_BASE> for details. To get MM and MB to |
| install to the same location simply set INSTALL_BASE in MM and |
| C<--install_base> in MB to the same location. |
| |
| perl Makefile.PL INSTALL_BASE=/whatever |
| perl Build.PL --install_base /whatever |
| |
| This works most like other language's behavior when you specify a |
| prefix. We recommend this method. |
| |
| 2) Use PREFIX / C<--prefix> |
| |
| Module::Build 0.28 added support for C<--prefix> which works like |
| MakeMaker's PREFIX. |
| |
| perl Makefile.PL PREFIX=/whatever |
| perl Build.PL --prefix /whatever |
| |
| We highly discourage this method. It should only be used if you know |
| what you're doing and specifically need the PREFIX behavior. The |
| PREFIX algorithm is complicated and focused on matching the system |
| installation. |
| |
| =item How do I keep from installing man pages? |
| |
| Recent versions of MakeMaker will only install man pages on Unix-like |
| operating systems. |
| |
| For an individual module: |
| |
| perl Makefile.PL INSTALLMAN1DIR=none INSTALLMAN3DIR=none |
| |
| If you want to suppress man page installation for all modules you have |
| to reconfigure Perl and tell it 'none' when it asks where to install |
| man pages. |
| |
| |
| =item How do I use a module without installing it? |
| |
| Two ways. One is to build the module normally... |
| |
| perl Makefile.PL |
| make |
| make test |
| |
| ...and then use L<blib> to point Perl at the built but uninstalled module: |
| |
| perl -Mblib script.pl |
| perl -Mblib -e '...' |
| |
| The other is to install the module in a temporary location. |
| |
| perl Makefile.PL INSTALL_BASE=~/tmp |
| make |
| make test |
| make install |
| |
| And then set PERL5LIB to F<~/tmp/lib/perl5>. This works well when you |
| have multiple modules to work with. It also ensures that the module |
| goes through its full installation process which may modify it. |
| Again, L<local::lib> may assist you here. |
| |
| =item How can I organize tests into subdirectories and have them run? |
| |
| Let's take the following test directory structure: |
| |
| t/foo/sometest.t |
| t/bar/othertest.t |
| t/bar/baz/anothertest.t |
| |
| Now, inside of the C<WriteMakeFile()> function in your F<Makefile.PL>, specify |
| where your tests are located with the C<test> directive: |
| |
| test => {TESTS => 't/*.t t/*/*.t t/*/*/*.t'} |
| |
| The first entry in the string will run all tests in the top-level F<t/> |
| directory. The second will run all test files located in any subdirectory under |
| F<t/>. The third, runs all test files within any subdirectory within any other |
| subdirectory located under F<t/>. |
| |
| Note that you do not have to use wildcards. You can specify explicitly which |
| subdirectories to run tests in: |
| |
| test => {TESTS => 't/*.t t/foo/*.t t/bar/baz/*.t'} |
| |
| =item PREFIX vs INSTALL_BASE from Module::Build::Cookbook |
| |
| The behavior of PREFIX is complicated and depends closely on how your |
| Perl is configured. The resulting installation locations will vary |
| from machine to machine and even different installations of Perl on the |
| same machine. Because of this, its difficult to document where prefix |
| will place your modules. |
| |
| In contrast, INSTALL_BASE has predictable, easy to explain installation |
| locations. Now that Module::Build and MakeMaker both have INSTALL_BASE |
| there is little reason to use PREFIX other than to preserve your existing |
| installation locations. If you are starting a fresh Perl installation we |
| encourage you to use INSTALL_BASE. If you have an existing installation |
| installed via PREFIX, consider moving it to an installation structure |
| matching INSTALL_BASE and using that instead. |
| |
| =item Generating *.pm files with substitutions eg of $VERSION |
| |
| If you want to configure your module files for local conditions, or to |
| automatically insert a version number, you can use EUMM's C<PL_FILES> |
| capability, where it will automatically run each F<*.PL> it finds to |
| generate its basename. For instance: |
| |
| # Makefile.PL: |
| require 'common.pl'; |
| my $version = get_version(); |
| my @pms = qw(Foo.pm); |
| WriteMakefile( |
| NAME => 'Foo', |
| VERSION => $version, |
| PM => { map { ($_ => "\$(INST_LIB)/$_") } @pms }, |
| clean => { FILES => join ' ', @pms }, |
| ); |
| |
| # common.pl: |
| sub get_version { '0.04' } |
| sub process { my $v = get_version(); s/__VERSION__/$v/g; } |
| 1; |
| |
| # Foo.pm.PL: |
| require 'common.pl'; |
| $_ = join '', <DATA>; |
| process(); |
| my $file = shift; |
| open my $fh, '>', $file or die "$file: $!"; |
| print $fh $_; |
| __DATA__ |
| package Foo; |
| our $VERSION = '__VERSION__'; |
| 1; |
| |
| You may notice that C<PL_FILES> is not specified above, since the default |
| of mapping each .PL file to its basename works well. |
| |
| If the generated module were architecture-specific, you could replace |
| C<$(INST_LIB)> above with C<$(INST_ARCHLIB)>, although if you locate |
| modules under F<lib>, that would involve ensuring any C<lib/> in front |
| of the module location were removed. |
| |
| =back |
| |
| =head2 Common errors and problems |
| |
| =over 4 |
| |
| =item "No rule to make target `/usr/lib/perl5/CORE/config.h', needed by `Makefile'" |
| |
| Just what it says, you're missing that file. MakeMaker uses it to |
| determine if perl has been rebuilt since the Makefile was made. It's |
| a bit of a bug that it halts installation. |
| |
| Some operating systems don't ship the CORE directory with their base |
| perl install. To solve the problem, you likely need to install a perl |
| development package such as perl-devel (CentOS, Fedora and other |
| Redhat systems) or perl (Ubuntu and other Debian systems). |
| |
| =back |
| |
| =head2 Philosophy and History |
| |
| =over 4 |
| |
| =item Why not just use <insert other build config tool here>? |
| |
| 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 and linkers they might have. |
| |
| No such build tool exists. Even make itself has wildly different |
| dialects. So we have to build our own. |
| |
| |
| =item What is 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 was long the official heir apparent to MakeMaker. The |
| rate of both its development and adoption has slowed in recent years, |
| though, and it is unclear what the future holds for it. That said, |
| Module::Build set the stage for I<something> to become the heir to |
| MakeMaker. MakeMaker's maintainers have long said that it is a dead |
| end and should be kept functioning, while being cautious about extending |
| with new features. |
| |
| =back |
| |
| =head2 Module Writing |
| |
| =over 4 |
| |
| =item How do I keep my $VERSION up to date without resetting it manually? |
| |
| Often you want to manually set the $VERSION in the main module |
| distribution because this is the version that everybody sees on CPAN |
| and maybe you want to customize it a bit. But for all the other |
| modules in your dist, $VERSION is really just bookkeeping and all that's |
| important is it goes up every time the module is changed. Doing this |
| by hand is a pain and you often forget. |
| |
| Probably the easiest way to do this is using F<perl-reversion> in |
| L<Perl::Version>: |
| |
| perl-reversion -bump |
| |
| If your version control system supports revision numbers (git doesn't |
| easily), the simplest way to do it automatically is to use its revision |
| number (you are using version control, right?). |
| |
| In CVS, RCS and SVN you use $Revision$ (see the documentation of your |
| version control system for details). Every time the file is checked |
| in the $Revision$ will be updated, updating your $VERSION. |
| |
| SVN uses a simple integer for $Revision$ so you can adapt it for your |
| $VERSION like so: |
| |
| ($VERSION) = q$Revision$ =~ /(\d+)/; |
| |
| In CVS and RCS version 1.9 is followed by 1.10. Since CPAN compares |
| version numbers numerically we use a sprintf() to convert 1.9 to 1.009 |
| and 1.10 to 1.010 which compare properly. |
| |
| $VERSION = sprintf "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/g; |
| |
| If branches are involved (ie. $Revision: 1.5.3.4$) it's a little more |
| complicated. |
| |
| # must be all on one line or MakeMaker will get confused. |
| $VERSION = do { my @r = (q$Revision$ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r }; |
| |
| In SVN, $Revision$ should be the same for every file in the project so |
| they would all have the same $VERSION. CVS and RCS have a different |
| $Revision$ per file so each file will have a different $VERSION. |
| Distributed version control systems, such as SVK, may have a different |
| $Revision$ based on who checks out the file, leading to a different $VERSION |
| on each machine! Finally, some distributed version control systems, such |
| as darcs, have no concept of revision number at all. |
| |
| |
| =item What's this F<META.yml> thing and how did it get in my F<MANIFEST>?! |
| |
| F<META.yml> is a module meta-data file pioneered by Module::Build and |
| automatically generated as part of the 'distdir' target (and thus |
| 'dist'). See L<ExtUtils::MakeMaker/"Module Meta-Data">. |
| |
| To shut off its generation, pass the C<NO_META> flag to C<WriteMakefile()>. |
| |
| |
| =item How do I delete everything not in my F<MANIFEST>? |
| |
| Some folks are surprised that C<make distclean> does not delete |
| everything not listed in their MANIFEST (thus making a clean |
| distribution) but only tells them what they need to delete. This is |
| done because it is considered too dangerous. While developing your |
| module you might write a new file, not add it to the MANIFEST, then |
| run a C<distclean> and be sad because your new work was deleted. |
| |
| If you really want to do this, you can use |
| C<ExtUtils::Manifest::manifind()> to read the MANIFEST and File::Find |
| to delete the files. But you have to be careful. Here's a script to |
| do that. Use at your own risk. Have fun blowing holes in your foot. |
| |
| #!/usr/bin/perl -w |
| |
| use strict; |
| |
| use File::Spec; |
| use File::Find; |
| use ExtUtils::Manifest qw(maniread); |
| |
| my %manifest = map {( $_ => 1 )} |
| grep { File::Spec->canonpath($_) } |
| keys %{ maniread() }; |
| |
| if( !keys %manifest ) { |
| print "No files found in MANIFEST. Stopping.\n"; |
| exit; |
| } |
| |
| find({ |
| wanted => sub { |
| my $path = File::Spec->canonpath($_); |
| |
| return unless -f $path; |
| return if exists $manifest{ $path }; |
| |
| print "unlink $path\n"; |
| unlink $path; |
| }, |
| no_chdir => 1 |
| }, |
| "." |
| ); |
| |
| |
| =item Which tar should I use on Windows? |
| |
| We recommend ptar from Archive::Tar not older than 1.66 with '-C' option. |
| |
| =item Which zip should I use on Windows for '[ndg]make zipdist'? |
| |
| We recommend InfoZIP: L<http://www.info-zip.org/Zip.html> |
| |
| |
| =back |
| |
| =head2 XS |
| |
| =over 4 |
| |
| =item How do I prevent "object version X.XX does not match bootstrap parameter Y.YY" errors? |
| |
| XS code is very sensitive to the module version number and will |
| complain if the version number in your Perl module doesn't match. If |
| you change your module's version # without rerunning Makefile.PL the old |
| version number will remain in the Makefile, causing the XS code to be built |
| with the wrong number. |
| |
| To avoid this, you can force the Makefile to be rebuilt whenever you |
| change the module containing the version number by adding this to your |
| WriteMakefile() arguments. |
| |
| depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' } |
| |
| |
| =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. |
| There are three ways: C<XSMULTI>, separate directories, and bootstrapping |
| one XS from another. |
| |
| =over 8 |
| |
| =item XSMULTI |
| |
| Structure your modules so they are all located under F<lib>, such that |
| C<Foo::Bar> is in F<lib/Foo/Bar.pm> and F<lib/Foo/Bar.xs>, etc. Have your |
| top-level C<WriteMakefile> set the variable C<XSMULTI> to a true value. |
| |
| Er, that's it. |
| |
| =item Separate directories |
| |
| Put each XS files into separate directories, each with their own |
| F<Makefile.PL>. Make sure each of those F<Makefile.PL>s has the correct |
| C<CFLAGS>, C<INC>, C<LIBS> etc. You will need to make sure the top-level |
| F<Makefile.PL> refers to each of these using C<DIR>. |
| |
| =item Bootstrapping |
| |
| Let's assume that we have a package C<Cool::Foo>, which includes |
| C<Cool::Foo> and C<Cool::Bar> modules each having a separate XS |
| file. First we use the following I<Makefile.PL>: |
| |
| use ExtUtils::MakeMaker; |
| |
| WriteMakefile( |
| NAME => 'Cool::Foo', |
| VERSION_FROM => 'Foo.pm', |
| OBJECT => q/$(O_FILES)/, |
| # ... other attrs ... |
| ); |
| |
| Notice the C<OBJECT> attribute. MakeMaker generates the following |
| variables in I<Makefile>: |
| |
| # 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<O_FILES> variable to tell MakeMaker to use |
| these objects into the shared library. |
| |
| That's pretty much it. Now write I<Foo.pm> and I<Foo.xs>, I<Bar.pm> |
| and I<Bar.xs>, where I<Foo.pm> bootstraps the shared library and |
| I<Bar.pm> simply loading I<Foo.pm>. |
| |
| The only issue left is to how to bootstrap I<Bar.xs>. This is done |
| from I<Foo.xs>: |
| |
| 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: |
| |
| t/cool.t: |
| -------- |
| 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. |
| |
| An alternative way to achieve this can be seen in L<Gtk2::CodeGen> |
| and L<Glib::CodeGen>. |
| |
| =back |
| |
| =back |
| |
| =head1 DESIGN |
| |
| =head2 MakeMaker object hierarchy (simplified) |
| |
| What most people need to know (superclasses on top.) |
| |
| ExtUtils::MM_Any |
| | |
| ExtUtils::MM_Unix |
| | |
| ExtUtils::MM_{Current OS} |
| | |
| ExtUtils::MakeMaker |
| | |
| MY |
| |
| 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. |
| |
| =head2 MakeMaker object hierarchy (real) |
| |
| Here's how it really works: |
| |
| ExtUtils::MM_Any |
| | |
| ExtUtils::MM_Unix |
| | |
| ExtUtils::Liblist::Kid ExtUtils::MM_{Current OS} (if necessary) |
| | | |
| ExtUtils::Liblist ExtUtils::MakeMaker | |
| | | | |
| | | |----------------------- |
| ExtUtils::MM |
| | | |
| ExtUtils::MY MM (created by ExtUtils::MM) |
| | | |
| MY (created by ExtUtils::MY) | |
| . | |
| (mixin) | |
| . | |
| PACK### (created each call to ExtUtils::MakeMaker->new) |
| |
| NOTE: Yes, this is a mess. See |
| L<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 chosen based on your operating system. |
| |
| 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 ExtUtils::MM_{Current OS} |
| |
| 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 inheritance hiearchy |
| and simply be called as functions. |
| |
| NOTE: Modules like File::Spec and Exporter have been omitted for clarity. |
| |
| |
| =head2 The MM_* hierarchy |
| |
| MM_Win95 MM_NW5 |
| \ / |
| MM_BeOS MM_Cygwin MM_OS2 MM_VMS MM_Win32 MM_DOS 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. |
| |
| =head1 PATCHING |
| |
| If you have a question you'd like to see added to the FAQ (whether or |
| not you have the answer) please either: |
| |
| =over 2 |
| |
| =item * make a pull request on the MakeMaker github repository |
| |
| =item * raise a issue on the MakeMaker github repository |
| |
| =item * file an RT ticket |
| |
| =item * email makemaker@perl.org |
| |
| =back |
| |
| =head1 AUTHOR |
| |
| The denizens of makemaker@perl.org. |
| |
| =head1 SEE ALSO |
| |
| L<ExtUtils::MakeMaker> |
| |
| =cut |