This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Protect possible parentheses in ccflags, ccdlflags, and
[perl5.git] / lib / ExtUtils / Embed.pm
CommitLineData
39234879 1# $Id: Embed.pm,v 1.1.1.1 2002/01/16 19:27:19 schwern Exp $
a2c6f8f1
PP
2require 5.002;
3
4package ExtUtils::Embed;
5require Exporter;
6require FileHandle;
7use Config;
8use Getopt::Std;
9bbedd82 9use File::Spec;
a2c6f8f1
PP
10
11#Only when we need them
12#require ExtUtils::MakeMaker;
13#require ExtUtils::Liblist;
14
15use vars qw(@ISA @EXPORT $VERSION
16 @Extensions $Verbose $lib_ext
17 $opt_o $opt_s
18 );
19use strict;
20
39234879 21$VERSION = 1.2506_01;
a2c6f8f1
PP
22
23@ISA = qw(Exporter);
24@EXPORT = qw(&xsinit &ldopts
25 &ccopts &ccflags &ccdlflags &perl_inc
26 &xsi_header &xsi_protos &xsi_body);
27
28#let's have Miniperl borrow from us instead
29#require ExtUtils::Miniperl;
30#*canon = \&ExtUtils::Miniperl::canon;
31
32$Verbose = 0;
33$lib_ext = $Config{lib_ext} || '.a';
34
7e24002c
DM
35sub is_cmd { $0 eq '-e' }
36
37sub my_return {
38 my $val = shift;
39 if(is_cmd) {
40 print $val;
41 }
42 else {
43 return $val;
44 }
45}
46
a2c6f8f1
PP
47sub xsinit {
48 my($file, $std, $mods) = @_;
49 my($fh,@mods,%seen);
50 $file ||= "perlxsi.c";
acfe0abc 51 my $xsinit_proto = "pTHX";
a2c6f8f1
PP
52
53 if (@_) {
54 @mods = @$mods if $mods;
55 }
56 else {
57 getopts('o:s:');
58 $file = $opt_o if defined $opt_o;
59 $std = $opt_s if defined $opt_s;
60 @mods = @ARGV;
61 }
62 $std = 1 unless scalar @mods;
63
64 if ($file eq "STDOUT") {
65 $fh = \*STDOUT;
66 }
67 else {
68 $fh = new FileHandle "> $file";
69 }
70
71 push(@mods, static_ext()) if defined $std;
72 @mods = grep(!$seen{$_}++, @mods);
73
74 print $fh &xsi_header();
20ce7b12 75 print $fh "EXTERN_C void xs_init ($xsinit_proto);\n\n";
a2c6f8f1
PP
76 print $fh &xsi_protos(@mods);
77
8bdb6b78 78 print $fh "\nEXTERN_C void\nxs_init($xsinit_proto)\n{\n";
a2c6f8f1
PP
79 print $fh &xsi_body(@mods);
80 print $fh "}\n";
81
82}
83
84sub xsi_header {
85 return <<EOF;
a2c6f8f1
PP
86#include <EXTERN.h>
87#include <perl.h>
a2c6f8f1
PP
88
89EOF
90}
91
92sub xsi_protos {
93 my(@exts) = @_;
94 my(@retval,%seen);
acfe0abc 95 my $boot_proto = "pTHX_ CV* cv";
a2c6f8f1
PP
96 foreach $_ (@exts){
97 my($pname) = canon('/', $_);
98 my($mname, $cname);
99 ($mname = $pname) =~ s!/!::!g;
100 ($cname = $pname) =~ s!/!__!g;
20ce7b12 101 my($ccode) = "EXTERN_C void boot_${cname} ($boot_proto);\n";
a2c6f8f1
PP
102 next if $seen{$ccode}++;
103 push(@retval, $ccode);
104 }
105 return join '', @retval;
106}
107
108sub xsi_body {
109 my(@exts) = @_;
110 my($pname,@retval,%seen);
111 my($dl) = canon('/','DynaLoader');
a3c8358c 112 push(@retval, "\tchar *file = __FILE__;\n");
a2c6f8f1 113 push(@retval, "\tdXSUB_SYS;\n") if $] > 5.002;
a3c8358c 114 push(@retval, "\n");
a2c6f8f1
PP
115
116 foreach $_ (@exts){
117 my($pname) = canon('/', $_);
118 my($mname, $cname, $ccode);
119 ($mname = $pname) =~ s!/!::!g;
120 ($cname = $pname) =~ s!/!__!g;
121 if ($pname eq $dl){
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}++;
126 } else {
127 $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n";
128 push(@retval, $ccode) unless $seen{$ccode}++;
129 }
130 }
131 return join '', @retval;
132}
133
134sub static_ext {
135 unless (scalar @Extensions) {
136 @Extensions = sort split /\s+/, $Config{static_ext};
137 unshift @Extensions, qw(DynaLoader);
138 }
139 @Extensions;
140}
141
f0595bdd
JH
142sub _ldflags {
143 my $ldflags = $Config{ldflags};
144 $ldflags =~ s/([\(\)])/\\$1/g;
145 return $ldflags;
146}
147
148sub _ccflags {
149 my $ccflags = $Config{ccflags};
150 $ccflags =~ s/([\(\)])/\\$1/g;
151 return $ccflags;
152}
153
154sub _ccdlflags {
155 my $ccdlflags = $Config{ccdlflags};
156 $ccdlflags =~ s/([\(\)])/\\$1/g;
157 return $ccdlflags;
158}
159
a2c6f8f1
PP
160sub ldopts {
161 require ExtUtils::MakeMaker;
162 require ExtUtils::Liblist;
163 my($std,$mods,$link_args,$path) = @_;
164 my(@mods,@link_args,@argv);
165 my($dllib,$config_libs,@potential_libs,@path);
166 local($") = ' ' unless $" eq ' ';
a2c6f8f1
PP
167 if (scalar @_) {
168 @link_args = @$link_args if $link_args;
169 @mods = @$mods if $mods;
170 }
171 else {
172 @argv = @ARGV;
173 #hmm
174 while($_ = shift @argv) {
175 /^-std$/ && do { $std = 1; next; };
176 /^--$/ && do { @link_args = @argv; last; };
177 /^-I(.*)/ && do { $path = $1 || shift @argv; next; };
178 push(@mods, $_);
179 }
180 }
181 $std = 1 unless scalar @link_args;
9bbedd82
JH
182 my $sep = $Config{path_sep} || ':';
183 @path = $path ? split(/\Q$sep/, $path) : @INC;
a2c6f8f1
PP
184
185 push(@potential_libs, @link_args) if scalar @link_args;
9bbedd82
JH
186 # makemaker includes std libs on windows by default
187 if ($^O ne 'MSWin32' and defined($std)) {
188 push(@potential_libs, $Config{perllibs});
189 }
a2c6f8f1
PP
190
191 push(@mods, static_ext()) if $std;
192
193 my($mod,@ns,$root,$sub,$extra,$archive,@archives);
194 print STDERR "Searching (@path) for archives\n" if $Verbose;
195 foreach $mod (@mods) {
3ab83790 196 @ns = split(/::|\/|\\/, $mod);
a2c6f8f1 197 $sub = $ns[-1];
56c2fb36 198 $root = File::Spec->catdir(@ns);
a2c6f8f1
PP
199
200 print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
201 foreach (@path) {
56c2fb36 202 next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
a2c6f8f1 203 push @archives, $archive;
56c2fb36 204 if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
a2c6f8f1
PP
205 local(*FH);
206 if(open(FH, $extra)) {
207 my($libs) = <FH>; chomp $libs;
208 push @potential_libs, split /\s+/, $libs;
209 }
210 else {
211 warn "Couldn't open '$extra'";
212 }
213 }
214 last;
215 }
216 }
217 #print STDERR "\@potential_libs = @potential_libs\n";
218
9bbedd82
JH
219 my $libperl;
220 if ($^O eq 'MSWin32') {
221 $libperl = $Config{libperl};
222 }
223 else {
224 $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0] || "-lperl";
225 }
af248097 226
9bbedd82
JH
227 my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
228 $lpath = qq["$lpath"] if $^O eq 'MSWin32';
a2c6f8f1 229 my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
5de3f0da 230 MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
a2c6f8f1
PP
231
232 my $ld_or_bs = $bsloadlibs || $ldloadlibs;
233 print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
f0595bdd
JH
234 my $ccdlflags = _ccdlflags();
235 my $ldflags = _ldflags();
236 my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
a2c6f8f1
PP
237 print STDERR "ldopts: '$linkage'\n" if $Verbose;
238
239 return $linkage if scalar @_;
7e24002c 240 my_return("$linkage\n");
a2c6f8f1
PP
241}
242
243sub ccflags {
f0595bdd
JH
244 my $ccflags = _ccflags();
245 my_return(" $ccflags ");
a2c6f8f1
PP
246}
247
248sub ccdlflags {
f0595bdd
JH
249 my $ccdlflags = _ccdlflags();
250 my_return(" $ccdlflags ");
a2c6f8f1
PP
251}
252
253sub perl_inc {
9bbedd82
JH
254 my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
255 $dir = qq["$dir"] if $^O eq 'MSWin32';
256 my_return(" -I$dir ");
a2c6f8f1
PP
257}
258
259sub ccopts {
7e24002c 260 ccflags . perl_inc;
a2c6f8f1
PP
261}
262
263sub canon {
264 my($as, @ext) = @_;
265 foreach(@ext) {
266 # might be X::Y or lib/auto/X/Y/Y.a
267 next if s!::!/!g;
268 s:^(lib|ext)/(auto/)?::;
269 s:/\w+\.\w+$::;
270 }
271 grep(s:/:$as:, @ext) if ($as ne '/');
272 @ext;
273}
274
275__END__
276
277=head1 NAME
278
279ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications
280
281=head1 SYNOPSIS
282
283
284 perl -MExtUtils::Embed -e xsinit
9bbedd82 285 perl -MExtUtils::Embed -e ccopts
a2c6f8f1
PP
286 perl -MExtUtils::Embed -e ldopts
287
288=head1 DESCRIPTION
289
290ExtUtils::Embed provides utility functions for embedding a Perl interpreter
291and extensions in your C/C++ applications.
292Typically, an application B<Makefile> will invoke ExtUtils::Embed
293functions while building your application.
294
295=head1 @EXPORT
296
297ExtUtils::Embed exports the following functions:
a6006777 298
4e864201
JM
299xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
300ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
a2c6f8f1
PP
301
302=head1 FUNCTIONS
303
bbc7dcd2 304=over 4
2ae324a7 305
a2c6f8f1
PP
306=item xsinit()
307
4e864201 308Generate C/C++ code for the XS initializer function.
a2c6f8f1
PP
309
310When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
311the following options are recognized:
312
4e864201 313B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
a2c6f8f1
PP
314
315B<-o STDOUT> will print to STDOUT.
316
317B<-std> (Write code for extensions that are linked with the current Perl.)
318
319Any additional arguments are expected to be names of modules
320to generate code for.
321
322When invoked with parameters the following are accepted and optional:
323
324C<xsinit($filename,$std,[@modules])>
325
326Where,
327
328B<$filename> is equivalent to the B<-o> option.
329
330B<$std> is boolean, equivalent to the B<-std> option.
331
332B<[@modules]> is an array ref, same as additional arguments mentioned above.
333
334=item Examples
335
a6006777 336
a2c6f8f1
PP
337 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
338
339
340This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
a7665c5e 341to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
a2c6f8f1
PP
342
343Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
344
345 perl -MExtUtils::Embed -e xsinit
346
347
348This will generate code for linking with B<DynaLoader> and
349each static extension found in B<$Config{static_ext}>.
350The code is written to the default file name B<perlxsi.c>.
351
352
353 perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
354
355
356Here, code is written for all the currently linked extensions along with code
357for B<DBI> and B<DBD::Oracle>.
358
359If you have a working B<DynaLoader> then there is rarely any need to statically link in any
360other extensions.
361
362=item ldopts()
363
364Output arguments for linking the Perl library and extensions to your
365application.
366
367When invoked as C<`perl -MExtUtils::Embed -e ldopts --`>
368the following options are recognized:
369
370B<-std>
371
372Output arguments for linking the Perl library and any extensions linked
373with the current Perl.
374
4e864201 375B<-I> E<lt>path1:path2E<gt>
a2c6f8f1
PP
376
377Search path for ModuleName.a archives.
378Default path is B<@INC>.
379Library archives are expected to be found as
380B</some/path/auto/ModuleName/ModuleName.a>
381For example, when looking for B<Socket.a> relative to a search path,
382we should find B<auto/Socket/Socket.a>
383
384When looking for B<DBD::Oracle> relative to a search path,
385we should find B<auto/DBD/Oracle/Oracle.a>
386
a7665c5e 387Keep in mind that you can always supply B</my/own/path/ModuleName.a>
a2c6f8f1
PP
388as an additional linker argument.
389
4e864201 390B<--> E<lt>list of linker argsE<gt>
a2c6f8f1
PP
391
392Additional linker arguments to be considered.
393
394Any additional arguments found before the B<--> token
395are expected to be names of modules to generate code for.
396
397When invoked with parameters the following are accepted and optional:
398
399C<ldopts($std,[@modules],[@link_args],$path)>
400
a7665c5e 401Where:
a2c6f8f1
PP
402
403B<$std> is boolean, equivalent to the B<-std> option.
404
405B<[@modules]> is equivalent to additional arguments found before the B<--> token.
406
407B<[@link_args]> is equivalent to arguments found after the B<--> token.
408
409B<$path> is equivalent to the B<-I> option.
410
411In addition, when ldopts is called with parameters, it will return the argument string
412rather than print it to STDOUT.
413
414=item Examples
415
416
417 perl -MExtUtils::Embed -e ldopts
418
419
420This will print arguments for linking with B<libperl.a>, B<DynaLoader> and
421extensions found in B<$Config{static_ext}>. This includes libraries
422found in B<$Config{libs}> and the first ModuleName.a library
423for each extension that is found by searching B<@INC> or the path
de592821 424specified by the B<-I> option.
a2c6f8f1
PP
425In addition, when ModuleName.a is found, additional linker arguments
426are picked up from the B<extralibs.ld> file in the same directory.
427
428
429 perl -MExtUtils::Embed -e ldopts -- -std Socket
a6006777 430
a2c6f8f1
PP
431
432This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
433
434
435 perl -MExtUtils::Embed -e ldopts -- DynaLoader
436
437
438This will print arguments for linking with just the B<DynaLoader> extension
439and B<libperl.a>.
440
441
442 perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
443
444
445Any arguments after the second '--' token are additional linker
446arguments that will be examined for potential conflict. If there is no
447conflict, the additional arguments will be part of the output.
448
449
450=item perl_inc()
451
452For including perl header files this function simply prints:
453
36477c24 454 -I$Config{archlibexp}/CORE
a2c6f8f1
PP
455
456So, rather than having to say:
457
36477c24 458 perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
a2c6f8f1
PP
459
460Just say:
461
462 perl -MExtUtils::Embed -e perl_inc
463
464=item ccflags(), ccdlflags()
465
466These functions simply print $Config{ccflags} and $Config{ccdlflags}
467
468=item ccopts()
469
470This function combines perl_inc(), ccflags() and ccdlflags() into one.
471
472=item xsi_header()
473
474This function simply returns a string defining the same B<EXTERN_C> macro as
475B<perlmain.c> along with #including B<perl.h> and B<EXTERN.h>.
476
477=item xsi_protos(@modules)
478
479This function returns a string of B<boot_$ModuleName> prototypes for each @modules.
480
481=item xsi_body(@modules)
482
483This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
484function to B<boot_ModuleName> for each @modules.
485
022735b4 486B<xsinit()> uses the xsi_* functions to generate most of its code.
a2c6f8f1 487
2ae324a7
PP
488=back
489
a2c6f8f1
PP
490=head1 EXAMPLES
491
492For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
0325b4c4 493with embedded perl, see L<perlembed>.
a6006777 494
a2c6f8f1
PP
495=head1 SEE ALSO
496
4e864201 497L<perlembed>
a2c6f8f1
PP
498
499=head1 AUTHOR
500
4e864201 501Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
a2c6f8f1 502
4e864201
JM
503Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
504B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.
a2c6f8f1
PP
505
506=cut
507