1 # $Id: Embed.pm,v 1.1.1.1 2002/01/16 19:27:19 schwern Exp $
4 package ExtUtils::Embed;
11 #Only when we need them
12 #require ExtUtils::MakeMaker;
13 #require ExtUtils::Liblist;
15 use vars qw(@ISA @EXPORT $VERSION
16 @Extensions $Verbose $lib_ext
21 # This is not a dual-life module, so no need for development version numbers
25 @EXPORT = qw(&xsinit &ldopts
26 &ccopts &ccflags &ccdlflags &perl_inc
27 &xsi_header &xsi_protos &xsi_body);
29 #let's have Miniperl borrow from us instead
30 #require ExtUtils::Miniperl;
31 #*canon = \&ExtUtils::Miniperl::canon;
34 $lib_ext = $Config{lib_ext} || '.a';
36 sub is_cmd { $0 eq '-e' }
49 my($file, $std, $mods) = @_;
51 $file ||= "perlxsi.c";
52 my $xsinit_proto = "pTHX";
55 @mods = @$mods if $mods;
59 $file = $opt_o if defined $opt_o;
60 $std = $opt_s if defined $opt_s;
63 $std = 1 unless scalar @mods;
65 if ($file eq "STDOUT") {
69 $fh = new FileHandle "> $file";
72 push(@mods, static_ext()) if defined $std;
73 @mods = grep(!$seen{$_}++, @mods);
75 print $fh &xsi_header();
76 print $fh "EXTERN_C void xs_init ($xsinit_proto);\n\n";
77 print $fh &xsi_protos(@mods);
79 print $fh "\nEXTERN_C void\nxs_init($xsinit_proto)\n{\n";
80 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, "\tchar *file = __FILE__;\n");
114 push(@retval, "\tdXSUB_SYS;\n") if $] > 5.002;
118 my($pname) = canon('/', $_);
119 my($mname, $cname, $ccode);
120 ($mname = $pname) =~ s!/!::!g;
121 ($cname = $pname) =~ s!/!__!g;
123 # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'!
124 # boot_DynaLoader is called directly in DynaLoader.pm
125 $ccode = "\t/* DynaLoader is a special case */\n\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n";
126 push(@retval, $ccode) unless $seen{$ccode}++;
128 $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n";
129 push(@retval, $ccode) unless $seen{$ccode}++;
132 return join '', @retval;
136 unless (scalar @Extensions) {
137 my $static_ext = $Config{static_ext};
138 $static_ext =~ s/^\s+//;
139 @Extensions = sort split /\s+/, $static_ext;
140 unshift @Extensions, qw(DynaLoader);
147 $$arg =~ s/([\(\)])/\\$1/g;
151 my $ldflags = $Config{ldflags};
157 my $ccflags = $Config{ccflags};
163 my $ccdlflags = $Config{ccdlflags};
164 _escape(\$ccdlflags);
169 require ExtUtils::MakeMaker;
170 require ExtUtils::Liblist;
171 my($std,$mods,$link_args,$path) = @_;
172 my(@mods,@link_args,@argv);
173 my($dllib,$config_libs,@potential_libs,@path);
174 local($") = ' ' unless $" eq ' ';
176 @link_args = @$link_args if $link_args;
177 @mods = @$mods if $mods;
182 while($_ = shift @argv) {
183 /^-std$/ && do { $std = 1; next; };
184 /^--$/ && do { @link_args = @argv; last; };
185 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
189 $std = 1 unless scalar @link_args;
190 my $sep = $Config{path_sep} || ':';
191 @path = $path ? split(/\Q$sep/, $path) : @INC;
193 push(@potential_libs, @link_args) if scalar @link_args;
194 # makemaker includes std libs on windows by default
195 if ($^O ne 'MSWin32' and defined($std)) {
196 push(@potential_libs, $Config{perllibs});
199 push(@mods, static_ext()) if $std;
201 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
202 print STDERR "Searching (@path) for archives\n" if $Verbose;
203 foreach $mod (@mods) {
204 @ns = split(/::|\/|\\/, $mod);
206 $root = File::Spec->catdir(@ns);
208 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
210 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
211 push @archives, $archive;
212 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
214 if(open(FH, $extra)) {
215 my($libs) = <FH>; chomp $libs;
216 push @potential_libs, split /\s+/, $libs;
219 warn "Couldn't open '$extra'";
225 #print STDERR "\@potential_libs = @potential_libs\n";
228 if ($^O eq 'MSWin32') {
229 $libperl = $Config{libperl};
231 elsif ($^O eq 'os390' && $Config{usedl}) {
232 # Nothing for OS/390 (z/OS) dynamic.
234 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0]
235 || ($Config{libperl} =~ /^lib(\w+)(\Q$lib_ext\E|\.\Q$Config{dlext}\E)$/
240 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
241 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
242 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
243 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
245 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
246 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
247 my $ccdlflags = _ccdlflags();
248 my $ldflags = _ldflags();
249 my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
250 print STDERR "ldopts: '$linkage'\n" if $Verbose;
252 return $linkage if scalar @_;
253 my_return("$linkage\n");
257 my $ccflags = _ccflags();
258 my_return(" $ccflags ");
262 my $ccdlflags = _ccdlflags();
263 my_return(" $ccdlflags ");
267 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
268 $dir = qq["$dir"] if $^O eq 'MSWin32';
269 my_return(" -I$dir ");
279 # might be X::Y or lib/auto/X/Y/Y.a
281 s:^(lib|ext)/(auto/)?::;
284 map(s:/:$as:, @ext) if ($as ne '/');
292 ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
297 perl -MExtUtils::Embed -e xsinit
298 perl -MExtUtils::Embed -e ccopts
299 perl -MExtUtils::Embed -e ldopts
303 ExtUtils::Embed provides utility functions for embedding a Perl interpreter
304 and extensions in your C/C++ applications.
305 Typically, an application B<Makefile> will invoke ExtUtils::Embed
306 functions while building your application.
310 ExtUtils::Embed exports the following functions:
312 xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
313 ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
321 Generate C/C++ code for the XS initializer function.
323 When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
324 the following options are recognized:
326 B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
328 B<-o STDOUT> will print to STDOUT.
330 B<-std> (Write code for extensions that are linked with the current Perl.)
332 Any additional arguments are expected to be names of modules
333 to generate code for.
335 When invoked with parameters the following are accepted and optional:
337 C<xsinit($filename,$std,[@modules])>
341 B<$filename> is equivalent to the B<-o> option.
343 B<$std> is boolean, equivalent to the B<-std> option.
345 B<[@modules]> is an array ref, same as additional arguments mentioned above.
350 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
353 This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
354 to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
356 Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
358 perl -MExtUtils::Embed -e xsinit
361 This will generate code for linking with B<DynaLoader> and
362 each static extension found in B<$Config{static_ext}>.
363 The code is written to the default file name B<perlxsi.c>.
366 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
369 Here, code is written for all the currently linked extensions along with code
370 for B<DBI> and B<DBD::Oracle>.
372 If you have a working B<DynaLoader> then there is rarely any need to statically link in any
377 Output arguments for linking the Perl library and extensions to your
380 When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
381 the following options are recognized:
385 Output arguments for linking the Perl library and any extensions linked
386 with the current Perl.
388 B<-I> E<lt>path1:path2E<gt>
390 Search path for ModuleName.a archives.
391 Default path is B<@INC>.
392 Library archives are expected to be found as
393 B</some/path/auto/ModuleName/ModuleName.a>
394 For example, when looking for B<Socket.a> relative to a search path,
395 we should find B<auto/Socket/Socket.a>
397 When looking for B<DBD::Oracle> relative to a search path,
398 we should find B<auto/DBD/Oracle/Oracle.a>
400 Keep in mind that you can always supply B</my/own/path/ModuleName.a>
401 as an additional linker argument.
403 B<--> E<lt>list of linker argsE<gt>
405 Additional linker arguments to be considered.
407 Any additional arguments found before the B<--> token
408 are expected to be names of modules to generate code for.
410 When invoked with parameters the following are accepted and optional:
412 C<ldopts($std,[@modules],[@link_args],$path)>
416 B<$std> is boolean, equivalent to the B<-std> option.
418 B<[@modules]> is equivalent to additional arguments found before the B<--> token.
420 B<[@link_args]> is equivalent to arguments found after the B<--> token.
422 B<$path> is equivalent to the B<-I> option.
424 In addition, when ldopts is called with parameters, it will return the argument string
425 rather than print it to STDOUT.
430 perl -MExtUtils::Embed -e ldopts
433 This will print arguments for linking with B<libperl> and
434 extensions found in B<$Config{static_ext}>. This includes libraries
435 found in B<$Config{libs}> and the first ModuleName.a library
436 for each extension that is found by searching B<@INC> or the path
437 specified by the B<-I> option.
438 In addition, when ModuleName.a is found, additional linker arguments
439 are picked up from the B<extralibs.ld> file in the same directory.
442 perl -MExtUtils::Embed -e ldopts -- -std Socket
445 This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
447 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
449 Any arguments after the second '--' token are additional linker
450 arguments that will be examined for potential conflict. If there is no
451 conflict, the additional arguments will be part of the output.
456 For including perl header files this function simply prints:
458 -I$Config{archlibexp}/CORE
460 So, rather than having to say:
462 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
466 perl -MExtUtils::Embed -e perl_inc
468 =item ccflags(), ccdlflags()
470 These functions simply print $Config{ccflags} and $Config{ccdlflags}
474 This function combines perl_inc(), ccflags() and ccdlflags() into one.
478 This function simply returns a string defining the same B<EXTERN_C> macro as
479 B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
481 =item xsi_protos(@modules)
483 This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
485 =item xsi_body(@modules)
487 This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
488 function to B<boot_ModuleName> for each @modules.
490 B<xsinit()> uses the xsi_* functions to generate most of its code.
496 For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
497 with embedded perl, see L<perlembed>.
505 Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
507 Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
508 B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.