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);
143 require ExtUtils::MakeMaker;
144 require ExtUtils::Liblist;
145 my($std,$mods,$link_args,$path) = @_;
146 my(@mods,@link_args,@argv);
147 my($dllib,$config_libs,@potential_libs,@path);
148 local($") = ' ' unless $" eq ' ';
150 @link_args = @$link_args if $link_args;
151 @mods = @$mods if $mods;
156 while($_ = shift @argv) {
157 /^-std$/ && do { $std = 1; next; };
158 /^--$/ && do { @link_args = @argv; last; };
159 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
163 $std = 1 unless scalar @link_args;
164 my $sep = $Config{path_sep} || ':';
165 @path = $path ? split(/\Q$sep/, $path) : @INC;
167 push(@potential_libs, @link_args) if scalar @link_args;
168 # makemaker includes std libs on windows by default
169 if ($^O ne 'MSWin32' and defined($std)) {
170 push(@potential_libs, $Config{perllibs});
173 push(@mods, static_ext()) if $std;
175 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
176 print STDERR "Searching (@path) for archives\n" if $Verbose;
177 foreach $mod (@mods) {
178 @ns = split(/::|\/|\\/, $mod);
180 $root = File::Spec->catdir(@ns);
182 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
184 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
185 push @archives, $archive;
186 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
188 if(open(FH, $extra)) {
189 my($libs) = <FH>; chomp $libs;
190 push @potential_libs, split /\s+/, $libs;
193 warn "Couldn't open '$extra'";
199 #print STDERR "\@potential_libs = @potential_libs\n";
202 if ($^O eq 'MSWin32') {
203 $libperl = $Config{libperl};
206 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0] || "-lperl";
209 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
210 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
211 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
212 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
214 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
215 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
216 my $linkage = "$Config{ccdlflags} $Config{ldflags} @archives $ld_or_bs";
217 print STDERR "ldopts: '$linkage'\n" if $Verbose;
219 return $linkage if scalar @_;
220 my_return("$linkage\n");
224 my_return(" $Config{ccflags} ");
228 my_return(" $Config{ccdlflags} ");
232 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
233 $dir = qq["$dir"] if $^O eq 'MSWin32';
234 my_return(" -I$dir ");
244 # might be X::Y or lib/auto/X/Y/Y.a
246 s:^(lib|ext)/(auto/)?::;
249 grep(s:/:$as:, @ext) if ($as ne '/');
257 ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
262 perl -MExtUtils::Embed -e xsinit
263 perl -MExtUtils::Embed -e ccopts
264 perl -MExtUtils::Embed -e ldopts
268 ExtUtils::Embed provides utility functions for embedding a Perl interpreter
269 and extensions in your C/C++ applications.
270 Typically, an application B<Makefile> will invoke ExtUtils::Embed
271 functions while building your application.
275 ExtUtils::Embed exports the following functions:
277 xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
278 ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
286 Generate C/C++ code for the XS initializer function.
288 When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
289 the following options are recognized:
291 B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
293 B<-o STDOUT> will print to STDOUT.
295 B<-std> (Write code for extensions that are linked with the current Perl.)
297 Any additional arguments are expected to be names of modules
298 to generate code for.
300 When invoked with parameters the following are accepted and optional:
302 C<xsinit($filename,$std,[@modules])>
306 B<$filename> is equivalent to the B<-o> option.
308 B<$std> is boolean, equivalent to the B<-std> option.
310 B<[@modules]> is an array ref, same as additional arguments mentioned above.
315 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
318 This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
319 to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
321 Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
323 perl -MExtUtils::Embed -e xsinit
326 This will generate code for linking with B<DynaLoader> and
327 each static extension found in B<$Config{static_ext}>.
328 The code is written to the default file name B<perlxsi.c>.
331 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
334 Here, code is written for all the currently linked extensions along with code
335 for B<DBI> and B<DBD::Oracle>.
337 If you have a working B<DynaLoader> then there is rarely any need to statically link in any
342 Output arguments for linking the Perl library and extensions to your
345 When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
346 the following options are recognized:
350 Output arguments for linking the Perl library and any extensions linked
351 with the current Perl.
353 B<-I> E<lt>path1:path2E<gt>
355 Search path for ModuleName.a archives.
356 Default path is B<@INC>.
357 Library archives are expected to be found as
358 B</some/path/auto/ModuleName/ModuleName.a>
359 For example, when looking for B<Socket.a> relative to a search path,
360 we should find B<auto/Socket/Socket.a>
362 When looking for B<DBD::Oracle> relative to a search path,
363 we should find B<auto/DBD/Oracle/Oracle.a>
365 Keep in mind that you can always supply B</my/own/path/ModuleName.a>
366 as an additional linker argument.
368 B<--> E<lt>list of linker argsE<gt>
370 Additional linker arguments to be considered.
372 Any additional arguments found before the B<--> token
373 are expected to be names of modules to generate code for.
375 When invoked with parameters the following are accepted and optional:
377 C<ldopts($std,[@modules],[@link_args],$path)>
381 B<$std> is boolean, equivalent to the B<-std> option.
383 B<[@modules]> is equivalent to additional arguments found before the B<--> token.
385 B<[@link_args]> is equivalent to arguments found after the B<--> token.
387 B<$path> is equivalent to the B<-I> option.
389 In addition, when ldopts is called with parameters, it will return the argument string
390 rather than print it to STDOUT.
395 perl -MExtUtils::Embed -e ldopts
398 This will print arguments for linking with B<libperl.a>, B<DynaLoader> and
399 extensions found in B<$Config{static_ext}>. This includes libraries
400 found in B<$Config{libs}> and the first ModuleName.a library
401 for each extension that is found by searching B<@INC> or the path
402 specified by the B<-I> option.
403 In addition, when ModuleName.a is found, additional linker arguments
404 are picked up from the B<extralibs.ld> file in the same directory.
407 perl -MExtUtils::Embed -e ldopts -- -std Socket
410 This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
413 perl -MExtUtils::Embed -e ldopts -- DynaLoader
416 This will print arguments for linking with just the B<DynaLoader> extension
420 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
423 Any arguments after the second '--' token are additional linker
424 arguments that will be examined for potential conflict. If there is no
425 conflict, the additional arguments will be part of the output.
430 For including perl header files this function simply prints:
432 -I$Config{archlibexp}/CORE
434 So, rather than having to say:
436 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
440 perl -MExtUtils::Embed -e perl_inc
442 =item ccflags(), ccdlflags()
444 These functions simply print $Config{ccflags} and $Config{ccdlflags}
448 This function combines perl_inc(), ccflags() and ccdlflags() into one.
452 This function simply returns a string defining the same B<EXTERN_C> macro as
453 B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
455 =item xsi_protos(@modules)
457 This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
459 =item xsi_body(@modules)
461 This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
462 function to B<boot_ModuleName> for each @modules.
464 B<xsinit()> uses the xsi_* functions to generate most of its code.
470 For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
471 with embedded perl, see L<perlembed>.
479 Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
481 Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
482 B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.