develooper Front page | perl.perl5.porters | Postings from June 2013

Re: dmake can't find config.h, and collector throws error when tryingto compile perl-static.exe (perl-5.18.0 / mingw / 32b)

Thread Previous | Thread Next
Jan Dubois
June 6, 2013 18:10
Re: dmake can't find config.h, and collector throws error when tryingto compile perl-static.exe (perl-5.18.0 / mingw / 32b)
Message ID:
On Thu, Jun 6, 2013 at 10:26 AM, Steve Hay <> wrote:
> Ok, so that's actually a perl error about a perl function called
> CopyFile(), and I shouldn't have gone off thinking that a C function
> missing from the executable was the problem, but I'm still currently at
> a loss to see why it isn't working. (It works fine if I use the normal
> perl.exe and perl519.dll.)
> Having said that, it seems to be something specific to the module Win32.
> Randomly trying a few other XS things (Cwd, Sys::Hostname, Digest::MD5,
> Encode) they appear to working fine.
> What is special about Win32 that it doesn't work?

Win32 is "special" because many of it's Perl level functions are
pre-defined (even without a "use Win32" statement), while the
implementation is in a dynamically linked module. This is done via the
statically linked Win32CORE wrapper that will load Win32 on demand.

The problem here is that Win32CORE is not included in miniperl, so the
initialization code has to be called dynamically:

In Perl_init_os_extras in win32/win32.c:

    /* Initialize Win32CORE if it has been statically linked. */
    void (*pfn_init)(pTHX);
    pfn_init = (void
    if (pfn_init)

The w32_perldll_handle is intialized during DLL_PROCESS_ATTACH in the
DllMain() function in win32/perllib.c, which will not be called when
perllib.c is part of an .exe file and not in a .dll.

So you may want to modify Perl_init_os_extras to something like this:

    void (*pfn_init)(pTHX);
    HMODULE module = (HMODULE)((w32_perldll_handle == INVALID_HANDLE_VALUE)
                                ? GetModuleHandle(NULL)
                                : w32_perldll_handle);
    pfn_init = (void (*)(pTHX))GetProcAddress(module, "init_Win32CORE");

This should be safe even for miniperl, because pfn_init() is only
called when it isn't NULL.

I notice that DllMain also calls set_w32_module_name(), but I think
that may be redundant, because it is called before w32_module_name is
used anyways.  The only reason I can think of calling it during
DllMain would be if perl.exe called set_w32_module_name() before the
DLL was loaded, in which case w32_module_name would initially be set
to the name of the EXE file, and once the DLL is loaded, it would be
reset to the DLL name.

In either case, there should be no need to call set_w32_module_name()
from Perl_init_os_extras.

> It's also still a puzzle to me why the perl-static.exe is only 2MB if it
> contains everything necessary from perl519s.lib, which is 20MB.

I have no idea... However, 20MB seems rather large to me, so maybe a
lot of this is debug information, symbol tables etc.

Also, are you sure you are referencing the boot_* symbols of all the
submodules as well.  E.g. referencing boot_Encode will not pull in the
Encode::CN module, which has it's own XS code.  So you may need to
reference boot_Encode_CN (and JP, KR, TW), which together are about
3MB.  There may be other modules which load submodules dynamically, so
run a `find . -name *.dll` on a regular Perl on Win32 install and
double-check that you have a boot_* reference for all of them.



Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About