1N/Apackage ExtUtils::MakeMaker::FAQ;
1N/A
1N/A(our $VERSION) = sprintf "%03d", q$Revision: 1.9 $ =~ /Revision:\s+(\S+)/;
1N/A
1N/A1;
1N/A__END__
1N/A
1N/A=head1 NAME
1N/A
1N/AExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker
1N/A
1N/A=head1 DESCRIPTION
1N/A
1N/AFAQs, tricks and tips for C<ExtUtils::MakeMaker>.
1N/A
1N/A=head2 Philosophy and History
1N/A
1N/A=over 4
1N/A
1N/A=item Why not just use <insert other build config tool here>?
1N/A
1N/AWhy did MakeMaker reinvent the build configuration wheel? Why not
1N/Ajust use autoconf or automake or ppm or Ant or ...
1N/A
1N/AThere are many reasons, but the major one is cross-platform
1N/Acompatibility.
1N/A
1N/APerl is one of the most ported pieces of software ever. It works on
1N/Aoperating systems I've never even heard of (see perlport for details).
1N/AIt needs a build tool that can work on all those platforms and with
1N/Aany wacky C compilers they might have.
1N/A
1N/ANo such build tool existed at the time and I only know of one now
1N/A(Module::Build).
1N/A
1N/A
1N/A=item What's Module::Build and how does it relate to MakeMaker?
1N/A
1N/AModule::Build is a project by Ken Williams to supplant MakeMaker.
1N/AIts primary advantages are:
1N/A
1N/A=over 8
1N/A
1N/A=item * pure perl. no make, no shell commands
1N/A
1N/A=item * easier to customize
1N/A
1N/A=item * cleaner internals
1N/A
1N/A=item * less cruft
1N/A
1N/A=back
1N/A
1N/AModule::Build is the official heir apparent to MakeMaker and we
1N/Aencourage people to work on M::B rather than spending time improving
1N/AMakeMaker.
1N/A
1N/A=back
1N/A
1N/A=head2 Module Writing
1N/A
1N/A=over 4
1N/A
1N/A=item How do I keep my $VERSION up to date without resetting it manually?
1N/A
1N/AOften you want to manually set the $VERSION in the main module
1N/Adistribution because this is the version that everybody sees on CPAN
1N/Aand maybe you want to customize it a bit. But for all the other
1N/Amodules in your dist, $VERSION is really just bookkeeping and all that's
1N/Aimportant is it goes up every time the module is changed. Doing this
1N/Aby hand is a pain and you often forget.
1N/A
1N/ASimplest way to do it automatically is to use your version control
1N/Asystem's revision number (you are using version control, right?).
1N/A
1N/AIn CVS and RCS you use $Z<>Revision$ writing it like so:
1N/A
1N/A $VERSION = sprintf "%d.%03d", q$Revision: 1.9 $ =~ /(\d+)/g;
1N/A
1N/AEvery time the file is checked in the $Z<>Revision$ will be updated,
1N/Aupdating your $VERSION.
1N/A
1N/AIn CVS version 1.9 is followed by 1.10. Since CPAN compares version
1N/Anumbers numerically we use a sprintf() to convert 1.9 to 1.009 and
1N/A1.10 to 1.010 which compare properly.
1N/A
1N/AIf branches are involved (ie. $Z<>Revision: 1.5.3.4) its a little more
1N/Acomplicated.
1N/A
1N/A # must be all on one line or MakeMaker will get confused.
1N/A $VERSION = do { my @r = (q$Revision: 1.9 $ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r };
1N/A
1N/A=item What's this F<META.yml> thing and how did it get in my F<MANIFEST>?!
1N/A
1N/AF<META.yml> is a module meta-data file pioneered by Module::Build and
1N/Aautomatically generated as part of the 'distdir' target (and thus
1N/A'dist'). See L<ExtUtils::MakeMaker/"Module Meta-Data">.
1N/A
1N/ATo shut off its generation, pass the C<NO_META> flag to C<WriteMakefile()>.
1N/A
1N/A=back
1N/A
1N/A=head2 XS
1N/A
1N/A=over 4
1N/A
1N/A=item How to I prevent "object version X.XX does not match bootstrap parameter Y.YY" errors?
1N/A
1N/AXS code is very sensitive to the module version number and will
1N/Acomplain if the version number in your Perl module doesn't match. If
1N/Ayou change your module's version # without reruning Makefile.PL the old
1N/Aversion number will remain in the Makefile causing the XS code to be built
1N/Awith the wrong number.
1N/A
1N/ATo avoid this, you can force the Makefile to be rebuilt whenever you
1N/Achange the module containing the version number by adding this to your
1N/AWriteMakefile() arguments.
1N/A
1N/A depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' }
1N/A
1N/A
1N/A=item How do I make two or more XS files coexist in the same directory?
1N/A
1N/ASometimes you need to have two and more XS files in the same package.
1N/AOne way to go is to put them into separate directories, but sometimes
1N/Athis is not the most suitable solution. The following technique allows
1N/Ayou to put two (and more) XS files in the same directory.
1N/A
1N/ALet's assume that we have a package C<Cool::Foo>, which includes
1N/AC<Cool::Foo> and C<Cool::Bar> modules each having a separate XS
1N/Afile. First we use the following I<Makefile.PL>:
1N/A
1N/A use ExtUtils::MakeMaker;
1N/A
1N/A WriteMakefile(
1N/A NAME => 'Cool::Foo',
1N/A VERSION_FROM => 'Foo.pm',
1N/A OBJECT => q/$(O_FILES)/,
1N/A # ... other attrs ...
1N/A );
1N/A
1N/ANotice the C<OBJECT> attribute. MakeMaker generates the following
1N/Avariables in I<Makefile>:
1N/A
1N/A # Handy lists of source code files:
1N/A XS_FILES= Bar.xs \
1N/A Foo.xs
1N/A C_FILES = Bar.c \
1N/A Foo.c
1N/A O_FILES = Bar.o \
1N/A Foo.o
1N/A
1N/ATherefore we can use the C<O_FILES> variable to tell MakeMaker to use
1N/Athese objects into the shared library.
1N/A
1N/AThat's pretty much it. Now write I<Foo.pm> and I<Foo.xs>, I<Bar.pm>
1N/Aand I<Bar.xs>, where I<Foo.pm> bootstraps the shared library and
1N/AI<Bar.pm> simply loading I<Foo.pm>.
1N/A
1N/AThe only issue left is to how to bootstrap I<Bar.xs>. This is done
1N/Afrom I<Foo.xs>:
1N/A
1N/A MODULE = Cool::Foo PACKAGE = Cool::Foo
1N/A
1N/A BOOT:
1N/A # boot the second XS file
1N/A boot_Cool__Bar(aTHX_ cv);
1N/A
1N/AIf you have more than two files, this is the place where you should
1N/Aboot extra XS files from.
1N/A
1N/AThe following four files sum up all the details discussed so far.
1N/A
1N/A Foo.pm:
1N/A -------
1N/A package Cool::Foo;
1N/A
1N/A require DynaLoader;
1N/A
1N/A our @ISA = qw(DynaLoader);
1N/A our $VERSION = '0.01';
1N/A bootstrap Cool::Foo $VERSION;
1N/A
1N/A 1;
1N/A
1N/A Bar.pm:
1N/A -------
1N/A package Cool::Bar;
1N/A
1N/A use Cool::Foo; # bootstraps Bar.xs
1N/A
1N/A 1;
1N/A
1N/A Foo.xs:
1N/A -------
1N/A #include "EXTERN.h"
1N/A #include "perl.h"
1N/A #include "XSUB.h"
1N/A
1N/A MODULE = Cool::Foo PACKAGE = Cool::Foo
1N/A
1N/A BOOT:
1N/A # boot the second XS file
1N/A boot_Cool__Bar(aTHX_ cv);
1N/A
1N/A MODULE = Cool::Foo PACKAGE = Cool::Foo PREFIX = cool_foo_
1N/A
1N/A void
1N/A cool_foo_perl_rules()
1N/A
1N/A CODE:
1N/A fprintf(stderr, "Cool::Foo says: Perl Rules\n");
1N/A
1N/A Bar.xs:
1N/A -------
1N/A #include "EXTERN.h"
1N/A #include "perl.h"
1N/A #include "XSUB.h"
1N/A
1N/A MODULE = Cool::Bar PACKAGE = Cool::Bar PREFIX = cool_bar_
1N/A
1N/A void
1N/A cool_bar_perl_rules()
1N/A
1N/A CODE:
1N/A fprintf(stderr, "Cool::Bar says: Perl Rules\n");
1N/A
1N/AAnd of course a very basic test:
1N/A
1N/A test.pl:
1N/A --------
1N/A use Test;
1N/A BEGIN { plan tests => 1 };
1N/A use Cool::Foo;
1N/A use Cool::Bar;
1N/A Cool::Foo::perl_rules();
1N/A Cool::Bar::perl_rules();
1N/A ok 1;
1N/A
1N/AThis tip has been brought to you by Nick Ing-Simmons and Stas Bekman.
1N/A
1N/A=back
1N/A
1N/A=head1 PATCHING
1N/A
1N/AIf you have a question you'd like to see added to the FAQ (whether or
1N/Anot you have the answer) please send it to makemaker@perl.org.
1N/A
1N/A=head1 AUTHOR
1N/A
1N/AThe denizens of makemaker@perl.org.
1N/A
1N/A=head1 SEE ALSO
1N/A
1N/AL<ExtUtils::MakeMaker>
1N/A
1N/A=cut