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