Re: [PATCH] Hash::Util::FieldHash
[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
111Remove all existing todo files in the F<parts/base> and
112F<parts/todo> directories.
113
114=item *
115
116Update the API information. Copy the latest F<embed.fnc> file from
117bleadperl to the F<parts> directory and run F<devel/mkapidoc.sh> to
118collect the remaining information in F<parts/apidoc.fnc>.
119
120=item *
121
122Build the new baseline by running
123
124 perl devel/mktodo --base
125
126in the root directory of the distribution. When it's finished,
127move all files from the F<parts/todo> directory to F<parts/base>.
128
129=item *
130
131Build the new todo files by running
132
133 perl devel/mktodo
134
135in the root directory of the distribution.
136
137=item *
138
139Finally, add the remaining baseline information by running
140
4a582685 141 perl Makefile.PL && make
142 perl devel/scanprov write
adfe19db 143
144=back
145
146=head2 Implementation
147
148Residing in F<parts/inc/> is the "heart" of C<Devel::PPPort>. Each
149of the files implements a part of the supported API, along with
150hints, dependency information, XS code and tests.
151The files are in a POD-like format that is parsed using the
152functions in F<parts/ppptools.pl>.
153
154The scripts F<PPPort_pm.PL>, F<PPPort_xs.PL> and F<mktests.PL> all
155use the information in F<parts/inc/> to generate the main module
156F<PPPort.pm>, the XS code in F<PPPort.xs> and various test files
157in F<t/>.
158
159All of these files could be generated on the fly while building
160C<Devel::PPPort>, but not having the tests in C<t/> and not having
161F<PPPort.xs> will confuse Configure and TEST/harness in the core.
162Not having F<PPPort.pm> will be bad for viewing the docs on
163C<search.cpan.org>. So unfortunately, it's unavoidable to put
164some redundancy into the package.
165
166=head2 Adding stuff to Devel::PPPort
167
168First, check if the code you plan to add fits into one of the
169existing files in F<parts/inc/>. If not, just start a new one and
170remember to include it from within F<PPPort_pm.PL>.
171
172Each file holds all relevant data for implementing a certain part
173of the API:
174
175=over 2
176
177=item *
178
179A list of the provided API in the C<=provides> section.
180
181=item *
182
183The implementation to add to F<ppport.h> in the C<=implementation>
184section.
185
186=item *
187
188The code required to add to PPPort.xs for testing the implementation.
189This code goes into the C<=xshead>, C<=xsinit>, C<=xsmisc>, C<=xsboot>
0d0f8426 190and C<=xsubs> section. Have a look at the template at the bottom
191of F<PPPort_xs.PL> to see where the code ends up.
adfe19db 192
193=item *
194
195The tests in the C<=tests> section. Remember not to use any fancy
196modules or syntax elements, as the test code should be able to run
197with Perl 5.003, which, for example, doesn't support C<my> in
198C<for>-loops:
199
0d0f8426 200 for my $x (1, 2, 3) { } # won't work with 5.003
adfe19db 201
0d0f8426 202You can use C<ok()> to report success or failure:
203
204 ok($got == 42);
205 ok($got, $expected);
206
207Regular expressions are not supported as the second argument to C<ok>,
208because older perls do not support the C<qr> operator.
adfe19db 209
210=back
211
212It's usually the best approach to just copy an existing file and
213use it as a template.
214
0d0f8426 215=head2 Implementation Hints
216
217In the C<=implementation> section, you can use
218
219 __UNDEFINED__ macro some definition
220
221instead of
222
223 #ifndef macro
224 # define macro some definition
225 #endif
226
227The macro can have optional arguments and the definition can even
228span multiple lines, like in
229
230 __UNDEFINED__ SvMAGIC_set(sv, val) \
231 STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
232 (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END
233
234This usually makes the code more compact and readable. And you
235only have to add C<__UNDEFINED__> to the C<=provided> section.
236
237Version checking can be tricky if you want to do it correct.
238You can use
239
240 #if { VERSION < 5.9.3 }
241
242instead of
243
244 #if ((PERL_VERSION < 9) || (PERL_VERSION == 9 && PERL_SUBVERSION < 3))
245
246The version number can be either of the new form C<5.x.x> or of the older
247form C<5.00x_yy>. Both are translated into the correct preprocessor
248statements. It is also possible to combine this with other statements:
249
250 #if { VERSION >= 5.004 } && !defined(sv_vcatpvf)
251 /* a */
252 #elif { VERSION < 5.004_63 } && { VERSION != 5.004_05 }
253 /* b */
254 #endif
255
256This not only works in the C<=implementation> section, but also in
257the C<=xsubs>, C<=xsinit>, C<=xsmisc>, C<=xshead> and C<=xsboot> sections.
258
adfe19db 259=head2 Testing
260
261To automatically test C<Devel::PPPort> with lots of different Perl
262versions, you can use the F<soak> script. Just pass it a list of
263all Perl binaries you want to test.
264
265=head2 Special Makefile targets
266
4a582685 267You can use
adfe19db 268
269 make regen
270
4a582685 271to regenerate all of the autogenerated files. To get rid of all
272generated files (except for F<parts/todo/*> and F<parts/base/*>),
273use
adfe19db 274
275 make purge_all
276
277That's it.
278
0d0f8426 279=head2 Submitting Patches
280
281If you've added some functionality to C<Devel::PPPort>, please
282consider submitting a patch with your work to either the author
283(E<lt>mhx@cpan.orgE<gt>) or to the CPAN Request Tracker at
284L<http://rt.cpan.org>.
285
286When submitting patches, please only add the relevant changes
287and don't include the differences of the generated files. You
288can use the C<purge_all> target to delete all autogenerated
289files.
290
adfe19db 291=head1 COPYRIGHT
292
0d0f8426 293Version 3.x, Copyright (C) 2004-2006, Marcus Holland-Moritz.
adfe19db 294
295Version 2.x, Copyright (C) 2001, Paul Marquess.
296
297Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
298
299This program is free software; you can redistribute it and/or
300modify it under the same terms as Perl itself.
301
302=head1 SEE ALSO
303
ba120f6f 304See L<ppport.h> and L<devel/regenerate>.
adfe19db 305
306=cut
307