1*0Sstevel@tonic-gatepackage ExtUtils::MakeMaker::FAQ; 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate(our $VERSION) = sprintf "%03d", q$Revision: 1.9 $ =~ /Revision:\s+(\S+)/; 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gate1; 6*0Sstevel@tonic-gate__END__ 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate=head1 NAME 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gateExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker 11*0Sstevel@tonic-gate 12*0Sstevel@tonic-gate=head1 DESCRIPTION 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gateFAQs, tricks and tips for C<ExtUtils::MakeMaker>. 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gate=head2 Philosophy and History 17*0Sstevel@tonic-gate 18*0Sstevel@tonic-gate=over 4 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gate=item Why not just use <insert other build config tool here>? 21*0Sstevel@tonic-gate 22*0Sstevel@tonic-gateWhy did MakeMaker reinvent the build configuration wheel? Why not 23*0Sstevel@tonic-gatejust use autoconf or automake or ppm or Ant or ... 24*0Sstevel@tonic-gate 25*0Sstevel@tonic-gateThere are many reasons, but the major one is cross-platform 26*0Sstevel@tonic-gatecompatibility. 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gatePerl is one of the most ported pieces of software ever. It works on 29*0Sstevel@tonic-gateoperating systems I've never even heard of (see perlport for details). 30*0Sstevel@tonic-gateIt needs a build tool that can work on all those platforms and with 31*0Sstevel@tonic-gateany wacky C compilers they might have. 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gateNo such build tool existed at the time and I only know of one now 34*0Sstevel@tonic-gate(Module::Build). 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate=item What's Module::Build and how does it relate to MakeMaker? 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gateModule::Build is a project by Ken Williams to supplant MakeMaker. 40*0Sstevel@tonic-gateIts primary advantages are: 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate=over 8 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate=item * pure perl. no make, no shell commands 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate=item * easier to customize 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate=item * cleaner internals 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate=item * less cruft 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate=back 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gateModule::Build is the official heir apparent to MakeMaker and we 55*0Sstevel@tonic-gateencourage people to work on M::B rather than spending time improving 56*0Sstevel@tonic-gateMakeMaker. 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate=back 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate=head2 Module Writing 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate=over 4 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate=item How do I keep my $VERSION up to date without resetting it manually? 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gateOften you want to manually set the $VERSION in the main module 67*0Sstevel@tonic-gatedistribution because this is the version that everybody sees on CPAN 68*0Sstevel@tonic-gateand maybe you want to customize it a bit. But for all the other 69*0Sstevel@tonic-gatemodules in your dist, $VERSION is really just bookkeeping and all that's 70*0Sstevel@tonic-gateimportant is it goes up every time the module is changed. Doing this 71*0Sstevel@tonic-gateby hand is a pain and you often forget. 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gateSimplest way to do it automatically is to use your version control 74*0Sstevel@tonic-gatesystem's revision number (you are using version control, right?). 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gateIn CVS and RCS you use $Z<>Revision$ writing it like so: 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate $VERSION = sprintf "%d.%03d", q$Revision: 1.9 $ =~ /(\d+)/g; 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gateEvery time the file is checked in the $Z<>Revision$ will be updated, 81*0Sstevel@tonic-gateupdating your $VERSION. 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gateIn CVS version 1.9 is followed by 1.10. Since CPAN compares version 84*0Sstevel@tonic-gatenumbers numerically we use a sprintf() to convert 1.9 to 1.009 and 85*0Sstevel@tonic-gate1.10 to 1.010 which compare properly. 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gateIf branches are involved (ie. $Z<>Revision: 1.5.3.4) its a little more 88*0Sstevel@tonic-gatecomplicated. 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gate # must be all on one line or MakeMaker will get confused. 91*0Sstevel@tonic-gate $VERSION = do { my @r = (q$Revision: 1.9 $ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r }; 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate=item What's this F<META.yml> thing and how did it get in my F<MANIFEST>?! 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gateF<META.yml> is a module meta-data file pioneered by Module::Build and 96*0Sstevel@tonic-gateautomatically generated as part of the 'distdir' target (and thus 97*0Sstevel@tonic-gate'dist'). See L<ExtUtils::MakeMaker/"Module Meta-Data">. 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gateTo shut off its generation, pass the C<NO_META> flag to C<WriteMakefile()>. 100*0Sstevel@tonic-gate 101*0Sstevel@tonic-gate=back 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate=head2 XS 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate=over 4 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate=item How to I prevent "object version X.XX does not match bootstrap parameter Y.YY" errors? 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gateXS code is very sensitive to the module version number and will 110*0Sstevel@tonic-gatecomplain if the version number in your Perl module doesn't match. If 111*0Sstevel@tonic-gateyou change your module's version # without reruning Makefile.PL the old 112*0Sstevel@tonic-gateversion number will remain in the Makefile causing the XS code to be built 113*0Sstevel@tonic-gatewith the wrong number. 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gateTo avoid this, you can force the Makefile to be rebuilt whenever you 116*0Sstevel@tonic-gatechange the module containing the version number by adding this to your 117*0Sstevel@tonic-gateWriteMakefile() arguments. 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' } 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate=item How do I make two or more XS files coexist in the same directory? 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gateSometimes you need to have two and more XS files in the same package. 125*0Sstevel@tonic-gateOne way to go is to put them into separate directories, but sometimes 126*0Sstevel@tonic-gatethis is not the most suitable solution. The following technique allows 127*0Sstevel@tonic-gateyou to put two (and more) XS files in the same directory. 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gateLet's assume that we have a package C<Cool::Foo>, which includes 130*0Sstevel@tonic-gateC<Cool::Foo> and C<Cool::Bar> modules each having a separate XS 131*0Sstevel@tonic-gatefile. First we use the following I<Makefile.PL>: 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gate use ExtUtils::MakeMaker; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate WriteMakefile( 136*0Sstevel@tonic-gate NAME => 'Cool::Foo', 137*0Sstevel@tonic-gate VERSION_FROM => 'Foo.pm', 138*0Sstevel@tonic-gate OBJECT => q/$(O_FILES)/, 139*0Sstevel@tonic-gate # ... other attrs ... 140*0Sstevel@tonic-gate ); 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gateNotice the C<OBJECT> attribute. MakeMaker generates the following 143*0Sstevel@tonic-gatevariables in I<Makefile>: 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate # Handy lists of source code files: 146*0Sstevel@tonic-gate XS_FILES= Bar.xs \ 147*0Sstevel@tonic-gate Foo.xs 148*0Sstevel@tonic-gate C_FILES = Bar.c \ 149*0Sstevel@tonic-gate Foo.c 150*0Sstevel@tonic-gate O_FILES = Bar.o \ 151*0Sstevel@tonic-gate Foo.o 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gateTherefore we can use the C<O_FILES> variable to tell MakeMaker to use 154*0Sstevel@tonic-gatethese objects into the shared library. 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gateThat's pretty much it. Now write I<Foo.pm> and I<Foo.xs>, I<Bar.pm> 157*0Sstevel@tonic-gateand I<Bar.xs>, where I<Foo.pm> bootstraps the shared library and 158*0Sstevel@tonic-gateI<Bar.pm> simply loading I<Foo.pm>. 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gateThe only issue left is to how to bootstrap I<Bar.xs>. This is done 161*0Sstevel@tonic-gatefrom I<Foo.xs>: 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate MODULE = Cool::Foo PACKAGE = Cool::Foo 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate BOOT: 166*0Sstevel@tonic-gate # boot the second XS file 167*0Sstevel@tonic-gate boot_Cool__Bar(aTHX_ cv); 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gateIf you have more than two files, this is the place where you should 170*0Sstevel@tonic-gateboot extra XS files from. 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gateThe following four files sum up all the details discussed so far. 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate Foo.pm: 175*0Sstevel@tonic-gate ------- 176*0Sstevel@tonic-gate package Cool::Foo; 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate require DynaLoader; 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate our @ISA = qw(DynaLoader); 181*0Sstevel@tonic-gate our $VERSION = '0.01'; 182*0Sstevel@tonic-gate bootstrap Cool::Foo $VERSION; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate 1; 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate Bar.pm: 187*0Sstevel@tonic-gate ------- 188*0Sstevel@tonic-gate package Cool::Bar; 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate use Cool::Foo; # bootstraps Bar.xs 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate 1; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate Foo.xs: 195*0Sstevel@tonic-gate ------- 196*0Sstevel@tonic-gate #include "EXTERN.h" 197*0Sstevel@tonic-gate #include "perl.h" 198*0Sstevel@tonic-gate #include "XSUB.h" 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate MODULE = Cool::Foo PACKAGE = Cool::Foo 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate BOOT: 203*0Sstevel@tonic-gate # boot the second XS file 204*0Sstevel@tonic-gate boot_Cool__Bar(aTHX_ cv); 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate MODULE = Cool::Foo PACKAGE = Cool::Foo PREFIX = cool_foo_ 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate void 209*0Sstevel@tonic-gate cool_foo_perl_rules() 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate CODE: 212*0Sstevel@tonic-gate fprintf(stderr, "Cool::Foo says: Perl Rules\n"); 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate Bar.xs: 215*0Sstevel@tonic-gate ------- 216*0Sstevel@tonic-gate #include "EXTERN.h" 217*0Sstevel@tonic-gate #include "perl.h" 218*0Sstevel@tonic-gate #include "XSUB.h" 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate MODULE = Cool::Bar PACKAGE = Cool::Bar PREFIX = cool_bar_ 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate void 223*0Sstevel@tonic-gate cool_bar_perl_rules() 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate CODE: 226*0Sstevel@tonic-gate fprintf(stderr, "Cool::Bar says: Perl Rules\n"); 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gateAnd of course a very basic test: 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate test.pl: 231*0Sstevel@tonic-gate -------- 232*0Sstevel@tonic-gate use Test; 233*0Sstevel@tonic-gate BEGIN { plan tests => 1 }; 234*0Sstevel@tonic-gate use Cool::Foo; 235*0Sstevel@tonic-gate use Cool::Bar; 236*0Sstevel@tonic-gate Cool::Foo::perl_rules(); 237*0Sstevel@tonic-gate Cool::Bar::perl_rules(); 238*0Sstevel@tonic-gate ok 1; 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gateThis tip has been brought to you by Nick Ing-Simmons and Stas Bekman. 241*0Sstevel@tonic-gate 242*0Sstevel@tonic-gate=back 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate=head1 PATCHING 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gateIf you have a question you'd like to see added to the FAQ (whether or 247*0Sstevel@tonic-gatenot you have the answer) please send it to makemaker@perl.org. 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate=head1 AUTHOR 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gateThe denizens of makemaker@perl.org. 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate=head1 SEE ALSO 254*0Sstevel@tonic-gate 255*0Sstevel@tonic-gateL<ExtUtils::MakeMaker> 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate=cut 258