1 # $Id: Embed.pm,v 1.22 1997/01/30 00:37:09 dougm Exp $
4 package ExtUtils::Embed;
10 #Only when we need them
11 #require ExtUtils::MakeMaker;
12 #require ExtUtils::Liblist;
14 use vars qw(@ISA @EXPORT $VERSION
15 @Extensions $Verbose $lib_ext
20 $VERSION = sprintf("%d.%02d", q$Revision: 1.2201 $ =~ /(\d+)\.(\d+)/);
21 #for the namespace change
22 $Devel::embed::VERSION = "99.99";
24 sub Version { $VERSION; }
27 @EXPORT = qw(&xsinit &ldopts
28 &ccopts &ccflags &ccdlflags &perl_inc
29 &xsi_header &xsi_protos &xsi_body);
31 #let's have Miniperl borrow from us instead
32 #require ExtUtils::Miniperl;
33 #*canon = \&ExtUtils::Miniperl::canon;
36 $lib_ext = $Config{lib_ext} || '.a';
39 my($file, $std, $mods) = @_;
41 $file ||= "perlxsi.c";
44 @mods = @$mods if $mods;
48 $file = $opt_o if defined $opt_o;
49 $std = $opt_s if defined $opt_s;
52 $std = 1 unless scalar @mods;
54 if ($file eq "STDOUT") {
58 $fh = new FileHandle "> $file";
61 push(@mods, static_ext()) if defined $std;
62 @mods = grep(!$seen{$_}++, @mods);
64 print $fh &xsi_header();
65 print $fh "EXTERN_C void xs_init _((void));\n\n";
66 print $fh &xsi_protos(@mods);
68 print $fh "\nEXTERN_C void\nxs_init()\n{\n";
69 print $fh &xsi_body(@mods);
86 # define EXTERN_C extern "C"
90 # define EXTERN_C extern
102 my($pname) = canon('/', $_);
104 ($mname = $pname) =~ s!/!::!g;
105 ($cname = $pname) =~ s!/!__!g;
106 my($ccode) = "EXTERN_C void boot_${cname} _((CV* cv));\n";
107 next if $seen{$ccode}++;
108 push(@retval, $ccode);
110 return join '', @retval;
115 my($pname,@retval,%seen);
116 my($dl) = canon('/','DynaLoader');
117 push(@retval, "\tdXSUB_SYS;\n") if $] > 5.002;
118 push(@retval, "\tchar *file = __FILE__;\n\n");
121 my($pname) = canon('/', $_);
122 my($mname, $cname, $ccode);
123 ($mname = $pname) =~ s!/!::!g;
124 ($cname = $pname) =~ s!/!__!g;
126 # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'!
127 # boot_DynaLoader is called directly in DynaLoader.pm
128 $ccode = "\t/* DynaLoader is a special case */\n\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n";
129 push(@retval, $ccode) unless $seen{$ccode}++;
131 $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n";
132 push(@retval, $ccode) unless $seen{$ccode}++;
135 return join '', @retval;
139 unless (scalar @Extensions) {
140 @Extensions = sort split /\s+/, $Config{static_ext};
141 unshift @Extensions, qw(DynaLoader);
147 require ExtUtils::MakeMaker;
148 require ExtUtils::Liblist;
149 my($std,$mods,$link_args,$path) = @_;
150 my(@mods,@link_args,@argv);
151 my($dllib,$config_libs,@potential_libs,@path);
152 local($") = ' ' unless $" eq ' ';
153 my $MM = bless {} => 'MY';
155 @link_args = @$link_args if $link_args;
156 @mods = @$mods if $mods;
161 while($_ = shift @argv) {
162 /^-std$/ && do { $std = 1; next; };
163 /^--$/ && do { @link_args = @argv; last; };
164 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
168 $std = 1 unless scalar @link_args;
169 @path = $path ? split(/:/, $path) : @INC;
171 push(@potential_libs, @link_args) if scalar @link_args;
172 push(@potential_libs, $Config{libs}) if defined $std;
174 push(@mods, static_ext()) if $std;
176 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
177 print STDERR "Searching (@path) for archives\n" if $Verbose;
178 foreach $mod (@mods) {
179 @ns = split('::', $mod);
181 $root = $MM->catdir(@ns);
183 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
185 next unless -e ($archive = $MM->catdir($_,"auto",$root,"$sub$lib_ext"));
186 push @archives, $archive;
187 if(-e ($extra = $MM->catdir($_,"auto",$root,"extralibs.ld"))) {
189 if(open(FH, $extra)) {
190 my($libs) = <FH>; chomp $libs;
191 push @potential_libs, split /\s+/, $libs;
194 warn "Couldn't open '$extra'";
200 #print STDERR "\@potential_libs = @potential_libs\n";
202 my $libperl = (grep(/^(-l\w+perl)$/, @link_args))[0] || "-lperl";
204 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
206 $MM->catdir("-L$Config{archlibexp}", "CORE"), " $libperl",
209 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
210 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
211 my $linkage = "$Config{ccdlflags} $Config{ldflags} @archives $ld_or_bs";
212 print STDERR "ldopts: '$linkage'\n" if $Verbose;
214 return $linkage if scalar @_;
219 print " $Config{ccflags} ";
223 print " $Config{ccdlflags} ";
227 print " -I$Config{archlibexp}/CORE ";
238 # might be X::Y or lib/auto/X/Y/Y.a
240 s:^(lib|ext)/(auto/)?::;
243 grep(s:/:$as:, @ext) if ($as ne '/');
251 ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
256 perl -MExtUtils::Embed -e xsinit
257 perl -MExtUtils::Embed -e ldopts
261 ExtUtils::Embed provides utility functions for embedding a Perl interpreter
262 and extensions in your C/C++ applications.
263 Typically, an application B<Makefile> will invoke ExtUtils::Embed
264 functions while building your application.
268 ExtUtils::Embed exports the following functions:
270 xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
271 ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
277 Generate C/C++ code for the XS initializer function.
279 When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
280 the following options are recognized:
282 B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
284 B<-o STDOUT> will print to STDOUT.
286 B<-std> (Write code for extensions that are linked with the current Perl.)
288 Any additional arguments are expected to be names of modules
289 to generate code for.
291 When invoked with parameters the following are accepted and optional:
293 C<xsinit($filename,$std,[@modules])>
297 B<$filename> is equivalent to the B<-o> option.
299 B<$std> is boolean, equivalent to the B<-std> option.
301 B<[@modules]> is an array ref, same as additional arguments mentioned above.
306 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
309 This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
310 to the C B<boot_Socket> function and writes it to a file named "xsinit.c".
312 Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
314 perl -MExtUtils::Embed -e xsinit
317 This will generate code for linking with B<DynaLoader> and
318 each static extension found in B<$Config{static_ext}>.
319 The code is written to the default file name B<perlxsi.c>.
322 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
325 Here, code is written for all the currently linked extensions along with code
326 for B<DBI> and B<DBD::Oracle>.
328 If you have a working B<DynaLoader> then there is rarely any need to statically link in any
333 Output arguments for linking the Perl library and extensions to your
336 When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
337 the following options are recognized:
341 Output arguments for linking the Perl library and any extensions linked
342 with the current Perl.
344 B<-I> E<lt>path1:path2E<gt>
346 Search path for ModuleName.a archives.
347 Default path is B<@INC>.
348 Library archives are expected to be found as
349 B</some/path/auto/ModuleName/ModuleName.a>
350 For example, when looking for B<Socket.a> relative to a search path,
351 we should find B<auto/Socket/Socket.a>
353 When looking for B<DBD::Oracle> relative to a search path,
354 we should find B<auto/DBD/Oracle/Oracle.a>
356 Keep in mind, you can always supply B</my/own/path/ModuleName.a>
357 as an additional linker argument.
359 B<--> E<lt>list of linker argsE<gt>
361 Additional linker arguments to be considered.
363 Any additional arguments found before the B<--> token
364 are expected to be names of modules to generate code for.
366 When invoked with parameters the following are accepted and optional:
368 C<ldopts($std,[@modules],[@link_args],$path)>
372 B<$std> is boolean, equivalent to the B<-std> option.
374 B<[@modules]> is equivalent to additional arguments found before the B<--> token.
376 B<[@link_args]> is equivalent to arguments found after the B<--> token.
378 B<$path> is equivalent to the B<-I> option.
380 In addition, when ldopts is called with parameters, it will return the argument string
381 rather than print it to STDOUT.
386 perl -MExtUtils::Embed -e ldopts
389 This will print arguments for linking with B<libperl.a>, B<DynaLoader> and
390 extensions found in B<$Config{static_ext}>. This includes libraries
391 found in B<$Config{libs}> and the first ModuleName.a library
392 for each extension that is found by searching B<@INC> or the path
393 specifed by the B<-I> option.
394 In addition, when ModuleName.a is found, additional linker arguments
395 are picked up from the B<extralibs.ld> file in the same directory.
398 perl -MExtUtils::Embed -e ldopts -- -std Socket
401 This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
404 perl -MExtUtils::Embed -e ldopts -- DynaLoader
407 This will print arguments for linking with just the B<DynaLoader> extension
411 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
414 Any arguments after the second '--' token are additional linker
415 arguments that will be examined for potential conflict. If there is no
416 conflict, the additional arguments will be part of the output.
421 For including perl header files this function simply prints:
423 -I$Config{archlibexp}/CORE
425 So, rather than having to say:
427 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
431 perl -MExtUtils::Embed -e perl_inc
433 =item ccflags(), ccdlflags()
435 These functions simply print $Config{ccflags} and $Config{ccdlflags}
439 This function combines perl_inc(), ccflags() and ccdlflags() into one.
443 This function simply returns a string defining the same B<EXTERN_C> macro as
444 B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
446 =item xsi_protos(@modules)
448 This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
450 =item xsi_body(@modules)
452 This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
453 function to B<boot_ModuleName> for each @modules.
455 B<xsinit()> uses the xsi_* functions to generate most of it's code.
459 For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
460 with embedded perl, see the eg/ directory and L<perlembed>.
468 Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
470 Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
471 B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.