3 package ExtUtils::Embed;
8 #Only when we need them
9 #require ExtUtils::MakeMaker;
10 #require ExtUtils::Liblist;
12 use vars qw(@ISA @EXPORT $VERSION
13 @Extensions $Verbose $lib_ext
18 # This is not a dual-life module, so no need for development version numbers
22 @EXPORT = qw(&xsinit &ldopts
23 &ccopts &ccflags &ccdlflags &perl_inc
24 &xsi_header &xsi_protos &xsi_body);
26 #let's have Miniperl borrow from us instead
27 #require ExtUtils::Miniperl;
28 #*canon = \&ExtUtils::Miniperl::canon;
31 $lib_ext = $Config{lib_ext} || '.a';
33 sub is_cmd { $0 eq '-e' }
46 my($file, $std, $mods) = @_;
48 $file ||= "perlxsi.c";
49 my $xsinit_proto = "pTHX";
52 @mods = @$mods if $mods;
56 Getopt::Std::getopts('o:s:');
57 $file = $opt_o if defined $opt_o;
58 $std = $opt_s if defined $opt_s;
61 $std = 1 unless scalar @mods;
63 if ($file eq "STDOUT") {
68 or die "Can't open '$file': $!";
71 push(@mods, static_ext()) if defined $std;
72 @mods = grep(!$seen{$_}++, @mods);
74 print $fh &xsi_header();
75 print $fh "EXTERN_C void xs_init ($xsinit_proto);\n\n";
76 print $fh &xsi_protos(@mods);
78 print $fh "\nEXTERN_C void\nxs_init($xsinit_proto)\n{\n";
79 print $fh &xsi_body(@mods);
96 my $boot_proto = "pTHX_ CV* cv";
98 my($pname) = canon('/', $_);
100 ($mname = $pname) =~ s!/!::!g;
101 ($cname = $pname) =~ s!/!__!g;
102 my($ccode) = "EXTERN_C void boot_${cname} ($boot_proto);\n";
103 next if $seen{$ccode}++;
104 push(@retval, $ccode);
106 return join '', @retval;
111 my($pname,@retval,%seen);
112 my($dl) = canon('/','DynaLoader');
113 push(@retval, "\tstatic const char file[] = __FILE__;\n");
114 push(@retval, "\tdXSUB_SYS;\n");
115 push(@retval, "\tPERL_UNUSED_CONTEXT;\n");
119 my($pname) = canon('/', $_);
120 my($mname, $cname, $ccode);
121 ($mname = $pname) =~ s!/!::!g;
122 ($cname = $pname) =~ s!/!__!g;
124 # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'!
125 # boot_DynaLoader is called directly in DynaLoader.pm
126 $ccode = "\t/* DynaLoader is a special case */\n\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n";
127 push(@retval, $ccode) unless $seen{$ccode}++;
129 $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n";
130 push(@retval, $ccode) unless $seen{$ccode}++;
133 return join '', @retval;
137 unless (scalar @Extensions) {
138 my $static_ext = $Config{static_ext};
139 $static_ext =~ s/^\s+//;
140 @Extensions = sort split /\s+/, $static_ext;
141 unshift @Extensions, qw(DynaLoader);
148 return $$arg if $^O eq 'VMS'; # parens legal in qualifier lists
149 $$arg =~ s/([\(\)])/\\$1/g;
153 my $ldflags = $Config{ldflags};
159 my $ccflags = $Config{ccflags};
165 my $ccdlflags = $Config{ccdlflags};
166 _escape(\$ccdlflags);
171 require ExtUtils::MakeMaker;
172 require ExtUtils::Liblist;
173 my($std,$mods,$link_args,$path) = @_;
174 my(@mods,@link_args,@argv);
175 my($dllib,$config_libs,@potential_libs,@path);
176 local($") = ' ' unless $" eq ' ';
178 @link_args = @$link_args if $link_args;
179 @mods = @$mods if $mods;
184 while($_ = shift @argv) {
185 /^-std$/ && do { $std = 1; next; };
186 /^--$/ && do { @link_args = @argv; last; };
187 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
191 $std = 1 unless scalar @link_args;
192 my $sep = $Config{path_sep} || ':';
193 @path = $path ? split(/\Q$sep/, $path) : @INC;
195 push(@potential_libs, @link_args) if scalar @link_args;
196 # makemaker includes std libs on windows by default
197 if ($^O ne 'MSWin32' and defined($std)) {
198 push(@potential_libs, $Config{perllibs});
201 push(@mods, static_ext()) if $std;
203 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
204 print STDERR "Searching (@path) for archives\n" if $Verbose;
205 foreach $mod (@mods) {
206 @ns = split(/::|\/|\\/, $mod);
208 $root = File::Spec->catdir(@ns);
210 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
212 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
213 push @archives, $archive;
214 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
216 if(open(FH, $extra)) {
217 my($libs) = <FH>; chomp $libs;
218 push @potential_libs, split /\s+/, $libs;
221 warn "Couldn't open '$extra'";
227 #print STDERR "\@potential_libs = @potential_libs\n";
230 if ($^O eq 'MSWin32') {
231 $libperl = $Config{libperl};
233 elsif ($^O eq 'os390' && $Config{usedl}) {
234 # Nothing for OS/390 (z/OS) dynamic.
236 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0]
237 || ($Config{libperl} =~ /^lib(\w+)(\Q$lib_ext\E|\.\Q$Config{dlext}\E)$/
242 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
243 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
244 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
245 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
247 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
248 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
249 my $ccdlflags = _ccdlflags();
250 my $ldflags = _ldflags();
251 my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
252 print STDERR "ldopts: '$linkage'\n" if $Verbose;
254 return $linkage if scalar @_;
255 my_return("$linkage\n");
259 my $ccflags = _ccflags();
260 my_return(" $ccflags ");
264 my $ccdlflags = _ccdlflags();
265 my_return(" $ccdlflags ");
269 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
270 $dir = qq["$dir"] if $^O eq 'MSWin32';
271 my_return(" -I$dir ");
281 # might be X::Y or lib/auto/X/Y/Y.a
283 s:^(lib|ext)/(auto/)?::;
286 map(s:/:$as:, @ext) if ($as ne '/');
294 ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
299 perl -MExtUtils::Embed -e xsinit
300 perl -MExtUtils::Embed -e ccopts
301 perl -MExtUtils::Embed -e ldopts
305 ExtUtils::Embed provides utility functions for embedding a Perl interpreter
306 and extensions in your C/C++ applications.
307 Typically, an application B<Makefile> will invoke ExtUtils::Embed
308 functions while building your application.
312 ExtUtils::Embed exports the following functions:
314 xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
315 ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
323 Generate C/C++ code for the XS initializer function.
325 When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
326 the following options are recognized:
328 B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
330 B<-o STDOUT> will print to STDOUT.
332 B<-std> (Write code for extensions that are linked with the current Perl.)
334 Any additional arguments are expected to be names of modules
335 to generate code for.
337 When invoked with parameters the following are accepted and optional:
339 C<xsinit($filename,$std,[@modules])>
343 B<$filename> is equivalent to the B<-o> option.
345 B<$std> is boolean, equivalent to the B<-std> option.
347 B<[@modules]> is an array ref, same as additional arguments mentioned above.
352 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
355 This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
356 to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
358 Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
360 perl -MExtUtils::Embed -e xsinit
363 This will generate code for linking with B<DynaLoader> and
364 each static extension found in B<$Config{static_ext}>.
365 The code is written to the default file name B<perlxsi.c>.
368 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
371 Here, code is written for all the currently linked extensions along with code
372 for B<DBI> and B<DBD::Oracle>.
374 If you have a working B<DynaLoader> then there is rarely any need to statically link in any
379 Output arguments for linking the Perl library and extensions to your
382 When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
383 the following options are recognized:
387 Output arguments for linking the Perl library and any extensions linked
388 with the current Perl.
390 B<-I> E<lt>path1:path2E<gt>
392 Search path for ModuleName.a archives.
393 Default path is B<@INC>.
394 Library archives are expected to be found as
395 B</some/path/auto/ModuleName/ModuleName.a>
396 For example, when looking for B<Socket.a> relative to a search path,
397 we should find B<auto/Socket/Socket.a>
399 When looking for B<DBD::Oracle> relative to a search path,
400 we should find B<auto/DBD/Oracle/Oracle.a>
402 Keep in mind that you can always supply B</my/own/path/ModuleName.a>
403 as an additional linker argument.
405 B<--> E<lt>list of linker argsE<gt>
407 Additional linker arguments to be considered.
409 Any additional arguments found before the B<--> token
410 are expected to be names of modules to generate code for.
412 When invoked with parameters the following are accepted and optional:
414 C<ldopts($std,[@modules],[@link_args],$path)>
418 B<$std> is boolean, equivalent to the B<-std> option.
420 B<[@modules]> is equivalent to additional arguments found before the B<--> token.
422 B<[@link_args]> is equivalent to arguments found after the B<--> token.
424 B<$path> is equivalent to the B<-I> option.
426 In addition, when ldopts is called with parameters, it will return the argument string
427 rather than print it to STDOUT.
432 perl -MExtUtils::Embed -e ldopts
435 This will print arguments for linking with B<libperl> and
436 extensions found in B<$Config{static_ext}>. This includes libraries
437 found in B<$Config{libs}> and the first ModuleName.a library
438 for each extension that is found by searching B<@INC> or the path
439 specified by the B<-I> option.
440 In addition, when ModuleName.a is found, additional linker arguments
441 are picked up from the B<extralibs.ld> file in the same directory.
444 perl -MExtUtils::Embed -e ldopts -- -std Socket
447 This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
449 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
451 Any arguments after the second '--' token are additional linker
452 arguments that will be examined for potential conflict. If there is no
453 conflict, the additional arguments will be part of the output.
458 For including perl header files this function simply prints:
460 -I$Config{archlibexp}/CORE
462 So, rather than having to say:
464 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
468 perl -MExtUtils::Embed -e perl_inc
470 =item ccflags(), ccdlflags()
472 These functions simply print $Config{ccflags} and $Config{ccdlflags}
476 This function combines perl_inc(), ccflags() and ccdlflags() into one.
480 This function simply returns a string defining the same B<EXTERN_C> macro as
481 B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
483 =item xsi_protos(@modules)
485 This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
487 =item xsi_body(@modules)
489 This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
490 function to B<boot_ModuleName> for each @modules.
492 B<xsinit()> uses the xsi_* functions to generate most of its code.
498 For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
499 with embedded perl, see L<perlembed>.
507 Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
509 Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
510 B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.