diff options
author | Nicholas Clark <nick@ccl4.org> | 2013-07-05 23:16:12 +0200 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2013-07-07 12:52:36 +0200 |
commit | c8935f6cd34349a50bf080be1bb4c46f2a00adfb (patch) | |
tree | f54aad414b4e90bd757d1c9fc1a107d761f4cf85 | |
parent | 7b4d95f74b61267ca3d460b061b824f1374b2672 (diff) | |
download | perl-c8935f6cd34349a50bf080be1bb4c46f2a00adfb.tar.gz |
Invert the build logic for miniperlmain.c and ExtUtils::Miniperl
Now ExtUtils::Miniperl has the master version of {mini,}perlmain.c and is
checked into the repository. miniperlmain.c is now generated by a script
in regen/ which uses ExtUtils::Miniperl.
Tweak ExtUtils::Miniperl::writemain() to take an optional first argument,
a reference to a file handle. This permits the regen script to use the
regen_lib.pl functions for file opening/closing/renaming and TAP generation.
For now check in ExtUtils::Miniperl minimally modified from the version
generated by the former minimod.pl. The next commit will tidy it up.
-rw-r--r-- | MANIFEST | 4 | ||||
-rw-r--r-- | ext/ExtUtils-Miniperl/Makefile.PL | 40 | ||||
-rw-r--r-- | ext/ExtUtils-Miniperl/Miniperl_pm.PL | 147 | ||||
-rw-r--r-- | ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm | 285 | ||||
-rw-r--r-- | miniperlmain.c | 4 | ||||
-rw-r--r-- | regen/miniperlmain.pl | 15 | ||||
-rw-r--r-- | t/porting/regen.t | 3 |
7 files changed, 306 insertions, 192 deletions
@@ -3567,8 +3567,7 @@ ext/Errno/ChangeLog Errno changes ext/Errno/Errno_pm.PL Errno perl module create script ext/Errno/Makefile.PL Errno extension makefile writer ext/Errno/t/Errno.t See if Errno works -ext/ExtUtils-Miniperl/Makefile.PL Runs Miniperl_pm.PL -ext/ExtUtils-Miniperl/Miniperl_pm.PL Writes ext/ExtUtils-Miniperl/Miniperl.pm +ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm Writes {mini,}perlmain.c ext/Fcntl/Fcntl.pm Fcntl extension Perl module ext/Fcntl/Fcntl.xs Fcntl extension external subroutines ext/Fcntl/Makefile.PL Fcntl extension makefile writer @@ -4757,6 +4756,7 @@ regen/feature.pl Generates feature.pm regen/genpacksizetables.pl Generate the size tables for pack/unpack regen/keywords.pl Program to write keywords.h regen/mg_vtable.pl generate mg_vtable.h +regen/miniperlmain.pl generate miniperlmain.c regen/mk_invlists.pl Generates charclass_invlists.h regen/mk_PL_charclass.pl Populate the PL_charclass table regen/opcode.pl Opcode header generator diff --git a/ext/ExtUtils-Miniperl/Makefile.PL b/ext/ExtUtils-Miniperl/Makefile.PL deleted file mode 100644 index 16c3ecb42e..0000000000 --- a/ext/ExtUtils-Miniperl/Makefile.PL +++ /dev/null @@ -1,40 +0,0 @@ -#!perl -w - -# Blatantly copied from ext/Pod-Functions/Makefile.PL -# If we think we want a third copy, then it's time to find a better way to do -# this. (Note, we have no ABSTRACT_FROM here) -# But for now, this replaces a bunch of platform specific special case code -# in the Makefiles for *nix, Win32 and VMS with one unified implementation. -# And in Perl, rather than 3+ different languages. - -use strict; -use ExtUtils::MakeMaker; -use File::Spec::Functions; - -WriteMakefile(NAME => 'ExtUtils::Miniperl', - VERSION_FROM => 'Miniperl_pm.PL', - LICENSE => 'perl', - PREREQ_PM => {}, - AUTHOR => 'Perl 5 Porters <perlbug@perl.org>', - INSTALLDIRS => 'perl', - PL_FILES => {}, # Stop EU::MM defaulting this to run our PL - PM => {'Miniperl.pm' => '$(INST_LIBDIR)/Miniperl.pm'}, - clean => {FILES => 'Miniperl.pm'}, - ); - -# There doesn't seem to be any way to get ExtUtils::MakeMaker to add a -# dependency on another file (or target), and as it's using :: rules, not : -# rules, then we can't simply add a one line dependency. So we need to provide -# the entire thing. Fortunately, the same code in MM_Unix.pm is actually used -# for all platforms, so this code below should also be portable: - -sub MY::postamble { - my $main = catfile(updir, updir, 'miniperlmain.c'); - return <<"EOT"; -all :: Miniperl.pm - \$(NOECHO) \$(NOOP) - -Miniperl.pm :: Miniperl_pm.PL $main - \$(PERLRUN) Miniperl_pm.PL $main -EOT -} diff --git a/ext/ExtUtils-Miniperl/Miniperl_pm.PL b/ext/ExtUtils-Miniperl/Miniperl_pm.PL deleted file mode 100644 index a7de280dc0..0000000000 --- a/ext/ExtUtils-Miniperl/Miniperl_pm.PL +++ /dev/null @@ -1,147 +0,0 @@ -#./miniperl -w -# minimod.pl writes the contents of miniperlmain.c into the module -# ExtUtils::Miniperl for later perusal (when the perl source is -# deleted) -# -# It also writes the subroutine writemain(), which takes as its -# arguments module names that shall be statically linked into perl. -# -# Authors: Andreas Koenig <k@franz.ww.TU-Berlin.DE>, Tim Bunce -# <Tim.Bunce@ig.co.uk> -# -# Version 1.0, Feb 2nd 1995 by Andreas Koenig - -use strict; - -open STDOUT, '>Miniperl.pm' - or die "Can't open Miniperl.pm: $!"; - -print <<'END'; -# This File keeps the contents of miniperlmain.c. -# -# It was generated automatically by minimod.PL from the contents -# of miniperlmain.c. Don't edit this file! -# -# ANY CHANGES MADE HERE WILL BE LOST! -# - - -package ExtUtils::Miniperl; -require Exporter; -@ISA = qw(Exporter); -@EXPORT = qw(&writemain); - -$head= <<'EOF!HEAD'; -END - -open MINI, shift; -while (<MINI>) { - last if /Do not delete this line--writemain depends on it/; - print; - /#include "perl.h"/ and print qq/#include "XSUB.h"\n/; -} - -print <<'END'; -EOF!HEAD -$tail=<<'EOF!TAIL'; -END - -while (<MINI>) { - print unless /dXSUB_SYS/; -} -close MINI; - -print <<'END'; -EOF!TAIL - -sub writemain{ - my(@exts) = @_; - - my($pname); - my($dl) = canon('/','DynaLoader'); - print $head; - - foreach $_ (@exts){ - my($pname) = canon('/', $_); - my($mname, $cname); - ($mname = $pname) =~ s!/!::!g; - ($cname = $pname) =~ s!/!__!g; - print "EXTERN_C void boot_${cname} (pTHX_ CV* cv);\n"; - } - - my ($tail1,$tail2,$tail3) = ( $tail =~ /\A(.*{\s*\n)(.*\n)(\s*\}.*)\Z/s ); - - print $tail1; - print "\tstatic const char file[] = __FILE__;\n"; - print "\tdXSUB_SYS;\n" if $] > 5.002; - print $tail2; - - foreach $_ (@exts){ - my($pname) = canon('/', $_); - my($mname, $cname, $ccode); - ($mname = $pname) =~ s!/!::!g; - ($cname = $pname) =~ s!/!__!g; - print "\t{\n"; - if ($pname eq $dl){ - # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'! - # boot_DynaLoader is called directly in DynaLoader.pm - $ccode = "\t/* DynaLoader is a special case */\n -\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n"; - print $ccode unless $SEEN{$ccode}++; - } else { - $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n"; - print $ccode unless $SEEN{$ccode}++; - } - print "\t}\n"; - } - print $tail3; -} - -sub canon{ - my($as, @ext) = @_; - foreach(@ext){ - # might be X::Y or lib/auto/X/Y/Y.a - next if s!::!/!g; - s:^(lib|ext)/(auto/)?::; - s:/\w+\.\w+$::; - } - grep(s:/:$as:, @ext) if ($as ne '/'); - @ext; -} - -1; -__END__ - -=head1 NAME - -ExtUtils::Miniperl, writemain - write the C code for perlmain.c - -=head1 SYNOPSIS - -C<use ExtUtils::Miniperl;> - -C<writemain(@directories);> - -=head1 DESCRIPTION - -This whole module is written when perl itself is built from a script -called minimod.PL. In case you want to patch it, please patch -minimod.PL in the perl distribution instead. - -writemain() takes an argument list of directories containing archive -libraries that relate to perl modules and should be linked into a new -perl binary. It writes to STDOUT a corresponding perlmain.c file that -is a plain C file containing all the bootstrap code to make the -modules associated with the libraries available from within perl. - -The typical usage is from within a Makefile generated by -ExtUtils::MakeMaker. So under normal circumstances you won't have to -deal with this module directly. - -=head1 SEE ALSO - -L<ExtUtils::MakeMaker> - -=cut - -END diff --git a/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm b/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm new file mode 100644 index 0000000000..3a43094e2c --- /dev/null +++ b/ext/ExtUtils-Miniperl/lib/ExtUtils/Miniperl.pm @@ -0,0 +1,285 @@ +# This File keeps the contents of miniperlmain.c. +# +# It was generated automatically by minimod.PL from the contents +# of miniperlmain.c. Don't edit this file! +# +# ANY CHANGES MADE HERE WILL BE LOST! +# + + +package ExtUtils::Miniperl; +require Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(&writemain); + +$head= <<'EOF!HEAD'; +/* miniperlmain.c + * + * Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2003, + * 2004, 2005, 2006, 2007, by Larry Wall and others + * + * You may distribute under the terms of either the GNU General Public + * License or the Artistic License, as specified in the README file. + * + */ + +/* + * The Road goes ever on and on + * Down from the door where it began. + * + * [Bilbo on p.35 of _The Lord of the Rings_, I/i: "A Long-Expected Party"] + * [Frodo on p.73 of _The Lord of the Rings_, I/iii: "Three Is Company"] + */ + +/* This file contains the main() function for the perl interpreter. + * Note that miniperlmain.c contains main() for the 'miniperl' binary, + * while perlmain.c contains main() for the 'perl' binary. + * + * Miniperl is like perl except that it does not support dynamic loading, + * and in fact is used to build the dynamic modules needed for the 'real' + * perl executable. + */ + +#ifdef OEMVS +#ifdef MYMALLOC +/* sbrk is limited to first heap segment so make it big */ +#pragma runopts(HEAP(8M,500K,ANYWHERE,KEEP,8K,4K) STACK(,,ANY,) ALL31(ON)) +#else +#pragma runopts(HEAP(2M,500K,ANYWHERE,KEEP,8K,4K) STACK(,,ANY,) ALL31(ON)) +#endif +#endif + + +#include "EXTERN.h" +#define PERL_IN_MINIPERLMAIN_C +#include "perl.h" +#include "XSUB.h" + +static void xs_init (pTHX); +static PerlInterpreter *my_perl; + +#if defined(PERL_GLOBAL_STRUCT_PRIVATE) +/* The static struct perl_vars* may seem counterproductive since the + * whole idea PERL_GLOBAL_STRUCT_PRIVATE was to avoid statics, but note + * that this static is not in the shared perl library, the globals PL_Vars + * and PL_VarsPtr will stay away. */ +static struct perl_vars* my_plvarsp; +struct perl_vars* Perl_GetVarsPrivate(void) { return my_plvarsp; } +#endif + +#ifdef NO_ENV_ARRAY_IN_MAIN +extern char **environ; +int +main(int argc, char **argv) +#else +int +main(int argc, char **argv, char **env) +#endif +{ + dVAR; + int exitstatus, i; +#ifdef PERL_GLOBAL_STRUCT + struct perl_vars *plvarsp = init_global_struct(); +# ifdef PERL_GLOBAL_STRUCT_PRIVATE + my_vars = my_plvarsp = plvarsp; +# endif +#endif /* PERL_GLOBAL_STRUCT */ +#ifndef NO_ENV_ARRAY_IN_MAIN + PERL_UNUSED_ARG(env); +#endif +#ifndef PERL_USE_SAFE_PUTENV + PL_use_safe_putenv = FALSE; +#endif /* PERL_USE_SAFE_PUTENV */ + + /* if user wants control of gprof profiling off by default */ + /* noop unless Configure is given -Accflags=-DPERL_GPROF_CONTROL */ + PERL_GPROF_MONCONTROL(0); + +#ifdef NO_ENV_ARRAY_IN_MAIN + PERL_SYS_INIT3(&argc,&argv,&environ); +#else + PERL_SYS_INIT3(&argc,&argv,&env); +#endif + +#if defined(USE_ITHREADS) + /* XXX Ideally, this should really be happening in perl_alloc() or + * perl_construct() to keep libperl.a transparently fork()-safe. + * It is currently done here only because Apache/mod_perl have + * problems due to lack of a call to cancel pthread_atfork() + * handlers when shared objects that contain the handlers may + * be dlclose()d. This forces applications that embed perl to + * call PTHREAD_ATFORK() explicitly, but if and only if it hasn't + * been called at least once before in the current process. + * --GSAR 2001-07-20 */ + PTHREAD_ATFORK(Perl_atfork_lock, + Perl_atfork_unlock, + Perl_atfork_unlock); +#endif + + if (!PL_do_undump) { + my_perl = perl_alloc(); + if (!my_perl) + exit(1); + perl_construct(my_perl); + PL_perl_destruct_level = 0; + } + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NULL); + if (!exitstatus) + perl_run(my_perl); + +#ifndef PERL_MICRO + /* Unregister our signal handler before destroying my_perl */ + for (i = 1; PL_sig_name[i]; i++) { + if (rsignal_state(PL_sig_num[i]) == (Sighandler_t) PL_csighandlerp) { + rsignal(PL_sig_num[i], (Sighandler_t) SIG_DFL); + } + } +#endif + + exitstatus = perl_destruct(my_perl); + + perl_free(my_perl); + +#if defined(USE_ENVIRON_ARRAY) && defined(PERL_TRACK_MEMPOOL) && !defined(NO_ENV_ARRAY_IN_MAIN) + /* + * The old environment may have been freed by perl_free() + * when PERL_TRACK_MEMPOOL is defined, but without having + * been restored by perl_destruct() before (this is only + * done if destruct_level > 0). + * + * It is important to have a valid environment for atexit() + * routines that are eventually called. + */ + environ = env; +#endif + + PERL_SYS_TERM(); + +#ifdef PERL_GLOBAL_STRUCT + free_global_struct(plvarsp); +#endif /* PERL_GLOBAL_STRUCT */ + + exit(exitstatus); + return exitstatus; +} + +/* Register any extra external extensions */ + +EOF!HEAD +$tail=<<'EOF!TAIL'; + +static void +xs_init(pTHX) +{ + PERL_UNUSED_CONTEXT; +} + +/* + * Local variables: + * c-indentation-style: bsd + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * + * ex: set ts=8 sts=4 sw=4 et: + */ +EOF!TAIL + +sub writemain{ + my $old_fh; + if (ref $_[0]) { + $old_fh = select shift; + } + my(@exts) = @_; + + my($pname); + my($dl) = canon('/','DynaLoader'); + print $head; + + foreach $_ (@exts){ + my($pname) = canon('/', $_); + my($mname, $cname); + ($mname = $pname) =~ s!/!::!g; + ($cname = $pname) =~ s!/!__!g; + print "EXTERN_C void boot_${cname} (pTHX_ CV* cv);\n"; + } + + my ($tail1,$tail2,$tail3) = ( $tail =~ /\A(.*{\s*\n)(.*\n)(\s*\}.*)\Z/s ); + + print $tail1; + print "\tstatic const char file[] = __FILE__;\n" + if @exts; + print "\tdXSUB_SYS;\n" if $] > 5.002; + print $tail2; + + foreach $_ (@exts){ + my($pname) = canon('/', $_); + my($mname, $cname, $ccode); + ($mname = $pname) =~ s!/!::!g; + ($cname = $pname) =~ s!/!__!g; + print "\t{\n"; + if ($pname eq $dl){ + # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'! + # boot_DynaLoader is called directly in DynaLoader.pm + $ccode = "\t/* DynaLoader is a special case */\n +\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n"; + print $ccode unless $SEEN{$ccode}++; + } else { + $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n"; + print $ccode unless $SEEN{$ccode}++; + } + print "\t}\n"; + } + print $tail3; + select $old_fh + if $fh; +} + +sub canon{ + my($as, @ext) = @_; + foreach(@ext){ + # might be X::Y or lib/auto/X/Y/Y.a + next if s!::!/!g; + s:^(lib|ext)/(auto/)?::; + s:/\w+\.\w+$::; + } + grep(s:/:$as:, @ext) if ($as ne '/'); + @ext; +} + +1; +__END__ + +=head1 NAME + +ExtUtils::Miniperl, writemain - write the C code for perlmain.c + +=head1 SYNOPSIS + +C<use ExtUtils::Miniperl;> + +C<writemain(@directories);> + +=head1 DESCRIPTION + +This whole module is written when perl itself is built from a script +called minimod.PL. In case you want to patch it, please patch +minimod.PL in the perl distribution instead. + +writemain() takes an argument list of directories containing archive +libraries that relate to perl modules and should be linked into a new +perl binary. It writes to STDOUT a corresponding perlmain.c file that +is a plain C file containing all the bootstrap code to make the +modules associated with the libraries available from within perl. + +The typical usage is from within a Makefile generated by +ExtUtils::MakeMaker. So under normal circumstances you won't have to +deal with this module directly. + +=head1 SEE ALSO + +L<ExtUtils::MakeMaker> + +=cut + diff --git a/miniperlmain.c b/miniperlmain.c index 61358f7848..3a06f7274b 100644 --- a/miniperlmain.c +++ b/miniperlmain.c @@ -38,6 +38,7 @@ #include "EXTERN.h" #define PERL_IN_MINIPERLMAIN_C #include "perl.h" +#include "XSUB.h" static void xs_init (pTHX); static PerlInterpreter *my_perl; @@ -150,13 +151,12 @@ main(int argc, char **argv, char **env) /* Register any extra external extensions */ -/* Do not delete this line--writemain depends on it */ static void xs_init(pTHX) { + dXSUB_SYS; PERL_UNUSED_CONTEXT; - dXSUB_SYS; } /* diff --git a/regen/miniperlmain.pl b/regen/miniperlmain.pl new file mode 100644 index 0000000000..205c5839ec --- /dev/null +++ b/regen/miniperlmain.pl @@ -0,0 +1,15 @@ +#!/usr/bin/perl + +use strict; + +BEGIN { + # Get function prototypes + require 'regen/regen_lib.pl'; + unshift @INC, 'ext/ExtUtils-Miniperl/lib'; +} + +use ExtUtils::Miniperl; + +my $fh = open_new('miniperlmain.c'); +writemain($fh); +close_and_rename($fh); diff --git a/t/porting/regen.t b/t/porting/regen.t index 194f80e072..78fd64fa18 100644 --- a/t/porting/regen.t +++ b/t/porting/regen.t @@ -19,7 +19,8 @@ if ( $^O eq "VMS" ) { my $in_regen_pl = 24; # I can't see a clean way to calculate this automatically. my @files = qw(perly.act perly.h perly.tab keywords.c keywords.h uconfig.h); my @progs = qw(regen/regcharclass.pl regen/mk_PL_charclass.pl - regen/unicode_constants.pl regen/genpacksizetables.pl); + regen/unicode_constants.pl regen/genpacksizetables.pl + regen/miniperlmain.pl); plan (tests => $in_regen_pl + @files + @progs + 2); |