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