1Inline::Module::TutoriaUls(e3r)Contributed Perl DocumentIantliionne::Module::Tutorial(3)
2
3
4
6 Inline::Module::Tutorial - Make "XS" modules for CPAN. The easy way!
7
9 This tutorial will teach you how to write "extension" modules for CPAN
10 using Inline::Module. The old way to do this is with "XS", Perl's
11 mechanism for binding C and C++ code to Perl. Inline::Module lets you
12 do this much easier, avoiding the need to learn XS, but delivering
13 results that are as robust as hand-written XS.
14
16 The tutorial starts by showing you how an example module (that is
17 actually on CPAN), was created with Inline::Module. The module is
18 called Acme::Math::XS, and its purpose (besides trivial math functions)
19 is to demonstrate how to do this.
20
21 The Makefile.PL
22 No matter which framework you use to make modules (ExtUtils::MakeMaker,
23 Dist::Zilla) etc, you'll need to add a little metadata to the controls.
24 For now we'll just show "Makefile.PL" (ExtUtils::MakeMaker) way:
25
26 use lib 'inc';
27 use ExtUtils::MakeMaker;
28 use Inline::Module;
29
30 WriteMakefile(
31 NAME => 'Acme::Math::XS',
32 ...
33 postamble => {
34 inline => {
35 module => 'Acme::Math::XS',
36 stub => 'Acme::Math::XS::Inline',
37 ilsm => 'Inline::C',
38 },
39 },
40 );
41
42 So you need to "use Inline::Module" and add a "postamble" section with
43 an "inline" section (with at least a "module" name) to "WriteMakefile".
44 The arguments specify the information that Inline::Module needs to do
45 the right things. The "stub" and "ilsm" values above are the defaults,
46 so not really needed in that example. All the values for those keys can
47 be either a string or an array ref of strings (ie single or multiple
48 values).
49
50 NOTE: You also need to add "inc" to @INC, even if doesn't exist while
51 you are
52 developing and testing. It will exist when you ship it to CPAN,
53 and the
54 "make install" process needs it to work properly. The Makefile.PL
55 or
56 Build.PL will actually die if you don't put "inc" first in @INC.
57
58 See Alt::Acme::Math::XS::EUMM for a working example on CPAN.
59
60 Meta Values
61 Just to reiterate, whether you are using ExtUtils::MakeMaker,
62 Module::Build, Module::Install, Dist::Zilla or Zilla::Dist, you need to
63 specify 3 Meta values:
64
65 "module"
66 One or more module names that live under the "lib" directory and
67 use Inline inside. This value is required in all cases (no
68 default).
69
70 "stub"
71 One or more names of stub modules, that are referenced in the
72 "module" modules listed above. The default is to add '::Inline' to
73 each value of the "module" keyword.
74
75 "ilsm"
76 A list of the Inline Language Support Modules (ILSMs) needed.
77 Usually just one of Inline::C (the default) or Inline::CPP.
78
79 Each framework list above has a slightly different way to express the
80 values, but they will all seem normal in that framework. See below.
81
82 The Module
83 Next we'll "inline" some C code into a Perl module called
84 "lib/Acme/Math/XS.pm". Here is the real module, but condensed a bit:
85
86 use strict; use warnings;
87 package Acme::Math::XS;
88 our $VERSION = '1.2.3';
89 use Exporter 'import';
90 our @EXPORT = qw(add subtract);
91 use Acme::Math::XS::Inline C => <<'...';
92 long add(long a, long b) { return a + b; }
93 long subtract(long a, long b) { return a - b; }
94 ...
95 1;
96
97 Normally you use Inline::C like this:
98
99 use Inline C => '<... c code ...>';
100
101 but here we just change "Inline" to "Acme::Math::XS::Inline". This is
102 the key part of how Inline::Module works. Since we want to use Inline
103 but not depend on it when the user installs this module, we do this
104 trick. The "::Inline" module is a little generated stub that knows how
105 to do all the right magics.
106
107 The Inline Stub Module
108 Next you'll need to actually generate the stub module. Run this
109 command:
110
111 perl -MInline::Module=makestub,Acme::Math::XS::Inline
112
113 You'll get a "lib/Acme/Math/XS/Inline.pm" that looks like this:
114
115 use strict; use warnings;
116 package Acme::Math::XS::Inline;
117 use Inline::Module stub => 'v2';
118 1;
119
120 The astute tutorialist will note that this module depends on
121 "Inline::Module", and that's a no-no. That's because this stub is used
122 for author side development and testing, and another stub replaces it
123 at module release time.
124
125 The replacement stub will look like this:
126
127 use strict; use warnings;
128 package Acme::Math::XS::Inline;
129 use base 'DynaLoader';
130 bootstrap Acme::Math::XS::Inline;
131 1;
132
133 And everything is fine. We are just using Dynaloader, the age old
134 loader of extension libraries. As long the shared library stuff gets
135 built into the "blib" directory at user build time (and it does!) we
136 are good to go.
137
138 Automatic Stub Generation
139 The stub module is generated code, and many people don't like to commit
140 generated code. There are a couple ways to deal with this.
141
142 The first is just to commit it anyway, because it only has to change
143 very rarely; when you install a new Inline::Module whose API version
144 has changed. You will get an error telling you to regenerate the stub.
145 One main advantage of this is that your project collaborators don't
146 need to know about generating the stub.
147
148 The second way is to ignore it in your source control (ie ".gitignore"
149 file).
150
151 Testing
152 There are a few ways to test stuff and I'll describe them here. They
153 should be familiar to most module authors.
154
155 "prove -l t/"
156 This is the easiest and most common method of testing for non-XS
157 module authors. Since Inline is involved, the compilation steps
158 just work.
159
160 With XS, you typically need to run "perl Makefile.PL && make"
161 first, and you also need to add the "-b" flag to "prove" to tell it
162 to look in the new "blib". Then you need to continually make sure
163 to repeat this every time you change C code. With Inline, you can
164 relax a bit.
165
166 "perl Makefile.PL && make test"
167 You can also use the XS style. It all works out the same.
168
169 "prove -b t/"
170 In this style, you are just invoking the "blib" results directly,
171 and Inline is not involved. Use this if you want to know that no
172 nothing is up a sleeve, but don't forget that auto-compilation
173 can't happen this way.
174
175 Making a Distribution (Tarball)
176 Now it's time to make the final product and ship it to CPAN. The
177 mechanics are dead simple:
178
179 perl Makefile.PL
180 make dist
181
182 Same as any other module. Some magic is happening though to make it all
183 work. You asked for this magic in your "Makefile.PL" changes!
184
185 "Inline::Module" modifies 2 targets in the Makefile:
186
187 "distdir"
188 This is the target that buils the distribution directory (before it
189 is tarred up).
190
191 "pure_all"
192 This odd sounding rule is actually the primary/default rule. It
193 gets invoked when you run:
194
195 make
196
197 without arguments. In other words, the build step.
198
199 In the "distdir" phase, we need to:
200
201 · Add the "Inline" modules that control building, under "inc/":
202
203 · Inline::Module
204
205 · Inline
206
207 · Inline::C
208
209 · a few helper modules
210
211 We also need to move the test/build stub module under "inc/" and put
212 the "Dynaloader" version in its place under "lib".
213
214 The "pure_all" phase is simply tweaked to rearrange the exact location
215 of things that get generated under "blib". Then they are ready to be
216 installed properly/normally by "make install".
217
218 Ship It
219 Assuming you've done all the other parts of normal CPAN modules
220 authoring, we are done here. Upload your module and watch CPAN Testers
221 for results on tons of different platforms.
222
224 This section will describe how to do everything we just did, using the
225 other popular CPAN build systems, like Dist::Zilla.
226
227 Dist::Zilla
228 For Dist::Zilla, install Dist::Zilla::Plugin::InlineModule and add this
229 to your "dist.ini" file:
230
231 [InlineModule]
232 module = Acme::Math::XS
233 stub = Acme::Math::XS::Inline
234 ilsm = Inline::C
235
236 Again, the last 2 lines are defaults. You can use any of the keywords
237 multiple times.
238
239 See Alt::Acme::Math::XS::DistZilla for a working example on CPAN.
240
241 Module::Build
242 Install Module::Build::InlineModule and write a "Build.PL" file that
243 looks like this:
244
245 use lib 'inc';
246 use Module::Build::InlineModule;
247
248 Module::Build::InlineModule->new(
249 dist_name => 'Alt-Acme-Math-XS-ModuleBuild',
250 ...
251 inline => {
252 module => 'Acme::Math::XS',
253 stub => 'Acme::Math::XS::Inline',
254 ilsm => 'Inline::C',
255 },
256 )->create_build_script();
257
258 See Alt::Acme::Math::XS::ModuleBuild for a working example on CPAN.
259
260 Module::Install
261 Install Module::Build::InlineModule and write a "Makefile.PL" that
262 looks like this:
263
264 use inc::Module::Install;
265
266 name 'Alt-Acme-Math-XS-ModuleInstall';
267 ...
268 inline
269 module => 'Acme::Math::XS',
270 stub => 'Acme::Math::XS::Inline',
271 ilsm => 'Inline::C';
272
273 WriteAll;
274
275 See Alt::Acme::Math::XS::ModuleInstall for a working example on CPAN.
276
277 Zilla::Dist
278 Just add these lines to your Meta file:
279
280 =zild:
281 inline:
282 module: Acme::Math::XS
283 stub: Acme::Math::XS::Inline
284 ilsm: Inline::C
285
286 See Alt::Acme::Math::XS::ZillaDist for a working example on CPAN.
287
289 Putting a lot of C code in your Perl might be too messy. You can just
290 move it to a ".c" file, and then change your Perl to this:
291
292 use Acme::Math::XS::Inline C => 'lib/Acme/Math/XS.c';
293
294 Note: You can put the ".c" file anywhere you want, except at the top
295 level.
296 Doing that will confuse the Makefile. If you put it under "lib"
297 like
298 above, it will get installed like ".pm" files. This might be
299 desirable
300 since it opens all your source (just lie when it's actually
301 inline).
302
304 Under the hood, Inline::Module does quite a few things different when
305 you use Inline::CPP, but this should be mostly transparent to you. Just
306 make sure you declare your "ilsm" keyword to be "Inline::CPP" and
307 everything should work fine.
308
310 It may be possible (though highly experimental) to use other Inline
311 Language Support Modules (ILSMs), like Java or Python. Simply list your
312 ILSM of choice in the Meta section, and see what happens.
313
314 Report any issues to:
315 <https://github.com/ingydotnet/inline-module-pm/issues>
316
318 This document reflects the current state of "Inline::Module". At this
319 time, it is brand new, so please report any bugs and/or misgivings.
320
322 · Ingy döt Net <ingy@cpan.org>
323
324 · David Oswald <davido@cpan.org>
325
327 Copyright 2014. Ingy döt Net.
328
329
330
331perl v5.32.0 2020-07-28 Inline::Module::Tutorial(3)