dynamic_list=' '
for f in $dynamic_ext; do
: the dependency named here will never exist
- dynamic_list="$dynamic_list $f.$dlext"
+ base=`echo "$f" | sed 's/.*\///'`
+ dynamic_list="$dynamic_list ext/$f/$base.$dlext"
done
static_list=' '
croak "Usage: DynaLoader::bootstrap(module)"
unless ($module);
- croak "Can't load module $module, DynaLoader not linked into this perl"
+ croak "Can't load module $module, dynamic loading not available in this perl"
unless defined(&dl_load_file);
print STDERR "DynaLoader::bootstrap($module)\n" if $dl_debug;
# get extension directory path, module name and depth
pname=`echo "$extspec" | sed -e 's:^ext/::' -e 's:/[^/]*$::'`
-mname=`echo "$pname" | sed -e 's!/!::!'`
+mname=`echo "$pname" | sed -e 's!/!::!g'`
depth=`echo "$pname" | sed -e 's![^/][^/]*!..!g'`
make=${altmake-make}
makeargs=''
use Getopt::Std;
-$usage='h2xs [-Aachfm] [-n module_name] [headerfile [extra_libraries]]
- -a Omit AutoLoad facilities from .pm file.
- -c Omit the constant() function from the XS file.
- -A Equivalent to -a -c
- -f Force creation of the extension even if the C header does not exist.
- -h help
- -n Specify a name to use for the extension.
-extra_libraries are any libraries that might be needed for loading
- the extension, e.g. -lm would try to link in the math library.
+sub usage{
+ warn "@_\n" if @_;
+ die 'h2xs [-fnch] [-n module_name] [headerfile [extra_libraries]]
+ -f Force creation of the extension even if the C header does not exist.
+ -n Specify a name to use for the extension (recommended).
+ -c Omit the constant() function and specialised AUTOLOAD from the XS file.
+ -h Display this help message
+extra_libraries
+ are any libraries that might be needed for loading the
+ extension, e.g. -lm would try to link in the math library.
';
+}
-sub usage{ die "Usage: $usage\n" }
-getopts("fhcaAn:") || &usage;
+getopts("fhcAn:") || usage;
-&usage if $opt_h;
-
-if( @ARGV ){
- $path_h = shift;
-}
-elsif( ! @ARGV && ! $opt_n ){
- die "Must supply header file or module name\n";
-}
+usage if $opt_h;
+$opt_c = 1 if $opt_A;
+$path_h = shift;
$extralibs = "@ARGV";
-if( $opt_A ){
- $opt_a = $opt_c = 1;
-}
+
+usage "Must supply header file or module name\n"
+ unless ($path_h or $opt_n);
+
if( $path_h ){
- $name = $path_h;
- if( $path_h =~ s#::#/#g && $opt_n ){
- warn "Nesting of headerfile ignored with -n\n";
+ $name = $path_h;
+ if( $path_h =~ s#::#/#g && $opt_n ){
+ warn "Nesting of headerfile ignored with -n\n";
+ }
+ $path_h .= ".h" unless $path_h =~ /\.h$/;
+ $path_h = "/usr/include/$path_h" unless $path_h =~ m#^[./]#;
+ die "Can't find $path_h\n" if ( ! $opt_f && ! -f $path_h );
+
+ # Scan the header file (we should deal with nested header files)
+ # Record the names of simple #define constants into const_names
+ # Function prototypes are not (currently) processed.
+ open(CH, "<$path_h") || die "Can't open $path_h: $!\n";
+ while (<CH>) {
+ if (/^#[ \t]*define\s+(\w+)\b\s*[^("]/) {
+ $_ = $1;
+ next if /^_.*_h_*$/i; # special case, but for what?
+ $const_names{$_}++;
}
- $path_h .= ".h" unless $path_h =~ /\.h$/;
- $path_h = "/usr/include/$path_h" unless $path_h =~ m#^[./]#;
- die "Can't find $path_h\n" if( ! $opt_f && ! -f $path_h );
+ }
+ close(CH);
+ @const_names = sort keys %const_names;
}
+
$module = $opt_n || do {
$name =~ s/\.h$//;
if( $name !~ /::/ ){
open(XS, ">$modfname.xs") || die "Can't create ext/$modpname/$modfname.xs: $!\n";
open(PM, ">$modfname.pm") || die "Can't create ext/$modpname/$modfname.pm: $!\n";
-
-if( -r $path_h ){
- open(CH, "<$path_h") || die "Can't open $path_h: $!\n";
- while (<CH>) {
- if (/^#[ \t]*define\s+(\w+)\b\s*[^("]/) {
- $_ = $1;
- next if /^_.*_h_*$/i;
- $names{$_}++;
- @AZ = 'A' .. 'Z' if !@AZ && /^[A-Z]/;
- @az = 'a' .. 'z' if !@az && /^[a-z]/;
- @under = '_' if !@under && /^_/;
- }
- }
- close(CH);
- @names = sort keys %names;
-}
-
$" = "\n\t";
warn "Writing ext/$modpname/$modfname.pm\n";
-if( ! $opt_a ){
print PM <<"END";
package $module;
require Exporter;
require AutoLoader;
require DynaLoader;
+
\@ISA = qw(Exporter AutoLoader DynaLoader);
-# Items to export into callers namespace by default
-# (move infrequently used names to \@EXPORT_OK below)
+
+# Items to export into callers namespace by default. Note: do not export
+# names by default without a very good reason. Use EXPORT_OK instead.
+# Do not simply export all your public functions/methods/constants.
\@EXPORT = qw(
- @names
+ @const_names
);
# Other items we are prepared to export if requested
\@EXPORT_OK = qw(
);
+END
+
+print PM <<"END" unless $opt_c;
sub AUTOLOAD {
- if (\@_ > 1) {
+ # This AUTOLOAD function overrides the one inherited from AutoLoader.
+ # It is used to 'autoload' constants from the constant() XS function.
+
+ # NOTE: THIS AUTOLOAD FUNCTION IS FLAWED (but is the best we can do for now).
+ # Avoid old-style ``&CONST'' usage. Either remove the ``&'' or add ``()''.
+ if (\@_ > 0) {
\$AutoLoader::AUTOLOAD = \$AUTOLOAD;
goto &AutoLoader::AUTOLOAD;
}
goto &\$AUTOLOAD;
}
-bootstrap $module;
-
-# Preloaded methods go here. Autoload methods go after __END__, and are
-# processed by the autosplit program.
-
-1;
-__END__
END
-}
-else{
-print PM <<"END";
-package $module;
-require Exporter;
-require DynaLoader;
-\@ISA = qw(Exporter DynaLoader);
-# Items to export into callers namespace by default
-\@EXPORT = qw();
-# Other items we are prepared to export if requested
-\@EXPORT_OK = qw();
+print PM <<"END";
+bootstrap $module;
+# Preloaded methods go here.
-bootstrap $module;
+# Autoload methods go after __END__, and are processed by the autosplit program.
1;
+__END__
END
-}
close PM;
+
warn "Writing ext/$modpname/$modfname.xs\n";
+
print XS <<"END";
#include "EXTERN.h"
#include "perl.h"
switch (*name) {
END
+my(@AZ, @az, @under);
+
+foreach(@const_names){
+ @AZ = 'A' .. 'Z' if !@AZ && /^[A-Z]/;
+ @az = 'a' .. 'z' if !@az && /^[a-z]/;
+ @under = '_' if !@under && /^_/;
+}
+
foreach $letter (@AZ, @az, @under) {
- last if $letter eq 'a' && !@names;
+ last if $letter eq 'a' && !@const_names;
print XS " case '$letter':\n";
my($name);
- while (substr($names[0],0,1) eq $letter) {
- $name = shift(@names);
+ while (substr($const_names[0],0,1) eq $letter) {
+ $name = shift(@const_names);
print XS <<"END";
if (strEQ(name, "$name"))
#ifdef $name
return 0;
}
+END
+}
+
+# Now switch from C to XS by issuing the first MODULE declaration:
+print XS <<"END";
MODULE = $module PACKAGE = $module
+END
+
+# If a constant() function was written then output a corresponding
+# XS declaration:
+print XS <<"END" unless $opt_c;
+
double
constant(name,arg)
char * name
int arg
END
-}
-else{
-print XS <<"END";
-
-MODULE = $module PACKAGE = $module
-
-END
-}
close XS;
-{
+
warn "Writing ext/$modpname/Makefile.PL\n";
open(PL, ">Makefile.PL") || die "Can't create ext/$modpname/Makefile.PL: $!\n";
print PL " 'DEFINE' => '', # e.g., '-DHAVE_SOMETHING' \n";
print PL " 'INC' => '', # e.g., '-I/usr/include/other' \n";
print PL ");\n";
-}
+
system '/bin/ls > MANIFEST';
in the extra-libraries argument.
.SH OPTIONS
.TP
-.B \-f
-Allows an extension to be created for a header even if that
-header is not found in /usr/include.
+.B \-n module_name
+Specifies a name to be used for the extension, e.g., -n RPC::DCE
.TP
-.B \-a
-Omit AutoLoad(), AUTOLOAD, and autosplit from the .pm and Makefile files.
+.B \-f
+Allows an extension to be created for a header even if that header is
+not found in /usr/include.
.TP
.B \-c
-Omit constant() from the .xs file.
-.TP
-.B \-n module_name
-Specifies a name to be used for the extension.
+Omit constant() from the .xs file and corresponding specialised AUTOLOAD from
+the .pm file.
.TP
.B \-A
-Turns on both -a and -c.
+Deprecated synonym for -c.
.SH EXAMPLES
.nf
# Extension is ONC::RPC. Still finds <rpcsvc/rusers.h>
h2xs -n ONC::RPC rpcsvc/rusers
- # Without AUTOLOAD, AutoLoad, autosplit
- h2xs -a rpcsvc/rusers
+ # Without constant() or AUTOLOAD
+ h2xs -c rpcsvc/rusers
# Creates templates for an extension named RPC
- h2xs -Afn RPC
+ h2xs -cfn RPC
# Extension is ONC::RPC.
- h2xs -An ONC::RPC
+ h2xs -cfn ONC::RPC
# Makefile.PL will look for library -lrpc in
# additional directory /opt/net/lib
.SH ENVIRONMENT
No environment variables are used.
.SH AUTHOR
-Larry Wall
+Larry Wall and others
.SH "SEE ALSO"
perl(1) ExtUtils::MakeMaker
.SH DIAGNOSTICS
package ExtUtils::MakeMaker;
-$Version = 3.6; # Last edited 19th Dec 1994 by Tim Bunce
+$Version = 3.7; # Last edited 19th Dec 1994 by Tim Bunce
use Config;
use Carp;
PERL_LIB: Directory containing the Perl library to use.
PERL_SRC: Directory containing the Perl source code
- (use of this should be avoided, it may be removed later)
+ (use of this should be avoided, it may be undefined)
INC: Include file dirs eg: '-I/usr/5include -I/path/to/inc'
DEFINE: something like "-DHAVE_UNISTD_H"
# Perl Macro: With source No source
# PERL_LIB ../../lib /usr/local/lib/perl5
# PERL_ARCHLIB ../../lib /usr/local/lib/perl5/sun4-sunos
- # PERL_SRC ../.. (undecided)
+ # PERL_SRC ../.. (undefined)
# INST Macro: Locally Publically
# INST_LIB ../../lib /usr/local/lib/perl5
}
}
unless ($att{PERL_SRC}){
- # Later versions will not die here.
- die "Unable to locate perl source. Try setting PERL_SRC.\n";
+ warn "Unable to locate perl source.\n";
# we should also consider $ENV{PERL5LIB} here
$att{PERL_LIB} = $Config{'privlib'} unless $att{PERL_LIB};
$att{PERL_ARCHLIB} = $Config{'archlib'} unless $att{PERL_ARCHLIB};
+ $att{PERL_INC} = "$att{PERL_ARCHLIB}/CORE"; # wild guess for now
+ die "Try setting PERL_SRC in Makefile.PL or on command line.\n"
+ unless (-f "$att{PERL_INC}/perl.h");
} else {
$att{PERL_LIB} = "$att{PERL_SRC}/lib" unless $att{PERL_LIB};
$att{PERL_ARCHLIB} = $att{PERL_LIB};
+ $att{PERL_INC} = $att{PERL_SRC};
}
# INST_LIB typically pre-set if building an extension after
$att{OBJECT} =~ s/\n+/ \\\n\t/g;
}
$att{BOOTDEP} = (-f "$att{BASEEXT}_BS") ? "$att{BASEEXT}_BS" : "";
- $att{LDTARGET} = '$(OBJECT)' unless $att{LDTARGET};
+ $att{LD} = ($Config{'ld'} || 'ld') unless $att{LD};
+ $att{LDTARGET} = '$(OBJECT)' unless $att{LDTARGET};
$att{LINKTYPE} = ($Config{'usedl'}) ? 'dynamic' : 'static'
unless $att{LINKTYPE};
# but that's a way off yet).
PERL_SRC = $att{PERL_SRC}
# Perl header files (will eventually be under PERL_LIB)
-PERL_INC = $att{PERL_SRC}
+PERL_INC = $att{PERL_INC}
# Perl binaries
PERL = $att{'PERL'}
FULLPERL = $att{'FULLPERL'}
# same manner as extliblist, e.g., do both and compare results during
# the transition period.
my($cc,$ccflags,$optimize,$large,$split)=@Config{qw(cc ccflags optimize large split)};
- my($prog);
- chop(my($old) = `cd $att{PERL_SRC}; sh $Config{'shellflags'} ./cflags $att{BASEEXT}.c`);
+ my($prog, $old);
+
+ chop($old = `cd $att{PERL_SRC}; sh $Config{'shellflags'} ./cflags $att{BASEEXT}.c`)
+ if $att{PERL_SRC};
+
# Why is this written this way ?
if ($prog = $Config{"$att{BASEEXT}_cflags"}) {
my(@o)=`cc=\"$cc\"
}
my($new) = "$cc -c $ccflags $optimize $large $split";
- if ($new ne $old) {
+ if (defined($old) and $new ne $old) {
warn "Warning (non-fatal): cflags evaluation in MakeMaker differs from shell output\n"
." package: $att{NAME}\n"
." old: $old\n"
." Using 'old' set.\n"
."Please notify perl5-porters\@isu.edu\n";
}
- my($cccmd)=$old;
+ my($cccmd)=($old) ? $old : $new;
"CCCMD = $cccmd\n";
}
sub tool_xsubpp{
- my(@tmdeps) = ('$(PERL_SRC)/ext/typemap');
+ my($xsdir) = '$(PERL_LIB)/ExtUtils';
+ # drop back to old location if xsubpp is not in new location yet
+ $xsdir = '$(PERL_SRC)/ext' unless (-f "$att{PERL_LIB}/ExtUtils/xsubpp");
+ my(@tmdeps) = ('$(XSUBPPDIR)/typemap');
push(@tmdeps, "typemap") if -f "typemap";
my(@tmargs) = map("-typemap $_", @tmdeps);
"
-XSUBPP = \$(PERL_SRC)/ext/xsubpp
+XSUBPPDIR = $xsdir
+XSUBPP = \$(XSUBPPDIR)/xsubpp
XSUBPPDEPS = @tmdeps
XSUBPPARGS = @tmargs
";
sub tools_other{
- q{
+ "
SHELL = /bin/sh
-
+LD = $att{LD}
+".q{
# The following is a portable way to say mkdir -p
MKPATH = $(PERL) -wle '$$"="/"; foreach $$p (@ARGV){ my(@p); foreach(split(/\//,$$p)){ push(@p,$$_); next if -d "@p/"; print "mkdir @p"; mkdir("@p",0777)||die $$! }} exit 0;'
};
# we use touch to prevent make continually trying to remake it.
# The DynaLoader only reads a non-empty file.
$(BOOTSTRAP): '.$att{BOOTDEP}.' $(CONFIGDEP)
- $(PERL) -I$(PERL_LIB) -e \'use ExtUtils::MakeMaker; &mkbootstrap("$(BSLOADLIBS)");\' INST_LIB=$(INST_LIB) PERL_SRC=$(PERL_SRC) NAME=$(NAME)
+ $(PERL) -I$(PERL_LIB) -e \'use ExtUtils::MakeMaker; &mkbootstrap("$(BSLOADLIBS)");\' \
+ INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) PERL_SRC=$(PERL_SRC) NAME=$(NAME)
@touch $(BOOTSTRAP)
$(INST_BOOT): $(BOOTSTRAP)
$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP)
@$(MKPATH) $(INST_AUTODIR)
$(ARMAYBE) cr $(BASEEXT).a $(OBJECT)
- ld $(LDDLFLAGS) -o $@ $(LDTARGET) $(OTHERLDFLAGS) $(MYEXTLIB) $(LDLOADLIBS)
+ $(LD) $(LDDLFLAGS) -o $@ $(LDTARGET) $(OTHERLDFLAGS) $(MYEXTLIB) $(LDLOADLIBS)
';
}
push(@m, <<'END');
ar cr $@ $(OBJECT) && $(RANLIB) $@
- @: Old mechanism - still needed:
- echo $(EXTRALIBS) >> $(PERL_SRC)/ext.libs
@: New mechanism - not yet used:
- echo $(EXTRALIBS) > $(INST_ARCHAUTODIR)/extralibs.ld
+ @echo $(EXTRALIBS) > $(INST_ARCHAUTODIR)/extralibs.ld
cp $@ $(INST_ARCHAUTODIR)/
END
+ push(@m, <<'END') if $att{PERL_SRC};
+ @: Old mechanism - still needed:
+ @echo $(EXTRALIBS) >> $(PERL_SRC)/ext.libs
+END
join('', "\n",@m);
}
$(OBJECT) : $(PERL_HDRS)
');
- # Don't output this if PERL_SRC not available:
+
push(@m,'
$(PERL_INC)/config.h: $(PERL_SRC)/config.sh; cd $(PERL_SRC); /bin/sh config_h.SH
$(PERL_INC)/embed.h: $(PERL_SRC)/config.sh; cd $(PERL_SRC); /bin/sh embed_h.SH
-');
+') if $att{PERL_SRC};
+
# This needs a better home:
push(@m, join(" ", values %{$att{XS}})." : \$(XSUBPPDEPS)\n")
if %{$att{XS}};
my($self, $libs) = @_;
return ("", "", "") unless $libs;
print STDERR "Potential libraries are '$libs':" if $Verbose;
- my(@old) = MY->old_extliblist($libs);
my(@new) = MY->new_extliblist($libs);
- my($oldlibs) = join(" : ",@old);
- my($newlibs) = join(" : ",@new);
- warn "Warning (non-fatal): $att{NAME} extliblist consistency check failed:\n".
- " old: $oldlibs\n".
- " new: $newlibs\n".
- "Using 'new' set. Please notify perl5-porters\@isu.edu.\n"
- if "$newlibs" ne "$oldlibs";
+ if ($att{PERL_SRC}){
+ my(@old) = MY->old_extliblist($libs);
+ my($oldlibs) = join(" : ",@old);
+ my($newlibs) = join(" : ",@new);
+ warn "Warning (non-fatal): $att{NAME} extliblist consistency check failed:\n".
+ " old: $oldlibs\n".
+ " new: $newlibs\n".
+ "Using 'new' set. Please notify perl5-porters\@isu.edu.\n"
+ if ("$newlibs" ne "$oldlibs");
+ }
@new;
}
sub old_extliblist {
my($self, $potential_libs)=@_;
return ("", "", "") unless $potential_libs;
+ die "old_extliblist requires PERL_SRC" unless $att{PERL_SRC};
my(%attrib, @w);
# Now run ext/util/extliblist to discover what *libs definitions
if (@fullname=<${thispth}/lib${thislib}.${so}.[0-9]*>){
$fullname=$fullname[-1]; #ATTN: 10 looses against 9!
} elsif (-f ($fullname="$thispth/lib$thislib.$so")){
- } elsif (-f ($fullname="$thispth/lib${thislib}_s.a")){
+ } elsif (-f ($fullname="$thispth/lib${thislib}_s.a")
+ && ($thislib .= "_s") ){ # we must explicitly ask for _s version
} elsif (-f ($fullname="$thispth/lib$thislib.a")){
} elsif (-f ($fullname="$thispth/Slib$thislib.a")){
} else {
# what do we know about this library...
my $is_dyna = ($fullname !~ /\.a$/);
- my $in_perl = ($libs =~ /\B-l${thislib}\b|\B-l${thislib}_s\b/s);
+ my $in_perl = ($libs =~ /\B-l${thislib}\b/s);
# Do not add it into the list if it is already linked in
# with the main perl executable.