-# $Id: Embed.pm,v 1.17 1996/07/02 13:48:17 dougm Exp $
+# $Id: Embed.pm,v 1.1.1.1 2002/01/16 19:27:19 schwern Exp $
require 5.002;
package ExtUtils::Embed;
require FileHandle;
use Config;
use Getopt::Std;
+use File::Spec;
#Only when we need them
#require ExtUtils::MakeMaker;
);
use strict;
-$VERSION = sprintf("%d.%02d", q$Revision: 1.17 $ =~ /(\d+)\.(\d+)/);
-#for the namespace change
-$Devel::embed::VERSION = "99.99";
-
-sub Version { $VERSION; }
+$VERSION = 1.26;
@ISA = qw(Exporter);
@EXPORT = qw(&xsinit &ldopts
$Verbose = 0;
$lib_ext = $Config{lib_ext} || '.a';
+sub is_cmd { $0 eq '-e' }
+
+sub my_return {
+ my $val = shift;
+ if(is_cmd) {
+ print $val;
+ }
+ else {
+ return $val;
+ }
+}
+
sub xsinit {
my($file, $std, $mods) = @_;
my($fh,@mods,%seen);
$file ||= "perlxsi.c";
+ my $xsinit_proto = "pTHX";
if (@_) {
@mods = @$mods if $mods;
@mods = grep(!$seen{$_}++, @mods);
print $fh &xsi_header();
- print $fh "EXTERN_C void xs_init _((void));\n\n";
+ print $fh "EXTERN_C void xs_init ($xsinit_proto);\n\n";
print $fh &xsi_protos(@mods);
- print $fh "\nEXTERN_C void\nxs_init()\n{\n";
+ print $fh "\nEXTERN_C void\nxs_init($xsinit_proto)\n{\n";
print $fh &xsi_body(@mods);
print $fh "}\n";
sub xsi_header {
return <<EOF;
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include <EXTERN.h>
#include <perl.h>
-#ifdef __cplusplus
-}
-# ifndef EXTERN_C
-# define EXTERN_C extern "C"
-# endif
-#else
-# ifndef EXTERN_C
-# define EXTERN_C extern
-# endif
-#endif
-
EOF
}
sub xsi_protos {
my(@exts) = @_;
my(@retval,%seen);
-
+ my $boot_proto = "pTHX_ CV* cv";
foreach $_ (@exts){
my($pname) = canon('/', $_);
my($mname, $cname);
($mname = $pname) =~ s!/!::!g;
($cname = $pname) =~ s!/!__!g;
- my($ccode) = "EXTERN_C void boot_${cname} _((CV* cv));\n";
+ my($ccode) = "EXTERN_C void boot_${cname} ($boot_proto);\n";
next if $seen{$ccode}++;
push(@retval, $ccode);
}
my(@exts) = @_;
my($pname,@retval,%seen);
my($dl) = canon('/','DynaLoader');
+ push(@retval, "\tchar *file = __FILE__;\n");
push(@retval, "\tdXSUB_SYS;\n") if $] > 5.002;
- push(@retval, "\tchar *file = __FILE__;\n\n");
+ push(@retval, "\n");
foreach $_ (@exts){
my($pname) = canon('/', $_);
@Extensions;
}
+sub _escape {
+ my $arg = shift;
+ $$arg =~ s/([\(\)])/\\$1/g;
+}
+
+sub _ldflags {
+ my $ldflags = $Config{ldflags};
+ _escape(\$ldflags);
+ return $ldflags;
+}
+
+sub _ccflags {
+ my $ccflags = $Config{ccflags};
+ _escape(\$ccflags);
+ return $ccflags;
+}
+
+sub _ccdlflags {
+ my $ccdlflags = $Config{ccdlflags};
+ _escape(\$ccdlflags);
+ return $ccdlflags;
+}
+
sub ldopts {
require ExtUtils::MakeMaker;
require ExtUtils::Liblist;
my(@mods,@link_args,@argv);
my($dllib,$config_libs,@potential_libs,@path);
local($") = ' ' unless $" eq ' ';
- my $MM = bless {} => 'MY';
if (scalar @_) {
@link_args = @$link_args if $link_args;
@mods = @$mods if $mods;
}
}
$std = 1 unless scalar @link_args;
- @path = $path ? split(/:/, $path) : @INC;
+ my $sep = $Config{path_sep} || ':';
+ @path = $path ? split(/\Q$sep/, $path) : @INC;
push(@potential_libs, @link_args) if scalar @link_args;
- push(@potential_libs, $Config{libs}) if defined $std;
+ # makemaker includes std libs on windows by default
+ if ($^O ne 'MSWin32' and defined($std)) {
+ push(@potential_libs, $Config{perllibs});
+ }
push(@mods, static_ext()) if $std;
my($mod,@ns,$root,$sub,$extra,$archive,@archives);
print STDERR "Searching (@path) for archives\n" if $Verbose;
foreach $mod (@mods) {
- @ns = split('::', $mod);
+ @ns = split(/::|\/|\\/, $mod);
$sub = $ns[-1];
- $root = $MM->catdir(@ns);
+ $root = File::Spec->catdir(@ns);
print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose;
foreach (@path) {
- next unless -e ($archive = $MM->catdir($_,"auto",$root,"$sub$lib_ext"));
+ next unless -e ($archive = File::Spec->catdir($_,"auto",$root,"$sub$lib_ext"));
push @archives, $archive;
- if(-e ($extra = $MM->catdir($_,"auto",$root,"extralibs.ld"))) {
+ if(-e ($extra = File::Spec->catdir($_,"auto",$root,"extralibs.ld"))) {
local(*FH);
if(open(FH, $extra)) {
my($libs) = <FH>; chomp $libs;
}
#print STDERR "\@potential_libs = @potential_libs\n";
+ my $libperl;
+ if ($^O eq 'MSWin32') {
+ $libperl = $Config{libperl};
+ }
+ elsif ($^O eq 'os390' && $Config{usedl}) {
+ # Nothing for OS/390 (z/OS) dynamic.
+ } else {
+ $libperl = (grep(/^-l\w*perl\w*$/, @link_args))[0]
+ || ($Config{libperl} =~ /^lib(\w+)(\Q$lib_ext\E|\.\Q$Config{dlext}\E)$/
+ ? "-l$1" : '')
+ || "-lperl";
+ }
+
+ my $lpath = File::Spec->catdir($Config{archlibexp}, 'CORE');
+ $lpath = qq["$lpath"] if $^O eq 'MSWin32';
my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) =
- $MM->ext(join ' ',
- $MM->catdir("-L$Config{archlib}", "CORE"), " -lperl",
- @potential_libs);
+ MM->ext(join ' ', "-L$lpath", $libperl, @potential_libs);
my $ld_or_bs = $bsloadlibs || $ldloadlibs;
print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose;
- my $linkage = "$Config{ldflags} @archives $ld_or_bs";
+ my $ccdlflags = _ccdlflags();
+ my $ldflags = _ldflags();
+ my $linkage = "$ccdlflags $ldflags @archives $ld_or_bs";
print STDERR "ldopts: '$linkage'\n" if $Verbose;
return $linkage if scalar @_;
- print "$linkage\n";
+ my_return("$linkage\n");
}
sub ccflags {
- print " $Config{ccflags} ";
+ my $ccflags = _ccflags();
+ my_return(" $ccflags ");
}
sub ccdlflags {
- print " $Config{ccdlflags} ";
+ my $ccdlflags = _ccdlflags();
+ my_return(" $ccdlflags ");
}
sub perl_inc {
- print " -I $Config{archlib}/CORE ";
+ my $dir = File::Spec->catdir($Config{archlibexp}, 'CORE');
+ $dir = qq["$dir"] if $^O eq 'MSWin32';
+ my_return(" -I$dir ");
}
sub ccopts {
- ccflags;
- ccdlflags;
- perl_inc;
+ ccflags . perl_inc;
}
sub canon {
perl -MExtUtils::Embed -e xsinit
+ perl -MExtUtils::Embed -e ccopts
perl -MExtUtils::Embed -e ldopts
=head1 DESCRIPTION
=head1 @EXPORT
ExtUtils::Embed exports the following functions:
-
-L<xsinit()>, L<ldopts()>, L<ccopts()>, L<perl_inc()>, L<ccflags()>,
-L<ccdlflags()>, L<xsi_header()>, L<xsi_protos()>, L<xsi_body()>
+
+xsinit(), ldopts(), ccopts(), perl_inc(), ccflags(),
+ccdlflags(), xsi_header(), xsi_protos(), xsi_body()
=head1 FUNCTIONS
+=over 4
+
=item xsinit()
-Generate C/C++ code for the XS intializer function.
+Generate C/C++ code for the XS initializer function.
When invoked as C<`perl -MExtUtils::Embed -e xsinit --`>
the following options are recognized:
-B<-o> <output filename> (Defaults to B<perlxsi.c>)
+B<-o> E<lt>output filenameE<gt> (Defaults to B<perlxsi.c>)
B<-o STDOUT> will print to STDOUT.
=item Examples
-
+
perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket
This will generate code with an B<xs_init> function that glues the perl B<Socket::bootstrap> function
-to the C B<boot_Socket> function and writes it to a file named "xsinit.c".
+to the C B<boot_Socket> function and writes it to a file named F<xsinit.c>.
Note that B<DynaLoader> is a special case where it must call B<boot_DynaLoader> directly.
Output arguments for linking the Perl library and any extensions linked
with the current Perl.
-B<-I> <path1:path2>
+B<-I> E<lt>path1:path2E<gt>
Search path for ModuleName.a archives.
Default path is B<@INC>.
When looking for B<DBD::Oracle> relative to a search path,
we should find B<auto/DBD/Oracle/Oracle.a>
-Keep in mind, you can always supply B</my/own/path/ModuleName.a>
+Keep in mind that you can always supply B</my/own/path/ModuleName.a>
as an additional linker argument.
-B<--> <list of linker args>
+B<--> E<lt>list of linker argsE<gt>
Additional linker arguments to be considered.
C<ldopts($std,[@modules],[@link_args],$path)>
-Where,
+Where:
B<$std> is boolean, equivalent to the B<-std> option.
perl -MExtUtils::Embed -e ldopts
-This will print arguments for linking with B<libperl.a>, B<DynaLoader> and
+This will print arguments for linking with B<libperl> and
extensions found in B<$Config{static_ext}>. This includes libraries
found in B<$Config{libs}> and the first ModuleName.a library
for each extension that is found by searching B<@INC> or the path
-specifed by the B<-I> option.
+specified by the B<-I> option.
In addition, when ModuleName.a is found, additional linker arguments
are picked up from the B<extralibs.ld> file in the same directory.
perl -MExtUtils::Embed -e ldopts -- -std Socket
-
-This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
-
-
- perl -MExtUtils::Embed -e ldopts -- DynaLoader
-
-
-This will print arguments for linking with just the B<DynaLoader> extension
-and B<libperl.a>.
+This will do the same as the above example, along with printing additional arguments for linking with the B<Socket> extension.
perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
-
Any arguments after the second '--' token are additional linker
arguments that will be examined for potential conflict. If there is no
conflict, the additional arguments will be part of the output.
For including perl header files this function simply prints:
- -I $Config{archlib}/CORE
+ -I$Config{archlibexp}/CORE
So, rather than having to say:
- perl -MConfig -e 'print "-I $Config{archlib}/CORE"'
+ perl -MConfig -e 'print "-I$Config{archlibexp}/CORE"'
Just say:
This function returns a string of calls to B<newXS()> that glue the module B<bootstrap>
function to B<boot_ModuleName> for each @modules.
-B<xsinit()> uses the xsi_* functions to generate most of it's code.
+B<xsinit()> uses the xsi_* functions to generate most of its code.
+
+=back
=head1 EXAMPLES
For examples on how to use B<ExtUtils::Embed> for building C/C++ applications
-with embedded perl, see the eg/ directory and the I<perlembed> man page.
-
+with embedded perl, see L<perlembed>.
+
=head1 SEE ALSO
-the I<perlembed> man page
+L<perlembed>
=head1 AUTHOR
-Doug MacEachern <dougm@osf.org>
+Doug MacEachern E<lt>F<dougm@osf.org>E<gt>
-Based on ideas from Tim Bunce <Tim.Bunce@ig.co.uk> and
-B<minimod.pl> by Andreas Koenig <k@anna.in-berlin.de> and Tim Bunce.
+Based on ideas from Tim Bunce E<lt>F<Tim.Bunce@ig.co.uk>E<gt> and
+B<minimod.pl> by Andreas Koenig E<lt>F<k@anna.in-berlin.de>E<gt> and Tim Bunce.
=cut