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
24 @EXPORT = qw(&xsinit &ldopts
25 &ccopts &ccflags &ccdlflags &perl_inc
26 &xsi_header &xsi_protos &xsi_body);
28 #let's have Miniperl borrow from us instead
29 #require ExtUtils::Miniperl;
30 #*canon = \&ExtUtils::Miniperl::canon;
33 $lib_ext = $Config{lib_ext} || '.a';
35 sub is_cmd { $0 eq '-e' }
48 my($file, $std, $mods) = @_;
50 $file ||= "perlxsi.c";
51 my $xsinit_proto = "pTHX";
54 @mods = @$mods if $mods;
58 $file = $opt_o if defined $opt_o;
59 $std = $opt_s if defined $opt_s;
62 $std = 1 unless scalar @mods;
64 if ($file eq "STDOUT") {
68 $fh = new FileHandle "> $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);
95 my $boot_proto = "pTHX_ CV* cv";
97 my($pname) = canon('/', $_);
99 ($mname = $pname) =~ s!/!::!g;
100 ($cname = $pname) =~ s!/!__!g;
101 my($ccode) = "EXTERN_C void boot_${cname} ($boot_proto);\n";
102 next if $seen{$ccode}++;
103 push(@retval, $ccode);
105 return join '', @retval;
110 my($pname,@retval,%seen);
111 my($dl) = canon('/','DynaLoader');
112 push(@retval, "\tchar *file = __FILE__;\n");
113 push(@retval, "\tdXSUB_SYS;\n") if $] > 5.002;
117 my($pname) = canon('/', $_);
118 my($mname, $cname, $ccode);
119 ($mname = $pname) =~ s!/!::!g;
120 ($cname = $pname) =~ s!/!__!g;
122 # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'!
123 # boot_DynaLoader is called directly in DynaLoader.pm
124 $ccode = "\t/* DynaLoader is a special case */\n\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n";
125 push(@retval, $ccode) unless $seen{$ccode}++;
127 $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n";
128 push(@retval, $ccode) unless $seen{$ccode}++;
131 return join '', @retval;
135 unless (scalar @Extensions) {
136 my $static_ext = $Config{static_ext};
137 $static_ext =~ s/^\s+//;
138 @Extensions = sort split /\s+/, $static_ext;
139 unshift @Extensions, qw(DynaLoader);
146 $$arg =~ s/([\(\)])/\\$1/g;
150 my $ldflags = $Config{ldflags};
156 my $ccflags = $Config{ccflags};
162 my $ccdlflags = $Config{ccdlflags};
163 _escape(\$ccdlflags);
168 require ExtUtils::MakeMaker;
169 require ExtUtils::Liblist;
170 my($std,$mods,$link_args,$path) = @_;
171 my(@mods,@link_args,@argv);
172 my($dllib,$config_libs,@potential_libs,@path);
173 local($") = ' ' unless $" eq ' ';
175 @link_args = @$link_args if $link_args;
176 @mods = @$mods if $mods;
181 while($_ = shift @argv) {
182 /^-std$/ && do { $std = 1; next; };
183 /^--$/ && do { @link_args = @argv; last; };
184 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
188 $std = 1 unless scalar @link_args;
189 my $sep = $Config{path_sep} || ':';
190 @path = $path ? split(/\Q$sep/, $path) : @INC;
192 push(@potential_libs, @link_args) if scalar @link_args;
193 # makemaker includes std libs on windows by default
194 if ($^O ne 'MSWin32' and defined($std)) {
195 push(@potential_libs, $Config{perllibs});
198 push(@mods, static_ext()) if $std;
200 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
201 print STDERR "Searching (@path) for archives\n" if $Verbose;
202 foreach $mod (@mods) {
203 @ns = split(/::|\/|\\/, $mod);
205 $root = File::Spec->catdir(@ns);
207 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
209 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
210 push @archives, $archive;
211 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
213 if(open(FH, $extra)) {
214 my($libs) = <FH>; chomp $libs;
215 push @potential_libs, split /\s+/, $libs;
218 warn "Couldn't open '$extra'";
224 #print STDERR "\@potential_libs = @potential_libs\n";
227 if ($^O eq 'MSWin32') {
228 $libperl = $Config{libperl};
230 elsif ($^O eq 'os390' && $Config{usedl}) {
231 # Nothing for OS/390 (z/OS) dynamic.
233 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0]
234 || ($Config{libperl} =~ /^lib(\w+)(\Q$lib_ext\E|\.\Q$Config{dlext}\E)$/
239 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
240 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
241 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
242 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
244 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
245 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
246 my $ccdlflags = _ccdlflags();
247 my $ldflags = _ldflags();
248 my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
249 print STDERR "ldopts: '$linkage'\n" if $Verbose;
251 return $linkage if scalar @_;
252 my_return("$linkage\n");
256 my $ccflags = _ccflags();
257 my_return(" $ccflags ");
261 my $ccdlflags = _ccdlflags();
262 my_return(" $ccdlflags ");
266 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
267 $dir = qq["$dir"] if $^O eq 'MSWin32';
268 my_return(" -I$dir ");
278 # might be X::Y or lib/auto/X/Y/Y.a
280 s:^(lib|ext)/(auto/)?::;
283 grep(s:/:$as:, @ext) if ($as ne '/');
291 ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
296 perl -MExtUtils::Embed -e xsinit
297 perl -MExtUtils::Embed -e ccopts
298 perl -MExtUtils::Embed -e ldopts
302 ExtUtils::Embed provides utility functions for embedding a Perl interpreter
303 and extensions in your C/C++ applications.
304 Typically, an application B<Makefile> will invoke ExtUtils::Embed
305 functions while building your application.
309 ExtUtils::Embed exports the following functions:
311 xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
312 ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
320 Generate C/C++ code for the XS initializer function.
322 When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
323 the following options are recognized:
325 B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
327 B<-o STDOUT> will print to STDOUT.
329 B<-std> (Write code for extensions that are linked with the current Perl.)
331 Any additional arguments are expected to be names of modules
332 to generate code for.
334 When invoked with parameters the following are accepted and optional:
336 C<xsinit($filename,$std,[@modules])>
340 B<$filename> is equivalent to the B<-o> option.
342 B<$std> is boolean, equivalent to the B<-std> option.
344 B<[@modules]> is an array ref, same as additional arguments mentioned above.
349 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
352 This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
353 to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
355 Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
357 perl -MExtUtils::Embed -e xsinit
360 This will generate code for linking with B<DynaLoader> and
361 each static extension found in B<$Config{static_ext}>.
362 The code is written to the default file name B<perlxsi.c>.
365 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
368 Here, code is written for all the currently linked extensions along with code
369 for B<DBI> and B<DBD::Oracle>.
371 If you have a working B<DynaLoader> then there is rarely any need to statically link in any
376 Output arguments for linking the Perl library and extensions to your
379 When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
380 the following options are recognized:
384 Output arguments for linking the Perl library and any extensions linked
385 with the current Perl.
387 B<-I> E<lt>path1:path2E<gt>
389 Search path for ModuleName.a archives.
390 Default path is B<@INC>.
391 Library archives are expected to be found as
392 B</some/path/auto/ModuleName/ModuleName.a>
393 For example, when looking for B<Socket.a> relative to a search path,
394 we should find B<auto/Socket/Socket.a>
396 When looking for B<DBD::Oracle> relative to a search path,
397 we should find B<auto/DBD/Oracle/Oracle.a>
399 Keep in mind that you can always supply B</my/own/path/ModuleName.a>
400 as an additional linker argument.
402 B<--> E<lt>list of linker argsE<gt>
404 Additional linker arguments to be considered.
406 Any additional arguments found before the B<--> token
407 are expected to be names of modules to generate code for.
409 When invoked with parameters the following are accepted and optional:
411 C<ldopts($std,[@modules],[@link_args],$path)>
415 B<$std> is boolean, equivalent to the B<-std> option.
417 B<[@modules]> is equivalent to additional arguments found before the B<--> token.
419 B<[@link_args]> is equivalent to arguments found after the B<--> token.
421 B<$path> is equivalent to the B<-I> option.
423 In addition, when ldopts is called with parameters, it will return the argument string
424 rather than print it to STDOUT.
429 perl -MExtUtils::Embed -e ldopts
432 This will print arguments for linking with B<libperl> and
433 extensions found in B<$Config{static_ext}>. This includes libraries
434 found in B<$Config{libs}> and the first ModuleName.a library
435 for each extension that is found by searching B<@INC> or the path
436 specified by the B<-I> option.
437 In addition, when ModuleName.a is found, additional linker arguments
438 are picked up from the B<extralibs.ld> file in the same directory.
441 perl -MExtUtils::Embed -e ldopts -- -std Socket
444 This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
446 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
448 Any arguments after the second '--' token are additional linker
449 arguments that will be examined for potential conflict. If there is no
450 conflict, the additional arguments will be part of the output.
455 For including perl header files this function simply prints:
457 -I$Config{archlibexp}/CORE
459 So, rather than having to say:
461 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
465 perl -MExtUtils::Embed -e perl_inc
467 =item ccflags(), ccdlflags()
469 These functions simply print $Config{ccflags} and $Config{ccdlflags}
473 This function combines perl_inc(), ccflags() and ccdlflags() into one.
477 This function simply returns a string defining the same B<EXTERN_C> macro as
478 B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
480 =item xsi_protos(@modules)
482 This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
484 =item xsi_body(@modules)
486 This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
487 function to B<boot_ModuleName> for each @modules.
489 B<xsinit()> uses the xsi_* functions to generate most of its code.
495 For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
496 with embedded perl, see L<perlembed>.
504 Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
506 Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
507 B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.