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