This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
boot_Win32CORE needs to be XS_EXTERNAL() following commit ab1478f7146843f7.
[perl5.git] / makedef.pl
index 4207c02..a4b5ced 100644 (file)
@@ -3,13 +3,13 @@
 # Create the export list for perl.
 #
 # Needed by WIN32 and OS/2 for creating perl.dll,
-# and by AIX for creating libperl.a when -Dusershrplib is in effect,
+# and by AIX for creating libperl.a when -Duseshrplib is in effect,
 # and by VMS for creating perlshr.exe.
 #
 # Reads from information stored in
 #
+#    %Config::Config (ie config.sh)
 #    config.h
-#    config.sh
 #    global.sym
 #    globvar.sym
 #    intrpvar.h
@@ -35,36 +35,41 @@ BEGIN { unshift @INC, "lib" }
 use Config;
 use strict;
 
-use vars qw($PLATFORM $CCTYPE $FILETYPE $TARG_DIR);
-
-$CCTYPE = 'MSVC';
-$TARG_DIR = '';
+my %ARGS = (CCTYPE => 'MSVC');
 
 my %define;
 
+sub process_cc_flags {
+    foreach (map {split /\s+/, $_} @_) {
+       $define{$1} = $2 // 1 if /^-D(\w+)(?:=(.+))?/;
+    }
+}
+
 while (@ARGV) {
     my $flag = shift;
-    if ($flag =~ s/^CC_FLAGS=/ /) {
-       for my $fflag ($flag =~ /(?:^|\s)-D(\S+)/g) {
-           $fflag     .= '=1' unless $fflag =~ /^(\w+)=/;
-           $define{$1} = $2   if $fflag =~ /^(\w+)=(.+)$/;
-       }
-       next;
+    if ($flag =~ /^(?:CC_FLAGS=)?(-D\w.*)/) {
+       process_cc_flags($1);
+    } elsif ($flag =~ /^(CCTYPE|FILETYPE|PLATFORM|TARG_DIR)=(.+)$/) {
+       $ARGS{$1} = $2;
     }
-    $define{$1} = 1 if ($flag =~ /^-D(\w+)$/);
-    $define{$1} = $2 if ($flag =~ /^-D(\w+)=(.+)$/);
-    $CCTYPE   = $1 if ($flag =~ /^CCTYPE=(\w+)$/);
-    $PLATFORM = $1 if ($flag =~ /^PLATFORM=(\w+)$/);
-    $FILETYPE = $1 if ($flag =~ /^FILETYPE=(\w+)$/);
-    $TARG_DIR = $1 if $flag =~ /^TARG_DIR=(.+)$/;
 }
 
-my @PLATFORM = qw(aix win32 wince os2 netware vms);
-my %PLATFORM;
-@PLATFORM{@PLATFORM} = ();
+{
+    my @PLATFORM = qw(aix win32 wince os2 netware vms);
+    my %PLATFORM;
+    @PLATFORM{@PLATFORM} = ();
+
+    die "PLATFORM undefined, must be one of: @PLATFORM\n"
+       unless defined $ARGS{PLATFORM};
+    die "PLATFORM must be one of: @PLATFORM\n"
+       unless exists $PLATFORM{$ARGS{PLATFORM}};
+}
 
-defined $PLATFORM || die "PLATFORM undefined, must be one of: @PLATFORM\n";
-exists $PLATFORM{$PLATFORM} || die "PLATFORM must be one of: @PLATFORM\n";
+# Is the following guard strictly necessary? Added during refactoring
+# to keep the same behaviour when merging other code into here.
+process_cc_flags(@Config{qw(ccflags optimize)})
+    if $ARGS{PLATFORM} ne 'win32' && $ARGS{PLATFORM} ne 'wince'
+    && $ARGS{PLATFORM} ne 'netware';
 
 # Add the compile-time options that miniperl was built with to %define.
 # On Win32 these are not the same options as perl itself will be built
@@ -87,38 +92,18 @@ my %exportperlmalloc =
        Perl_calloc             =>      "calloc",
     );
 
-my $exportperlmalloc = $PLATFORM eq 'os2';
+my $exportperlmalloc = $ARGS{PLATFORM} eq 'os2';
 
-my $config_sh   = "config.sh";
 my $config_h    = "config.h";
 my $intrpvar_h  = "intrpvar.h";
 my $perlvars_h  = "perlvars.h";
 my $global_sym  = "global.sym";
 my $globvar_sym = "globvar.sym";
 my $perlio_sym  = "perlio.sym";
-my $static_ext = "";
-
-s/^/$TARG_DIR/ foreach($intrpvar_h, $perlvars_h, $global_sym, $globvar_sym,
-                      $perlio_sym, $config_sh);
 
-unless ($PLATFORM eq 'win32' || $PLATFORM eq 'wince' || $PLATFORM eq 'netware') {
-    open(CFG,$config_sh) || die "Cannot open $config_sh: $!\n";
-    while (<CFG>) {
-       if (/^(?:ccflags|optimize)='(.+)'$/) {
-           $_ = $1;
-           $define{$1} = 1 while /-D(\w+)/g;
-       }
-       $define{$1} = $2
-           if /^(config_args|archname|perl_patchlevel)='(.+)'$/;
-    }
-    close(CFG);
-}
-if ($PLATFORM eq 'win32' || $PLATFORM eq 'wince') {
-    open(CFG, '<', $config_sh) || die "Cannot open $config_sh: $!\n";
-    if ((join '', <CFG>) =~ /^static_ext='(.*)'$/m) {
-        $static_ext = $1;
-    }
-    close(CFG);
+if (exists $ARGS{TARG_DIR}) {
+    s/^/$ARGS{TARG_DIR}/
+       foreach $intrpvar_h, $perlvars_h, $global_sym, $globvar_sym, $perlio_sym;
 }
 
 open(CFG,$config_h) || die "Cannot open $config_h: $!\n";
@@ -145,7 +130,7 @@ $define{PERL_IMPLICIT_CONTEXT} ||=
     $define{USE_ITHREADS} ||
     $define{MULTIPLICITY} ;
 
-if ($define{USE_ITHREADS} && $PLATFORM ne 'win32' && $^O ne 'darwin') {
+if ($define{USE_ITHREADS} && $ARGS{PLATFORM} ne 'win32' && $^O ne 'darwin') {
     $define{USE_REENTRANT_API} = 1;
 }
 
@@ -156,7 +141,7 @@ print STDERR "Defines: (" . join(' ', sort keys %define) . ")\n";
 my $sym_ord = 0;
 my %ordinal;
 
-if ($PLATFORM eq 'os2') {
+if ($ARGS{PLATFORM} eq 'os2') {
     if (open my $fh, '<', 'perl5.def') {
       while (<$fh>) {
        last if /^\s*EXPORTS\b/;
@@ -192,7 +177,7 @@ sub readvar {
     while (<$vars>) {
        # All symbols have a Perl_ prefix because that's what embed.h sticks
        # in front of them.  The A?I?S?C? is strictly speaking wrong.
-       next unless /\bPERLVAR(A?I?S?C?)\(([IGT])(\w+)/;
+       next unless /\bPERLVAR(A?I?S?C?)\(([IGT]),\s*(\w+)/;
 
        my $var = "PL_$3";
        my $symbol = $proc ? &$proc($1,$2,$3) : $var;
@@ -200,7 +185,7 @@ sub readvar {
     }
 }
 
-if ($PLATFORM ne 'os2') {
+if ($ARGS{PLATFORM} ne 'os2') {
     ++$skip{$_} foreach qw(
                     PL_cryptseen
                     PL_opsave
@@ -215,11 +200,11 @@ if ($PLATFORM ne 'os2') {
                     Perl_my_ntohl
                     Perl_my_swap
                         );
-    if ($PLATFORM eq 'vms') {
+    if ($ARGS{PLATFORM} eq 'vms') {
        ++$skip{PL_statusvalue_posix};
     } else {
        ++$skip{PL_statusvalue_vms};
-       if ($PLATFORM ne 'aix') {
+       if ($ARGS{PLATFORM} ne 'aix') {
            ++$skip{$_} foreach qw(
                                PL_DBcv
                                PL_generation
@@ -232,14 +217,14 @@ if ($PLATFORM ne 'os2') {
     }
 }
 
-if ($PLATFORM ne 'vms') {
+if ($ARGS{PLATFORM} ne 'vms') {
     # VMS does its own thing for these symbols.
     ++$skip{$_} foreach qw(
                        PL_sig_handlers_initted
                        PL_sig_ignoring
                        PL_sig_defaulting
                         );
-    if ($PLATFORM ne 'win32') {
+    if ($ARGS{PLATFORM} ne 'win32') {
        ++$skip{$_} foreach qw(
                            Perl_do_spawn
                            Perl_do_spawn_nowait
@@ -309,13 +294,8 @@ if ($define{'MYMALLOC'}) {
                    MallocCfg_ptr
                    MallocCfgP_ptr
                    ));
-    if ($define{'USE_ITHREADS'}) {
-       try_symbols(qw(
-                       PL_malloc_mutex
-                       ));
-    }
-    else {
-       ++$skip{PL_malloc_mutex};
+    unless ($define{USE_ITHREADS}) {
+       ++$skip{PL_malloc_mutex}
     }
 }
 else {
@@ -507,6 +487,11 @@ unless ($define{HAS_MMAP}) {
 
 if ($define{HAS_SIGACTION}) {
     ++$skip{PL_sig_trapped};
+
+    if ($ARGS{PLATFORM} eq 'vms') {
+        # FAKE_PERSISTENT_SIGNAL_HANDLERS defined as !defined(HAS_SIGACTION)
+        ++$skip{PL_sig_ignoring};
+    }
 }
 
 unless ($define{USE_LOCALE_COLLATE}) {
@@ -546,7 +531,7 @@ if ($define{HAS_SIGNBIT}) {
 if ($define{'PERL_GLOBAL_STRUCT'}) {
     readvar($perlvars_h, \%skip);
     ++$export{Perl_GetVars};
-    try_symbols(qw(PL_Vars PL_VarsPtr)) unless $CCTYPE eq 'GCC';
+    try_symbols(qw(PL_Vars PL_VarsPtr)) unless $ARGS{CCTYPE} eq 'GCC';
 } else {
     ++$skip{$_} foreach qw(Perl_init_global_struct Perl_free_global_struct);
 }
@@ -632,7 +617,7 @@ my @layer_syms = qw(
                    Perl_PerlIO_unread
                    Perl_PerlIO_write
 );
-if ($PLATFORM eq 'netware') {
+if ($ARGS{PLATFORM} eq 'netware') {
     push(@layer_syms,'PL_def_layerlist','PL_known_layers','PL_perlio');
 }
 
@@ -724,14 +709,6 @@ if ($define{'USE_PERLIO'}) {
        # PerlIO with layers - export implementation
        try_symbols(@layer_syms, 'perlsio_binmode');
     }
-    if ($define{'USE_ITHREADS'}) {
-       try_symbols(qw(
-                       PL_perlio_mutex
-                       ));
-    }
-    else {
-       ++$skip{PL_perlio_mutex};
-    }
 } else {
        # -Uuseperlio
        # Skip the PerlIO layer symbols - although
@@ -745,6 +722,7 @@ if ($define{'USE_PERLIO'}) {
                        PL_perlio_debug_fd
                        PL_perlio_fd_refcnt
                        PL_perlio_fd_refcnt_size
+                       PL_perlio_mutex
                             );
 
        # Also do NOT add abstraction symbols from $perlio_sym
@@ -758,17 +736,15 @@ if ($define{'USE_PERLIO'}) {
 # many symbols against them.
 
 for my $syms (@syms) {
-    open (GLOBAL, "<$syms") || die "failed to open $syms: $!\n";
-    while (<GLOBAL>) {
-       next if (!/^[A-Za-z]/);
-       # Functions have a Perl_ prefix
-       # Variables have a PL_ prefix
-       chomp($_);
-       my $symbol = ($syms =~ /var\.sym$/i ? "PL_" : "");
-       $symbol .= $_;
+    open my $global, '<', $syms or die "failed to open $syms: $!\n";
+    # Functions already have a Perl_ prefix
+    # Variables need a PL_ prefix
+    my $prefix = $syms =~ /var\.sym$/i ? 'PL_' : '';
+    while (<$global>) {
+       next unless /^([A-Za-z].*)/;
+       my $symbol = "$prefix$1";
        ++$export{$symbol} unless exists $skip{$symbol};
     }
-    close(GLOBAL);
 }
 
 # variables
@@ -776,7 +752,7 @@ for my $syms (@syms) {
 if ($define{'MULTIPLICITY'} && $define{PERL_GLOBAL_STRUCT}) {
     readvar($perlvars_h, \%export, sub { "Perl_" . $_[1] . $_[2] . "_ptr" });
     # XXX AIX seems to want the perlvars.h symbols, for some reason
-    if ($PLATFORM eq 'aix' or $PLATFORM eq 'os2') {    # OS/2 needs PL_thr_key
+    if ($ARGS{PLATFORM} eq 'aix' or $ARGS{PLATFORM} eq 'os2') {        # OS/2 needs PL_thr_key
        readvar($perlvars_h, \%export);
     }
 }
@@ -790,18 +766,19 @@ else {
 }
 
 # Oddities from PerlIO
+# All have alternate implementations in perlio.c, so always exist.
+# Should they be considered to be part of the API?
 try_symbols(qw(
                    PerlIO_binmode
                    PerlIO_getpos
                    PerlIO_init
                    PerlIO_setpos
                    PerlIO_sprintf
-                   PerlIO_sv_dup
                    PerlIO_tmpfile
                    PerlIO_vsprintf
             ));
 
-if ($PLATFORM eq 'win32') {
+if ($ARGS{PLATFORM} eq 'win32') {
     try_symbols(qw(
                                 setgid
                                 setuid
@@ -813,7 +790,7 @@ if ($PLATFORM eq 'win32') {
                 ));
 }
 
-if ($PLATFORM =~ /^win(?:32|ce)$/) {
+if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) {
     try_symbols(qw(
                            Perl_init_os_extras
                            Perl_thread_create
@@ -969,11 +946,11 @@ if ($PLATFORM =~ /^win(?:32|ce)$/) {
                            win32_getchar
                            win32_putchar
                 ));
-    if ($CCTYPE eq "BORLAND") {
+    if ($ARGS{CCTYPE} eq "BORLAND") {
        try_symbols('_matherr');
     }
 }
-elsif ($PLATFORM eq 'vms') {
+elsif ($ARGS{PLATFORM} eq 'vms') {
     try_symbols(qw(
                      Perl_cando
                      Perl_cando_by_name
@@ -1058,7 +1035,7 @@ elsif ($PLATFORM eq 'vms') {
                      PerlIO_openn
                 ));
 }
-elsif ($PLATFORM eq 'os2') {
+elsif ($ARGS{PLATFORM} eq 'os2') {
     try_symbols(qw(
                      ctermid
                      get_sysinfo
@@ -1127,7 +1104,7 @@ elsif ($PLATFORM eq 'os2') {
                      PL_do_undump
                 ));
 }
-elsif ($PLATFORM eq 'netware') {
+elsif ($ARGS{PLATFORM} eq 'netware') {
     try_symbols(qw(
                        Perl_init_os_extras
                        Perl_thread_create
@@ -1266,13 +1243,26 @@ elsif ($PLATFORM eq 'netware') {
                 ));
 }
 
-# records of type boot_module for statically linked modules (except Dynaloader)
-$static_ext =~ s/\//__/g;
-$static_ext =~ s/\bDynaLoader\b//;
-try_symbols(map {"boot_$_"} grep {/\S/} split /\s+/, $static_ext);
-try_symbols("init_Win32CORE") if $static_ext =~ /\bWin32CORE\b/;
+# When added this code was only run for Win32 and WinCE
+# Currently only Win32 links static extensions into the shared library.
+# The WinCE makefile doesn't appear to support static extensions, so this code
+# can't have any effect there.
+# The NetWare Makefile doesn't support static extensions (and hardcodes the
+# list of dynamic extensions, and the rules to build them)
+# For *nix (and presumably OS/2) with a shared libperl, Makefile.SH compiles
+# static extensions with -fPIC, but links them to perl, not libperl.so
+# The VMS build scripts don't yet implement static extensions at all.
+
+if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) {
+    # records of type boot_module for statically linked modules (except Dynaloader)
+    my $static_ext = $Config{static_ext} // "";
+    $static_ext =~ s/\//__/g;
+    $static_ext =~ s/\bDynaLoader\b//;
+    try_symbols(map {"boot_$_"} grep {/\S/} split /\s+/, $static_ext);
+    try_symbols("init_Win32CORE") if $static_ext =~ /\bWin32CORE\b/;
+}
 
-if ($PLATFORM eq 'os2') {
+if ($ARGS{PLATFORM} eq 'os2') {
     my (%mapped, @missing);
     open MAP, 'miniperl.map' or die 'Cannot read miniperl.map';
     /^\s*[\da-f:]+\s+(\w+)/i and $mapped{$1}++ foreach <MAP>;
@@ -1290,22 +1280,23 @@ if ($PLATFORM eq 'os2') {
 
 # Start with platform specific headers:
 
-if ($PLATFORM =~ /^win(?:32|ce)$/) {
-    (my $dll = ($define{PERL_DLL} || "perl515")) =~ s/\.dll$//i;
+if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) {
+    my $dll = $define{PERL_DLL} ? $define{PERL_DLL} =~ s/\.dll$//ir
+       : "perl$Config{api_revision}$Config{api_version}";
     print "LIBRARY $dll\n";
     # The DESCRIPTION module definition file statement is not supported
     # by VC7 onwards.
-    if ($CCTYPE =~ /^(?:MSVC60|GCC|BORLAND)$/) {
+    if ($ARGS{CCTYPE} =~ /^(?:MSVC60|GCC|BORLAND)$/) {
        print "DESCRIPTION 'Perl interpreter'\n";
     }
     print "EXPORTS\n";
 }
-elsif ($PLATFORM eq 'os2') {
+elsif ($ARGS{PLATFORM} eq 'os2') {
     (my $v = $]) =~ s/(\d\.\d\d\d)(\d\d)$/$1_$2/;
-    $v .= '-thread' if $define{archname} =~ /-thread/;
+    $v .= '-thread' if $Config{archname} =~ /-thread/;
     (my $dll = $define{PERL_DLL}) =~ s/\.dll$//i;
-    $v .= "\@$define{perl_patchlevel}" if $define{perl_patchlevel};
-    my $d = "DESCRIPTION '\@#perl5-porters\@perl.org:$v#\@ Perl interpreter, configured as $define{config_args}'";
+    $v .= "\@$Config{perl_patchlevel}" if $Config{perl_patchlevel};
+    my $d = "DESCRIPTION '\@#perl5-porters\@perl.org:$v#\@ Perl interpreter, configured as $Config{config_args}'";
     $d = substr($d, 0, 249) . "...'" if length $d > 253;
     print <<"---EOP---";
 LIBRARY '$dll' INITINSTANCE TERMINSTANCE
@@ -1316,7 +1307,7 @@ DATA LOADONCALL NONSHARED MULTIPLE
 EXPORTS
 ---EOP---
 }
-elsif ($PLATFORM eq 'aix') {
+elsif ($ARGS{PLATFORM} eq 'aix') {
     my $OSVER = `uname -v`;
     chop $OSVER;
     my $OSREL = `uname -r`;
@@ -1327,9 +1318,9 @@ elsif ($PLATFORM eq 'aix') {
        print "#!\n";
     }
 }
-elsif ($PLATFORM eq 'netware') {
-       if ($FILETYPE eq 'def') {
-       print "LIBRARY perl515\n";
+elsif ($ARGS{PLATFORM} eq 'netware') {
+       if ($ARGS{FILETYPE} eq 'def') {
+       print "LIBRARY perl$Config{api_revision}$Config{api_version}\n";
        print "DESCRIPTION 'Perl interpreter for NetWare'\n";
        print "EXPORTS\n";
        }
@@ -1338,11 +1329,11 @@ elsif ($PLATFORM eq 'netware') {
 # Then the symbols
 
 foreach my $symbol (sort keys %export) {
-    if ($PLATFORM =~ /^win(?:32|ce)$/) {
-       $symbol = "_$symbol" if $CCTYPE eq 'BORLAND';
+    if ($ARGS{PLATFORM} =~ /^win(?:32|ce)$/) {
+       $symbol = "_$symbol" if $ARGS{CCTYPE} eq 'BORLAND';
        print "\t$symbol\n";
     }
-    elsif ($PLATFORM eq 'os2') {
+    elsif ($ARGS{PLATFORM} eq 'os2') {
        printf qq(    %-31s \@%s\n),
          qq("$symbol"), $ordinal{$symbol} || ++$sym_ord;
        printf qq(    %-31s \@%s\n),
@@ -1350,7 +1341,7 @@ foreach my $symbol (sort keys %export) {
          $ordinal{$exportperlmalloc{$symbol}} || ++$sym_ord
          if $exportperlmalloc and exists $exportperlmalloc{$symbol};
     }
-    elsif ($PLATFORM eq 'netware') {
+    elsif ($ARGS{PLATFORM} eq 'netware') {
        print "\t$symbol,\n";
     } else {
        print "$symbol\n";
@@ -1359,7 +1350,7 @@ foreach my $symbol (sort keys %export) {
 
 # Then platform specific footers.
 
-if ($PLATFORM eq 'os2') {
+if ($ARGS{PLATFORM} eq 'os2') {
     print <<EOP;
     dll_perlmain=main
     fill_extLibpath