FAQ
If I run this script on Win32

use Config;
use ExtUtils::Miniperl;
use ExtUtils::Embed;

open STDOUT, ">", "perlmain.c";
writemain;
close STDOUT;

sub mysystem {
warn "$_[0]\n\n";
system $_[0]
and die +(split " ", $_[0])[0] . " failed.\n";
}

my $ccopts = ccopts;
my $ldopts = ldopts(1);

mysystem "$Config{cc} -c -o perlmain.o $ccopts perlmain.c";
mysystem "$Config{ld} -o myperl.exe perlmain.o $ldopts";

I get the output (wrapped for mail)

gcc -c -o perlmain.o -s -O2 -DWIN32 -DHAVE_DES_FCRYPT
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fno-strict-aliasing
-DPERL_MSVCRT_READFIX -I"C:\strawberry\perl\lib\CORE" perlmain.c

g++ -o myperl.exe perlmain.o -s -L"C:\strawberry\perl\lib\CORE"
-L"C:\strawberry\c\lib" C:\strawberry\perl\lib\CORE\libperl510.a
C:\strawberry\c\lib\libmsvcrt.a C:\strawberry\c\lib\libmoldname.a
C:\strawberry\c\lib\libkernel32.a C:\strawberry\c\lib\libuser32.a
C:\strawberry\c\lib\libgdi32.a C:\strawberry\c\lib\libwinspool.a
C:\strawberry\c\lib\libcomdlg32.a C:\strawberry\c\lib\libadvapi32.a
C:\strawberry\c\lib\libshell32.a C:\strawberry\c\lib\libole32.a
C:\strawberry\c\lib\liboleaut32.a C:\strawberry\c\lib\libnetapi32.a
C:\strawberry\c\lib\libuuid.a C:\strawberry\c\lib\libws2_32.a
C:\strawberry\c\lib\libmpr.a C:\strawberry\c\lib\libwinmm.a
C:\strawberry\c\lib\libversion.a C:\strawberry\c\lib\libodbc32.a
C:\strawberry\c\lib\libodbccp32.a

perlmain.o:perlmain.c:(.text+0x1a): undefined reference to
`_imp__PL_use_safe_putenv'
perlmain.o:perlmain.c:(.text+0x3e): undefined reference to
`_imp__PL_do_undump'
collect2: ld returned 1 exit status
g++ failed.

This is with Strawberry 5.10.0, but I get the same result with a
MinGW-built blead. If I edit the generated perlmain.c to #include
perlapi.h after perl.h, the built exe appears to work perfectly, but
isn't EXTERN.h supposed to handle that?

Ben

Search Discussions

  • Steve Hay at May 6, 2009 at 12:13 pm

    Ben Morrow wrote:
    If I run this script on Win32

    use Config;
    use ExtUtils::Miniperl;
    use ExtUtils::Embed;

    open STDOUT, ">", "perlmain.c";
    writemain;
    close STDOUT;

    sub mysystem {
    warn "$_[0]\n\n";
    system $_[0]
    and die +(split " ", $_[0])[0] . " failed.\n";
    }

    my $ccopts = ccopts;
    my $ldopts = ldopts(1);

    mysystem "$Config{cc} -c -o perlmain.o $ccopts perlmain.c";
    mysystem "$Config{ld} -o myperl.exe perlmain.o $ldopts";

    I get the output (wrapped for mail) [...]
    perlmain.o:perlmain.c:(.text+0x1a): undefined reference to
    `_imp__PL_use_safe_putenv'
    perlmain.o:perlmain.c:(.text+0x3e): undefined reference to
    `_imp__PL_do_undump'
    collect2: ld returned 1 exit status
    g++ failed.

    This is with Strawberry 5.10.0, but I get the same result with a
    MinGW-built blead. If I edit the generated perlmain.c to #include
    perlapi.h after perl.h, the built exe appears to work perfectly, but
    isn't EXTERN.h supposed to handle that?
    ^^^^^^^^

    Do you mean XSUB.h there? That includes perlapi.h.

    Certainly adding XSUB.h after perl.h in miniperlmain.c fixes it, but it
    seems somehow wrong to add XSUB.h to the main for miniperl, given that
    the main distinguishing feature of miniperl is that it doesn't do
    extensions!

    So perhaps it would be better to change minimod.pl to insert XSUB.h in
    the appropriate place in the miniperlmain.c code that it copies to
    ExtUtils/Minimod.pm?
  • Ben Morrow at May 6, 2009 at 2:05 pm

    Quoth SteveHay@planit.com (Steve Hay):
    Ben Morrow wrote:
    If I run this script on Win32

    use Config;
    use ExtUtils::Miniperl;
    use ExtUtils::Embed;

    open STDOUT, ">", "perlmain.c";
    writemain;
    close STDOUT;

    sub mysystem {
    warn "$_[0]\n\n";
    system $_[0]
    and die +(split " ", $_[0])[0] . " failed.\n";
    }

    my $ccopts = ccopts;
    my $ldopts = ldopts(1);

    mysystem "$Config{cc} -c -o perlmain.o $ccopts perlmain.c";
    mysystem "$Config{ld} -o myperl.exe perlmain.o $ldopts";

    I get the output (wrapped for mail) [...]
    perlmain.o:perlmain.c:(.text+0x1a): undefined reference to
    `_imp__PL_use_safe_putenv'
    perlmain.o:perlmain.c:(.text+0x3e): undefined reference to
    `_imp__PL_do_undump'
    collect2: ld returned 1 exit status
    g++ failed.

    This is with Strawberry 5.10.0, but I get the same result with a
    MinGW-built blead. If I edit the generated perlmain.c to #include
    perlapi.h after perl.h, the built exe appears to work perfectly, but
    isn't EXTERN.h supposed to handle that?
    ^^^^^^^^

    Do you mean XSUB.h there? That includes perlapi.h.
    No, I meant EXTERN.h, which does a whole lot of

    #define EXT extern __declspec(dllimport)

    stuff, which I thought was meant to handle this. I admit I don't begin
    to understand all this: that is, I can follow most of what's happening,
    but I can't see the reasons behind it.
    Certainly adding XSUB.h after perl.h in miniperlmain.c fixes it, but it
    seems somehow wrong to add XSUB.h to the main for miniperl, given that
    the main distinguishing feature of miniperl is that it doesn't do
    extensions!

    So perhaps it would be better to change minimod.pl to insert XSUB.h in
    the appropriate place in the miniperlmain.c code that it copies to
    ExtUtils/Minimod.pm?
    Hmm. I don't know. It says in perlembed that EXTERN.h and perl.h are all
    you need to embed a perl interpreter, so it feels like that should be
    enough for perlmain.c. OTOH, the minimal interpreter in perlembed
    doesn't use those vars, so it doesn't need perlapi.h.

    How much of what perlmain.c does should any embedded interpreter be
    doing? Obviously the PL_do_undump bit is completely optional, but most
    of the rest looks important.

    Ben
  • Steve Hay at May 6, 2009 at 5:16 pm

    Ben Morrow wrote on 2009-05-06:
    Quoth SteveHay@planit.com (Steve Hay):
    Ben Morrow wrote:
    [...]
    perlmain.o:perlmain.c:(.text+0x1a): undefined reference to
    `_imp__PL_use_safe_putenv'
    perlmain.o:perlmain.c:(.text+0x3e): undefined reference to
    `_imp__PL_do_undump'
    collect2: ld returned 1 exit status
    g++ failed.
    This is with Strawberry 5.10.0, but I get the same result with a
    MinGW-built blead. If I edit the generated perlmain.c to #include
    perlapi.h after perl.h, the built exe appears to work perfectly, but
    isn't EXTERN.h supposed to handle that?
    ^^^^^^^^

    Do you mean XSUB.h there? That includes perlapi.h.
    No, I meant EXTERN.h, which does a whole lot of

    #define EXT extern __declspec(dllimport)

    stuff, which I thought was meant to handle this. I admit I don't begin
    to understand all this: that is, I can follow most of what's
    happening,
    but I can't see the reasons behind it.
    I don't think that's relevant here. The lines that fix it are:

    #undef PL_do_undump
    #define PL_do_undump (*Perl_Gdo_undump_ptr(NULL))
    #undef PL_use_safe_putenv
    #define PL_use_safe_putenv (*Perl_Guse_safe_putenv_ptr(NULL))

    in perlapi.h, which is included by XSUB.h.

    (If you look in your perldll.def, you'll see that Perl_Gdo_undump_ptr
    and Perl_Guse_safe_putenv_ptr are exported, so it's just the #defines to
    use them that are missing.)

    I'll look at making the change to minimod.pl soon unless someone comes
    up with a better idea.
  • Ben Morrow at May 6, 2009 at 9:38 pm

    Quoth SteveHay@planit.com (Steve Hay):
    Ben Morrow wrote on 2009-05-06:
    Quoth SteveHay@planit.com (Steve Hay):
    Do you mean XSUB.h there? That includes perlapi.h.
    No, I meant EXTERN.h, which does a whole lot of

    #define EXT extern __declspec(dllimport)

    stuff, which I thought was meant to handle this. I admit I don't begin
    to understand all this: that is, I can follow most of what's
    happening,
    but I can't see the reasons behind it.
    I don't think that's relevant here. The lines that fix it are:

    #undef PL_do_undump
    #define PL_do_undump (*Perl_Gdo_undump_ptr(NULL))
    #undef PL_use_safe_putenv
    #define PL_use_safe_putenv (*Perl_Guse_safe_putenv_ptr(NULL))

    in perlapi.h, which is included by XSUB.h.

    (If you look in your perldll.def, you'll see that Perl_Gdo_undump_ptr
    and Perl_Guse_safe_putenv_ptr are exported, so it's just the #defines to
    use them that are missing.)

    I'll look at making the change to minimod.pl soon unless someone comes
    up with a better idea.
    OK, this patch seems to do it.

    Ben
  • Steve Hay at May 7, 2009 at 8:27 am

    Ben Morrow wrote on 2009-05-06:
    Quoth SteveHay@planit.com (Steve Hay):
    Ben Morrow wrote on 2009-05-06:
    Quoth SteveHay@planit.com (Steve Hay):
    Do you mean XSUB.h there? That includes perlapi.h.
    No, I meant EXTERN.h, which does a whole lot of

    #define EXT extern __declspec(dllimport)
    stuff, which I thought was meant to handle this. I admit I don't
    begin to understand all this: that is, I can follow most of what's
    happening, but I can't see the reasons behind it.
    I don't think that's relevant here. The lines that fix it are:

    #undef PL_do_undump
    #define PL_do_undump (*Perl_Gdo_undump_ptr(NULL))
    #undef PL_use_safe_putenv
    #define PL_use_safe_putenv (*Perl_Guse_safe_putenv_ptr(NULL))

    in perlapi.h, which is included by XSUB.h.

    (If you look in your perldll.def, you'll see that Perl_Gdo_undump_ptr
    and Perl_Guse_safe_putenv_ptr are exported, so it's just the #defines
    to use them that are missing.)

    I'll look at making the change to minimod.pl soon unless someone
    comes
    up with a better idea.
    OK, this patch seems to do it.
    Thanks, applied here:
    http://perl5.git.perl.org/perl.git/commit/3ecadf9
  • Reini Urban at May 14, 2009 at 10:55 am

    2009/5/6 Ben Morrow <ben@morrow.me.uk>:
    If I run this script on Win32
    For cygwin I had to make a similar Win32CORE.o excemption as for Dynaloader,
    hence your ExtUtils::Miniperl usage in ExtUtils::PerlToExe needs the
    attached patch.

    Win32CORE is a static_ext, but Miniperl is not supposed to link against
    those extensions, so the usage to add @static_ext together with
    ExtUtils::Embed::ldopts (without Win32CORE.o) requires this quirks.

    diff -u Makefile.PL.orig Makefile.PL
    --- Makefile.PL.orig 2009-05-13 23:01:52.593750000 +0200
    +++ Makefile.PL 2009-05-14 08:11:01.453125000 +0200
    @@ -39,7 +39,11 @@
    {
    open my $MAIN, ">", \$perlmain;
    my $OLD = select $MAIN;
    - writemain ExtUtils::Embed::static_ext;
    + my @static_ext = ExtUtils::Embed::static_ext;
    + if ($^O eq 'cygwin') { # not linked into cygperl5_x.dll
    + @static_ext = grep !/Win32CORE/, @static_ext;
    + }
    + writemain @static_ext;
    select $OLD;
    }
  • Ben Morrow at May 17, 2009 at 9:15 am

    Quoth rurban@x-ray.at (Reini Urban):

    For cygwin I had to make a similar Win32CORE.o excemption as for Dynaloader,
    hence your ExtUtils::Miniperl usage in ExtUtils::PerlToExe needs the
    attached patch.

    Win32CORE is a static_ext, but Miniperl is not supposed to link against
    those extensions, so the usage to add @static_ext together with
    ExtUtils::Embed::ldopts (without Win32CORE.o) requires this quirks. <snip>
    - writemain ExtUtils::Embed::static_ext;
    + my @static_ext = ExtUtils::Embed::static_ext;
    + if ($^O eq 'cygwin') { # not linked into cygperl5_x.dll
    + @static_ext = grep !/Win32CORE/, @static_ext;
    + }
    + writemain @static_ext;
    Thank you for taking the trouble to look at this.

    I don't believe this fix does anything. The only effect of passing
    Win32CORE to writemain is to cause it to create a newXS entry for
    Win32CORE::bootstrap; since this is a dummy function that never gets
    called it doesn't make any difference whether it's installed in the
    symbol table or not.

    There is a problem here, however, which doesn't relate just to Win32CORE
    on Cygwin but to all extensions in static_ext when perl is built with
    -Duseshrplib. First, an ordinary Unix system:

    freebsd% ./Configure -Dprefix=$prefix \
    -Dstatic_ext="File/Glob List/Util" \
    -Duseshrplib -Dusedevel -des && make && make install
    ...

    freebsd% nm perl | grep boot_
    U boot_DynaLoader
    0804a730 T boot_File__Glob
    0804c4b0 T boot_List__Util

    freebsd% nm libperl.so | grep boot_
    000edc70 T Perl_boot_core_PerlIO
    000e9ec0 T Perl_boot_core_UNIVERSAL
    0007f9d0 T Perl_boot_core_mro
    001010f0 T boot_DynaLoader

    So all the static extensions are linked into perl, except for DynaLoader
    which is linked into libperl.so. If we run ExtUtils::Embed from inside
    the build tree it includes all the necessary .as in the link line (I've
    tidied up the output a little):

    freebsd% LD_LIBRARY_PATH=. ./perl -Ilib -MExtUtils::Embed \
    -eldopts -- -std
    -Wl,-R$prefix/lib/5.11.0/i386-freebsd/CORE -Wl,-E
    -fstack-protector -L/usr/local/lib
    lib/auto/File/Glob/Glob.a lib/auto/List/Util/Util.a
    -L$prefix/lib/5.11.0/i386-freebsd/CORE
    -lperl -lm -lcrypt -lutil -lc

    but if we run the installed version it doesn't:

    freebsd% $prefix/bin/perl5.11.0 -MExtUtils::Embed -eldopts -- -std
    -Wl,-R$prefix/lib/5.11.0/i386-freebsd/CORE -Wl,-E
    -fstack-protector -L/usr/local/lib
    -L$prefix/lib/5.11.0/i386-freebsd/CORE
    -lperl -lm -lcrypt -lutil -lc

    It turns out this is because the .as haven't been installed, so it's
    actually impossible to correctly link an embedded interpreter.

    Under Cygwin the situation is the same except it's more immediately
    noticable because Win32CORE is always linked statically on Cygwin. The
    Cygwin-provided 5.10.0 tries to work around this by linking Win32CORE
    into *both* the .exe and the .dll, but I believe this is a bad idea
    because

    - it special-cases Win32CORE, when this is a generic problem;

    - cygwin.c:init_os_extras specifically assumes that Win32CORE will
    be linked into the main executable (it calls dlopen(NULL)) so
    embedded interpreters still won't end up calling init_Win32CORE
    unless they do so manually.

    (I think this dlopen(NULL) is actually a bug in itself--what about a dll
    that embeds perl?--but I can't immediately see any way around it.)

    Win32 is different in that it doesn't use the real perlmain at all but
    instead has a RunPerl entry point in the dll. All the static extensions
    get linked into the dll, and none of the .as get installed, so here
    things actually work as they should. (ExtUtils::Embed gives the wrong
    output from inside the build tree, but that doesn't matter.)

    AFAICS there are two possible solutions here: either install the .as, or
    link all the static extensions into libperl.so. Configure could also
    ask, though I can't see any good reason for someone not choosing the
    default. In any case I think ExtUtils::Embed ought to shriek if it is
    asked to link an extension it can't find; this probably means adding a
    $Config{libperl_ext} to record which extensions we have linked into our
    libperl (which will always be at least DynaLoader on useshrplib builds).

    I'm happy to try and do up a patch for this (whatever solution is deemed
    best), but I don't really know my way around Makefile.SH &c. so if
    someone who does can just say 'oh yes, it's right here' that would be a
    lot easier... :)

    Ben

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupperl5-porters @
categoriesperl
postedMay 5, '09 at 11:22p
activeMay 17, '09 at 9:15a
posts8
users3
websiteperl.org

People

Translate

site design / logo © 2021 Grokbase