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 @Extensions = sort split /\s+/, $Config{static_ext};
137 unshift @Extensions, qw(DynaLoader);
144 $$arg =~ s/([\(\)])/\\$1/g;
148 my $ldflags = $Config{ldflags};
154 my $ccflags = $Config{ccflags};
160 my $ccdlflags = $Config{ccdlflags};
161 _escape(\$ccdlflags);
166 require ExtUtils::MakeMaker;
167 require ExtUtils::Liblist;
168 my($std,$mods,$link_args,$path) = @_;
169 my(@mods,@link_args,@argv);
170 my($dllib,$config_libs,@potential_libs,@path);
171 local($") = ' ' unless $" eq ' ';
173 @link_args = @$link_args if $link_args;
174 @mods = @$mods if $mods;
179 while($_ = shift @argv) {
180 /^-std$/ && do { $std = 1; next; };
181 /^--$/ && do { @link_args = @argv; last; };
182 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
186 $std = 1 unless scalar @link_args;
187 my $sep = $Config{path_sep} || ':';
188 @path = $path ? split(/\Q$sep/, $path) : @INC;
190 push(@potential_libs, @link_args) if scalar @link_args;
191 # makemaker includes std libs on windows by default
192 if ($^O ne 'MSWin32' and defined($std)) {
193 push(@potential_libs, $Config{perllibs});
196 push(@mods, static_ext()) if $std;
198 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
199 print STDERR "Searching (@path) for archives\n" if $Verbose;
200 foreach $mod (@mods) {
201 @ns = split(/::|\/|\\/, $mod);
203 $root = File::Spec->catdir(@ns);
205 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
207 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
208 push @archives, $archive;
209 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
211 if(open(FH, $extra)) {
212 my($libs) = <FH>; chomp $libs;
213 push @potential_libs, split /\s+/, $libs;
216 warn "Couldn't open '$extra'";
222 #print STDERR "\@potential_libs = @potential_libs\n";
225 if ($^O eq 'MSWin32') {
226 $libperl = $Config{libperl};
229 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0] || "-lperl";
232 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
233 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
234 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
235 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
237 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
238 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
239 my $ccdlflags = _ccdlflags();
240 my $ldflags = _ldflags();
241 my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
242 print STDERR "ldopts: '$linkage'\n" if $Verbose;
244 return $linkage if scalar @_;
245 my_return("$linkage\n");
249 my $ccflags = _ccflags();
250 my_return(" $ccflags ");
254 my $ccdlflags = _ccdlflags();
255 my_return(" $ccdlflags ");
259 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
260 $dir = qq["$dir"] if $^O eq 'MSWin32';
261 my_return(" -I$dir ");
271 # might be X::Y or lib/auto/X/Y/Y.a
273 s:^(lib|ext)/(auto/)?::;
276 grep(s:/:$as:, @ext) if ($as ne '/');
284 ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
289 perl -MExtUtils::Embed -e xsinit
290 perl -MExtUtils::Embed -e ccopts
291 perl -MExtUtils::Embed -e ldopts
295 ExtUtils::Embed provides utility functions for embedding a Perl interpreter
296 and extensions in your C/C++ applications.
297 Typically, an application B<Makefile> will invoke ExtUtils::Embed
298 functions while building your application.
302 ExtUtils::Embed exports the following functions:
304 xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
305 ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
313 Generate C/C++ code for the XS initializer function.
315 When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
316 the following options are recognized:
318 B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
320 B<-o STDOUT> will print to STDOUT.
322 B<-std> (Write code for extensions that are linked with the current Perl.)
324 Any additional arguments are expected to be names of modules
325 to generate code for.
327 When invoked with parameters the following are accepted and optional:
329 C<xsinit($filename,$std,[@modules])>
333 B<$filename> is equivalent to the B<-o> option.
335 B<$std> is boolean, equivalent to the B<-std> option.
337 B<[@modules]> is an array ref, same as additional arguments mentioned above.
342 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
345 This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
346 to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
348 Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
350 perl -MExtUtils::Embed -e xsinit
353 This will generate code for linking with B<DynaLoader> and
354 each static extension found in B<$Config{static_ext}>.
355 The code is written to the default file name B<perlxsi.c>.
358 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
361 Here, code is written for all the currently linked extensions along with code
362 for B<DBI> and B<DBD::Oracle>.
364 If you have a working B<DynaLoader> then there is rarely any need to statically link in any
369 Output arguments for linking the Perl library and extensions to your
372 When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
373 the following options are recognized:
377 Output arguments for linking the Perl library and any extensions linked
378 with the current Perl.
380 B<-I> E<lt>path1:path2E<gt>
382 Search path for ModuleName.a archives.
383 Default path is B<@INC>.
384 Library archives are expected to be found as
385 B</some/path/auto/ModuleName/ModuleName.a>
386 For example, when looking for B<Socket.a> relative to a search path,
387 we should find B<auto/Socket/Socket.a>
389 When looking for B<DBD::Oracle> relative to a search path,
390 we should find B<auto/DBD/Oracle/Oracle.a>
392 Keep in mind that you can always supply B</my/own/path/ModuleName.a>
393 as an additional linker argument.
395 B<--> E<lt>list of linker argsE<gt>
397 Additional linker arguments to be considered.
399 Any additional arguments found before the B<--> token
400 are expected to be names of modules to generate code for.
402 When invoked with parameters the following are accepted and optional:
404 C<ldopts($std,[@modules],[@link_args],$path)>
408 B<$std> is boolean, equivalent to the B<-std> option.
410 B<[@modules]> is equivalent to additional arguments found before the B<--> token.
412 B<[@link_args]> is equivalent to arguments found after the B<--> token.
414 B<$path> is equivalent to the B<-I> option.
416 In addition, when ldopts is called with parameters, it will return the argument string
417 rather than print it to STDOUT.
422 perl -MExtUtils::Embed -e ldopts
425 This will print arguments for linking with B<libperl.a>, B<DynaLoader> and
426 extensions found in B<$Config{static_ext}>. This includes libraries
427 found in B<$Config{libs}> and the first ModuleName.a library
428 for each extension that is found by searching B<@INC> or the path
429 specified by the B<-I> option.
430 In addition, when ModuleName.a is found, additional linker arguments
431 are picked up from the B<extralibs.ld> file in the same directory.
434 perl -MExtUtils::Embed -e ldopts -- -std Socket
437 This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
440 perl -MExtUtils::Embed -e ldopts -- DynaLoader
443 This will print arguments for linking with just the B<DynaLoader> extension
447 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
450 Any arguments after the second '--' token are additional linker
451 arguments that will be examined for potential conflict. If there is no
452 conflict, the additional arguments will be part of the output.
457 For including perl header files this function simply prints:
459 -I$Config{archlibexp}/CORE
461 So, rather than having to say:
463 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
467 perl -MExtUtils::Embed -e perl_inc
469 =item ccflags(), ccdlflags()
471 These functions simply print $Config{ccflags} and $Config{ccdlflags}
475 This function combines perl_inc(), ccflags() and ccdlflags() into one.
479 This function simply returns a string defining the same B<EXTERN_C> macro as
480 B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
482 =item xsi_protos(@modules)
484 This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
486 =item xsi_body(@modules)
488 This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
489 function to B<boot_ModuleName> for each @modules.
491 B<xsinit()> uses the xsi_* functions to generate most of its code.
497 For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
498 with embedded perl, see L<perlembed>.
506 Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
508 Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
509 B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.