Upgrade to Devel::PPPort 3.11_06
[p5sagit/p5-mst-13.2.git] / ext / Devel / PPPort / HACKERS
CommitLineData
adfe19db 1=head1 NAME
2
3HACKERS - Devel::PPPort internals for hackers
4
5=head1 SYNOPSIS
6
7So you probably want to hack C<Devel::PPPort>?
8
9Well, here's some information to get you started with what's
10lying around in this distribution.
11
12=head1 DESCRIPTION
13
af36fda7 14=head2 How to build 111 versions of Perl
adfe19db 15
16C<Devel::PPPort> supports Perl versions between 5.003 and bleadperl.
17To guarantee this support, I need some of these versions on my
af36fda7 18machine. I currently have 111 different Perl version/configuration
adfe19db 19combinations installed on my laptop.
20
21As many of the old Perl distributions need patching to compile
af36fda7 22cleanly on newer systems (and because building 111 Perls by hand
adfe19db 23just isn't fun), I wrote a tool to build all the different
24versions and configurations. You can find it in F<devel/buildperl.pl>.
25It can currently build the following Perl releases:
26
27 5.003
28 5.004 - 5.004_05
29 5.005 - 5.005_04
30 5.6.x
31 5.7.x
32 5.8.x
33 5.9.x
34
35=head2 Fully automatic API checks
36
37Knowing which parts of the API are not backwards compatible and
38probably need C<Devel::PPPort> support is another problem that's
39not easy to deal with manually. If you run
40
41 perl Makefile.PL --with-apicheck
42
43a C file is generated by F<parts/apicheck.pl> that is compiled
44and linked with C<Devel::PPPort>. This C file has the purpose of
45using each of the public API functions/macros once.
46
47The required information is derived from C<parts/embed.fnc> (just
679ad62d 48a copy of bleadperl's C<embed.fnc>), C<parts/apidoc.fnc> (which
adfe19db 49is generated by F<devel/mkapidoc.sh> and simply collects the rest
679ad62d 50of the apidoc entries spread over the Perl source code) and
51C<parts/ppport.fnc> (which lists all API provided purely by
52Devel::PPPort).
adfe19db 53The generated C file C<apicheck.c> is currently about 500k in size
54and takes quite a while to compile.
55
56Usually, C<apicheck.c> won't compile with older perls. And even if
57it compiles, there's still a good chance of the dynamic linker
58failing at C<make test> time. But that's on purpose!
59
60We can use these failures to find changes in the API automatically.
61The two Perl scripts F<devel/mktodo> and F<devel/mktodo.pl>
62repeatedly run C<Devel::PPPort> with the apicheck code through
63all different versions of perl. Scanning the output of the compiler
64and the dynamic linker for errors, the files in F<parts/todo/> are
65generated. These files list all parts of the public API that don't
66work with less than a certain version of Perl.
67
68This information is in turn used by F<parts/apicheck.pl> to mask
69API calls in the generated C file for these versions, so the
70process can be stopped by the time F<apicheck.c> compiles cleanly
ba120f6f 71and the dynamic linker is happy. (Actually, this process may generate
72false positives, so by default each API call is checked once more
73afterwards.)
adfe19db 74
ba120f6f 75Running C<devel/mktodo> takes about an hour, depending of course
76on the machine you're running it on. If you run it with
77the C<--nocheck> option, it won't recheck the API calls that failed
78in the compilation stage and it'll take significantly less time.
79Running with C<--nocheck> should usually be safe.
adfe19db 80
81When running C<devel/mktodo> with the C<--base> option, it will
82generate the I<baseline> todo files by disabling all functionality
83provided by C<Devel::PPPort>. These are required for implementing
84the C<--compat-version> option of the C<ppport.h> script. The
85baseline todo files hold the information about which version of
86Perl lacks a certain part of the API.
87
88However, only the documented public API can be checked this way.
89And since C<Devel::PPPort> provides more macros, these would not be
90affected by C<--compat-version>. It's the job of F<devel/scanprov>
91to figure out the baseline information for all remaining provided
92macros by scanning the include files in the F<CORE> directory of
93various Perl versions.
94
ba120f6f 95The whole process isn't platform independent. It has currently been
96tested only under Linux, and it definitely requires at least C<gcc> and
97the C<nm> utility.
98
99It's not very often that one has to regenerate the baseline and todo
100files. If you have to, you can either run F<devel/regenerate> or just
101execute the following steps by hand:
adfe19db 102
103=over 4
104
105=item *
106
107You need a whole bunch of different Perls. The more, the better.
108You can use F<devel/buildperl.pl> to build them. I keep my perls
109in F</tmp/perl>, so most of the tools take this as a default.
110
111=item *
112
56093a11 113You also need a freshly built bleadperl that is in the path under
114exactly this name. (The name of the executable is currently hardcoded
115in F<devel/mktodo> and F<devel/scanprov>.)
116
117=item *
118
adfe19db 119Remove all existing todo files in the F<parts/base> and
120F<parts/todo> directories.
121
122=item *
123
124Update the API information. Copy the latest F<embed.fnc> file from
125bleadperl to the F<parts> directory and run F<devel/mkapidoc.sh> to
126collect the remaining information in F<parts/apidoc.fnc>.
127
128=item *
129
130Build the new baseline by running
131
132 perl devel/mktodo --base
133
134in the root directory of the distribution. When it's finished,
135move all files from the F<parts/todo> directory to F<parts/base>.
136
137=item *
138
139Build the new todo files by running
140
141 perl devel/mktodo
142
143in the root directory of the distribution.
144
145=item *
146
147Finally, add the remaining baseline information by running
148
4a582685 149 perl Makefile.PL && make
150 perl devel/scanprov write
adfe19db 151
152=back
153
154=head2 Implementation
155
156Residing in F<parts/inc/> is the "heart" of C<Devel::PPPort>. Each
157of the files implements a part of the supported API, along with
158hints, dependency information, XS code and tests.
159The files are in a POD-like format that is parsed using the
160functions in F<parts/ppptools.pl>.
161
162The scripts F<PPPort_pm.PL>, F<PPPort_xs.PL> and F<mktests.PL> all
163use the information in F<parts/inc/> to generate the main module
1d088ed8 164F<PPPort.pm>, the XS code in F<RealPPPort.xs> and various test files
adfe19db 165in F<t/>.
166
167All of these files could be generated on the fly while building
1d088ed8 168C<Devel::PPPort>, but not having the tests in C<t/> will confuse
169TEST/harness in the core. Not having F<PPPort.pm> will be bad for
170viewing the docs on C<search.cpan.org>. So unfortunately, it's
171unavoidable to put some redundancy into the package.
adfe19db 172
173=head2 Adding stuff to Devel::PPPort
174
175First, check if the code you plan to add fits into one of the
176existing files in F<parts/inc/>. If not, just start a new one and
177remember to include it from within F<PPPort_pm.PL>.
178
179Each file holds all relevant data for implementing a certain part
180of the API:
181
182=over 2
183
184=item *
185
186A list of the provided API in the C<=provides> section.
187
188=item *
189
190The implementation to add to F<ppport.h> in the C<=implementation>
191section.
192
193=item *
194
195The code required to add to PPPort.xs for testing the implementation.
196This code goes into the C<=xshead>, C<=xsinit>, C<=xsmisc>, C<=xsboot>
0d0f8426 197and C<=xsubs> section. Have a look at the template at the bottom
198of F<PPPort_xs.PL> to see where the code ends up.
adfe19db 199
200=item *
201
202The tests in the C<=tests> section. Remember not to use any fancy
203modules or syntax elements, as the test code should be able to run
204with Perl 5.003, which, for example, doesn't support C<my> in
205C<for>-loops:
206
0d0f8426 207 for my $x (1, 2, 3) { } # won't work with 5.003
adfe19db 208
0d0f8426 209You can use C<ok()> to report success or failure:
210
211 ok($got == 42);
212 ok($got, $expected);
213
214Regular expressions are not supported as the second argument to C<ok>,
215because older perls do not support the C<qr> operator.
adfe19db 216
217=back
218
219It's usually the best approach to just copy an existing file and
220use it as a template.
221
0d0f8426 222=head2 Implementation Hints
223
224In the C<=implementation> section, you can use
225
226 __UNDEFINED__ macro some definition
227
228instead of
229
230 #ifndef macro
231 # define macro some definition
232 #endif
233
234The macro can have optional arguments and the definition can even
235span multiple lines, like in
236
237 __UNDEFINED__ SvMAGIC_set(sv, val) \
238 STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
239 (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END
240
241This usually makes the code more compact and readable. And you
242only have to add C<__UNDEFINED__> to the C<=provided> section.
243
244Version checking can be tricky if you want to do it correct.
245You can use
246
247 #if { VERSION < 5.9.3 }
248
249instead of
250
251 #if ((PERL_VERSION < 9) || (PERL_VERSION == 9 && PERL_SUBVERSION < 3))
252
253The version number can be either of the new form C<5.x.x> or of the older
254form C<5.00x_yy>. Both are translated into the correct preprocessor
255statements. It is also possible to combine this with other statements:
256
257 #if { VERSION >= 5.004 } && !defined(sv_vcatpvf)
258 /* a */
259 #elif { VERSION < 5.004_63 } && { VERSION != 5.004_05 }
260 /* b */
261 #endif
262
263This not only works in the C<=implementation> section, but also in
264the C<=xsubs>, C<=xsinit>, C<=xsmisc>, C<=xshead> and C<=xsboot> sections.
265
adfe19db 266=head2 Testing
267
268To automatically test C<Devel::PPPort> with lots of different Perl
269versions, you can use the F<soak> script. Just pass it a list of
270all Perl binaries you want to test.
271
272=head2 Special Makefile targets
273
4a582685 274You can use
adfe19db 275
276 make regen
277
4a582685 278to regenerate all of the autogenerated files. To get rid of all
279generated files (except for F<parts/todo/*> and F<parts/base/*>),
280use
adfe19db 281
282 make purge_all
283
284That's it.
285
0d0f8426 286=head2 Submitting Patches
287
288If you've added some functionality to C<Devel::PPPort>, please
289consider submitting a patch with your work to either the author
290(E<lt>mhx@cpan.orgE<gt>) or to the CPAN Request Tracker at
291L<http://rt.cpan.org>.
292
293When submitting patches, please only add the relevant changes
294and don't include the differences of the generated files. You
295can use the C<purge_all> target to delete all autogenerated
296files.
297
56093a11 298=head2 Integrating into the Perl core
299
300When integrating this module into the Perl core, be sure to
301remove the following files from the distribution. They are
302either not needed or generated on the fly when building this
303module in the core:
304
305 MANIFEST
306 META.yml
307 PPPort.pm
308
adfe19db 309=head1 COPYRIGHT
310
d2dacc4f 311Version 3.x, Copyright (C) 2004-2007, Marcus Holland-Moritz.
adfe19db 312
313Version 2.x, Copyright (C) 2001, Paul Marquess.
314
315Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
316
317This program is free software; you can redistribute it and/or
318modify it under the same terms as Perl itself.
319
320=head1 SEE ALSO
321
ba120f6f 322See L<ppport.h> and L<devel/regenerate>.
adfe19db 323
324=cut
325