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
From:
Steve Hay
Date:
June 7, 2013 00:17
Subject:
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:
CADED=K7vWQOB9jdhFyrCY7Sr-HChfPkLxWs+PVUR1DhjXSDECQ@mail.gmail.com
On 6 June 2013 19:10, Jan Dubois <jand@activestate.com> wrote:
> On Thu, Jun 6, 2013 at 10:26 AM, Steve Hay <Steve.Hay@verosoftware.com> 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. */
> #ifndef PERL_IS_MINIPERL
>     void (*pfn_init)(pTHX);
>     pfn_init = (void
> (*)(pTHX))GetProcAddress((HMODULE)w32_perldll_handle,
> "init_Win32CORE");
>     aTHXa(PERL_GET_THX);
>     if (pfn_init)
>         pfn_init(aTHX);
> #else
>
> 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.
>

Thanks for waking me up to this. I've just pushed some changes
containing most of what I've done so far since it does fix the
original problem here of not being able to do a static build with
MinGW at all.

The main problem remaining is that if I include Win32 in the static
build then the pre-defined Win32 functions are not getting their
implementations loaded on-demand, but since Win32 is currently
excluded from the full static build anyway because of some other
perceived problem (which I'm either missing or has since gone away)
there was no reason to hold off what I've done so far.

I would still like to get Win32 working, though, so I've tried your
above suggestion with the attached patch (which also incorpoates your
other suggestion of removing DEFAULT_BINMODE), but it still gives me
the same error.

A simple "perl-static.exe -e "Win32::CopyFile()"" normally gives the
expected "usage: ..." error, but instead still gives me an error about
Win32::CopyFile being undefined. It works if I add -MWin32 to the
command-line, though, so it is indeed this on-demand loading which is
broken in the static build.

I made a debug build of it and stepped into Perl_init_os_extras. The
'module' variable is set to something sensible, but 'pfn_init' comes
back NULL. It's unusual to call GetProcAddress on an .exe. I believe
it should work, but I think the function needs to be exported from the
.exe? It currently isn't (only a few PerlIO_* functions,
Perl_win32_init/term, RunPerl and numerous win32_* functions are,
according to dumpbin /exports), so I'll have to look at that; not sure
where the best place to arrange for it is at the moment.

(I don't think my change in create_perllibst_h.pl was necessary, though.)


> 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.
>

I will look into that too. There is one other thing in DllMain()'s
DLL_PROCESS_ATTACH case which is missing from Perl_init_os_extras():

#ifndef UNDER_CE
    DisableThreadLibraryCalls((HMODULE)hModule);
#endif

Is that relevant at all?


>> 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.
>

I hadn't considered that, but you're quite right: all the Encode
sub-modules are missing from the list of static extensions which
perllib.c gets references to.

I will look into fixing that too, but again it isn't currently a
problem because Encode is also excluded from the static extension list
in an ALL_STATIC build.

Searching for all DLLs in a normal installation shows that it is only
Encode which has this problem.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About