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