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