This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perldelta entry for the updated links
[perl5.git] / lib / ExtUtils / Embed.pm
... / ...
CommitLineData
1package ExtUtils::Embed;
2require Exporter;
3use Config;
4require File::Spec;
5
6our ( @Extensions, $opt_o, $opt_s );
7use strict;
8
9# This is not a dual-life module, so no need for development version numbers
10our $VERSION = '1.35';
11
12our @ISA = qw(Exporter);
13our @EXPORT = qw(&xsinit &ldopts
14 &ccopts &ccflags &ccdlflags &perl_inc
15 &xsi_header &xsi_protos &xsi_body);
16
17our $Verbose = 0;
18our $lib_ext = $Config{lib_ext} || '.a';
19
20sub is_cmd { $0 eq '-e' }
21
22sub my_return {
23 my $val = shift;
24 if(is_cmd) {
25 print $val;
26 }
27 else {
28 return $val;
29 }
30}
31
32sub xsinit {
33 my($file, $std, $mods) = @_;
34 my($fh,@mods,%seen);
35 $file ||= "perlxsi.c";
36 my $xsinit_proto = "pTHX";
37
38 if (@_) {
39 @mods = @$mods if $mods;
40 }
41 else {
42 require Getopt::Std;
43 Getopt::Std::getopts('o:s:');
44 $file = $opt_o if defined $opt_o;
45 $std = $opt_s if defined $opt_s;
46 @mods = @ARGV;
47 }
48 $std = 1 unless scalar @mods;
49
50 if ($file eq "STDOUT") {
51 $fh = \*STDOUT;
52 }
53 else {
54 open $fh, '>', $file
55 or die "Can't open '$file': $!";
56 }
57
58 push(@mods, static_ext()) if defined $std;
59 @mods = grep(!$seen{$_}++, @mods);
60
61 print $fh &xsi_header();
62 print $fh "\nEXTERN_C void xs_init ($xsinit_proto);\n\n";
63 print $fh &xsi_protos(@mods);
64
65 print $fh "\nEXTERN_C void\nxs_init($xsinit_proto)\n{\n";
66 print $fh &xsi_body(@mods);
67 print $fh "}\n";
68
69}
70
71sub xsi_header {
72 return <<EOF;
73#include "EXTERN.h"
74#include "perl.h"
75#include "XSUB.h"
76EOF
77}
78
79sub xsi_protos {
80 my @exts = @_;
81 my %seen;
82 my $retval = '';
83 foreach my $cname (canon('__', @exts)) {
84 my $ccode = "EXTERN_C void boot_${cname} (pTHX_ CV* cv);\n";
85 $retval .= $ccode
86 unless $seen{$ccode}++;
87 }
88 return $retval;
89}
90
91sub xsi_body {
92 my @exts = @_;
93 my %seen;
94 my $retval;
95 $retval .= " static const char file[] = __FILE__;\n"
96 if @exts;
97 $retval .= <<'EOT';
98 dXSUB_SYS;
99 PERL_UNUSED_CONTEXT;
100EOT
101 $retval .= "\n"
102 if @exts;
103
104 foreach my $pname (canon('/', @exts)) {
105 next
106 if $seen{$pname}++;
107 (my $mname = $pname) =~ s!/!::!g;
108 (my $cname = $pname) =~ s!/!__!g;
109 my $fname;
110 if ($pname eq 'DynaLoader'){
111 # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'!
112 # boot_DynaLoader is called directly in DynaLoader.pm
113 $retval .= " /* DynaLoader is a special case */\n";
114 $fname = "${mname}::boot_DynaLoader";
115 } else {
116 $fname = "${mname}::bootstrap";
117 }
118 $retval .= " newXS(\"$fname\", boot_${cname}, file);\n"
119 }
120 return $retval;
121}
122
123sub static_ext {
124 @Extensions = ('DynaLoader', sort $Config{static_ext} =~ /(\S+)/g)
125 unless @Extensions;
126 @Extensions;
127}
128
129sub _escape {
130 my $arg = shift;
131 return $$arg if $^O eq 'VMS'; # parens legal in qualifier lists
132 $$arg =~ s/([\(\)])/\\$1/g;
133}
134
135sub _ldflags {
136 my $ldflags = $Config{ldflags};
137 _escape(\$ldflags);
138 return $ldflags;
139}
140
141sub _ccflags {
142 my $ccflags = $Config{ccflags};
143 _escape(\$ccflags);
144 return $ccflags;
145}
146
147sub _ccdlflags {
148 my $ccdlflags = $Config{ccdlflags};
149 _escape(\$ccdlflags);
150 return $ccdlflags;
151}
152
153sub ldopts {
154 require ExtUtils::MakeMaker;
155 require ExtUtils::Liblist;
156 my($std,$mods,$link_args,$path) = @_;
157 my(@mods,@link_args,@argv);
158 my($dllib,$config_libs,@potential_libs,@path);
159 local($") = ' ' unless $" eq ' ';
160 if (scalar @_) {
161 @link_args = @$link_args if $link_args;
162 @mods = @$mods if $mods;
163 }
164 else {
165 @argv = @ARGV;
166 #hmm
167 while($_ = shift @argv) {
168 /^-std$/ && do { $std = 1; next; };
169 /^--$/ && do { @link_args = @argv; last; };
170 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
171 push(@mods, $_);
172 }
173 }
174 $std = 1 unless scalar @link_args;
175 my $sep = $Config{path_sep} || ':';
176 @path = $path ? split(/\Q$sep/, $path) : @INC;
177
178 push(@potential_libs, @link_args) if scalar @link_args;
179 # makemaker includes std libs on windows by default
180 if ($^O ne 'MSWin32' and defined($std)) {
181 push(@potential_libs, $Config{perllibs});
182 }
183
184 push(@mods, static_ext()) if $std;
185
186 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
187 print STDERR "Searching (@path) for archives\n" if $Verbose;
188 foreach $mod (@mods) {
189 @ns = split(/::|\/|\\/, $mod);
190 $sub = $ns[-1];
191 $root = File::Spec->catdir(@ns);
192
193 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
194 foreach (@path) {
195 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
196 push @archives, $archive;
197 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
198 local(*FH);
199 if(open(FH, '<', $extra)) {
200 my($libs) = <FH>; chomp $libs;
201 push @potential_libs, split /\s+/, $libs;
202 }
203 else {
204 warn "Couldn't open '$extra'";
205 }
206 }
207 last;
208 }
209 }
210 #print STDERR "\@potential_libs = @potential_libs\n";
211
212 my $libperl;
213 if ($^O eq 'MSWin32') {
214 $libperl = $Config{libperl};
215 }
216 elsif ($^O eq 'os390' && $Config{usedl}) {
217 # Nothing for OS/390 (z/OS) dynamic.
218 } else {
219 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0]
220 || ($Config{libperl} =~ /^lib(\w+)(\Q$lib_ext\E|\.\Q$Config{dlext}\E)$/
221 ? "-l$1" : '')
222 || "-lperl";
223 }
224
225 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
226 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
227 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
228 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
229
230 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
231 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
232 my $ccdlflags = _ccdlflags();
233 my $ldflags = _ldflags();
234 my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
235 print STDERR "ldopts: '$linkage'\n" if $Verbose;
236
237 return $linkage if scalar @_;
238 my_return("$linkage\n");
239}
240
241sub ccflags {
242 my $ccflags = _ccflags();
243 my_return(" $ccflags ");
244}
245
246sub ccdlflags {
247 my $ccdlflags = _ccdlflags();
248 my_return(" $ccdlflags ");
249}
250
251sub perl_inc {
252 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
253 $dir = qq["$dir"] if $^O eq 'MSWin32';
254 my_return(" -I$dir ");
255}
256
257sub ccopts {
258 ccflags . perl_inc;
259}
260
261sub canon {
262 my($as, @ext) = @_;
263 foreach(@ext) {
264 # might be X::Y or lib/auto/X/Y/Y.a
265 next
266 if s!::!/!g;
267 s!^(?:lib|ext|dist|cpan)/(?:auto/)?!!;
268 s!/\w+\.\w+$!!;
269 }
270 if ($as ne '/') {
271 s!/!$as!g
272 foreach @ext;
273 }
274 @ext;
275}
276
277__END__
278
279=head1 NAME
280
281ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
282
283=head1 SYNOPSIS
284
285 perl -MExtUtils::Embed -e xsinit
286 perl -MExtUtils::Embed -e ccopts
287 perl -MExtUtils::Embed -e ldopts
288
289=head1 DESCRIPTION
290
291C<ExtUtils::Embed> provides utility functions for embedding a Perl interpreter
292and extensions in your C/C++ applications.
293Typically, an application F<Makefile> will invoke C<ExtUtils::Embed>
294functions while building your application.
295
296=head1 @EXPORT
297
298C<ExtUtils::Embed> exports the following functions:
299
300xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
301ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
302
303=head1 FUNCTIONS
304
305=over 4
306
307=item xsinit()
308
309Generate C/C++ code for the XS initializer function.
310
311When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
312the following options are recognized:
313
314B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
315
316B<-o STDOUT> will print to STDOUT.
317
318B<-std> (Write code for extensions that are linked with the current Perl.)
319
320Any additional arguments are expected to be names of modules
321to generate code for.
322
323When invoked with parameters the following are accepted and optional:
324
325C<xsinit($filename,$std,[@modules])>
326
327Where,
328
329B<$filename> is equivalent to the B<-o> option.
330
331B<$std> is boolean, equivalent to the B<-std> option.
332
333B<[@modules]> is an array ref, same as additional arguments mentioned above.
334
335=item Examples
336
337 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
338
339This will generate code with an C<xs_init> function that glues the perl C<Socket::bootstrap> function
340to the C C<boot_Socket> function and writes it to a file named F<xsinit.c>.
341
342Note that L<DynaLoader> is a special case where it must call C<boot_DynaLoader> directly.
343
344 perl -MExtUtils::Embed -e xsinit
345
346This will generate code for linking with C<DynaLoader> and
347each static extension found in C<$Config{static_ext}>.
348The code is written to the default file name F<perlxsi.c>.
349
350 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c \
351 -std DBI DBD::Oracle
352
353Here, code is written for all the currently linked extensions along with code
354for C<DBI> and C<DBD::Oracle>.
355
356If you have a working C<DynaLoader> then there is rarely any need to statically link in any
357other extensions.
358
359=item ldopts()
360
361Output arguments for linking the Perl library and extensions to your
362application.
363
364When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
365the following options are recognized:
366
367B<-std>
368
369Output arguments for linking the Perl library and any extensions linked
370with the current Perl.
371
372B<-I> E<lt>path1:path2E<gt>
373
374Search path for ModuleName.a archives.
375Default path is C<@INC>.
376Library archives are expected to be found as
377F</some/path/auto/ModuleName/ModuleName.a>
378For example, when looking for F<Socket.a> relative to a search path,
379we should find F<auto/Socket/Socket.a>
380
381When looking for C<DBD::Oracle> relative to a search path,
382we should find F<auto/DBD/Oracle/Oracle.a>
383
384Keep in mind that you can always supply F</my/own/path/ModuleName.a>
385as an additional linker argument.
386
387B<--> E<lt>list of linker argsE<gt>
388
389Additional linker arguments to be considered.
390
391Any additional arguments found before the B<--> token
392are expected to be names of modules to generate code for.
393
394When invoked with parameters the following are accepted and optional:
395
396C<ldopts($std,[@modules],[@link_args],$path)>
397
398Where:
399
400B<$std> is boolean, equivalent to the B<-std> option.
401
402B<[@modules]> is equivalent to additional arguments found before the B<--> token.
403
404B<[@link_args]> is equivalent to arguments found after the B<--> token.
405
406B<$path> is equivalent to the B<-I> option.
407
408In addition, when ldopts is called with parameters, it will return the argument string
409rather than print it to STDOUT.
410
411=item Examples
412
413 perl -MExtUtils::Embed -e ldopts
414
415This will print arguments for linking with C<libperl> and
416extensions found in C<$Config{static_ext}>. This includes libraries
417found in C<$Config{libs}> and the first ModuleName.a library
418for each extension that is found by searching C<@INC> or the path
419specified by the B<-I> option.
420In addition, when ModuleName.a is found, additional linker arguments
421are picked up from the F<extralibs.ld> file in the same directory.
422
423 perl -MExtUtils::Embed -e ldopts -- -std Socket
424
425This will do the same as the above example, along with printing additional
426arguments for linking with the C<Socket> extension.
427
428 perl -MExtUtils::Embed -e ldopts -- -std Msql -- \
429 -L/usr/msql/lib -lmsql
430
431Any arguments after the second '--' token are additional linker
432arguments that will be examined for potential conflict. If there is no
433conflict, the additional arguments will be part of the output.
434
435=item perl_inc()
436
437For including perl header files this function simply prints:
438
439 -I$Config{archlibexp}/CORE
440
441So, rather than having to say:
442
443 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
444
445Just say:
446
447 perl -MExtUtils::Embed -e perl_inc
448
449=item ccflags(), ccdlflags()
450
451These functions simply print $Config{ccflags} and $Config{ccdlflags}
452
453=item ccopts()
454
455This function combines C<perl_inc()>, C<ccflags()> and C<ccdlflags()> into one.
456
457=item xsi_header()
458
459This function simply returns a string defining the same C<EXTERN_C> macro as
460F<perlmain.c> along with #including F<perl.h> and F<EXTERN.h>.
461
462=item xsi_protos(@modules)
463
464This function returns a string of C<boot_$ModuleName> prototypes for each @modules.
465
466=item xsi_body(@modules)
467
468This function returns a string of calls to C<newXS()> that glue the module I<bootstrap>
469function to I<boot_ModuleName> for each @modules.
470
471C<xsinit()> uses the xsi_* functions to generate most of its code.
472
473=back
474
475=head1 EXAMPLES
476
477For examples on how to use C<ExtUtils::Embed> for building C/C++ applications
478with embedded perl, see L<perlembed>.
479
480=head1 SEE ALSO
481
482L<perlembed>
483
484=head1 AUTHOR
485
486Doug MacEachern E<lt>C<dougm@osf.org>E<gt>
487
488Based on ideas from Tim Bunce E<lt>C<Tim.Bunce@ig.co.uk>E<gt> and
489F<minimod.pl> by Andreas Koenig E<lt>C<k@anna.in-berlin.de>E<gt> and Tim Bunce.
490
491=cut