New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[PATCH] fix win32 with Ming.org GCC 3.4.5 build #16498
Comments
From @bulk88Created by @bulk88See attached patch. This is intended for 5.28. Maybe backport too. Perl Info
|
From @bulk880001-fix-win32-with-Ming.org-GCC-3.4.5-build.patchFrom d29cee8acac409d714598b1e81c3494b22a16e30 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Fri, 6 Apr 2018 18:41:22 -0400
Subject: [PATCH] fix win32 with Ming.org GCC 3.4.5 build
dlltool 2.20.51.20100123 from Strawberry 5.12 and
dlltool 2.17.50 20060824 from Strawberry 5.8.9 were making a libperl527.a
that caused perl.exe and all XS DLLs to import "perl527.exp.dll" while
the disk file is called perl527.dll.
This bug was eventually fixed, since in my testing dlltool 2.25 no date
code, Copyright 2014 from Strawberry 5.22.1 doesn't have this problem. I
suspect the bug was fixed in binutils commit 04276a0cf5
"2010-12-01 Kai Tietz <kai.tietz@onevision.com>"
https://sourceware.org/bugzilla/show_bug.cgi?id=11065
in version "AM_INIT_AUTOMAKE(bfd, 2.21.51)" or 1 ver bump higher. Just
always pass an explicit DLL name to dlltool instead of any kind of
dlltool version checking at build time and then optional arg.
The breakage for Mingw.org 3.4.5 was introduced in
commit bf543eaf90d "add parallelness to win32/GNUmakefile" where I added
parallelness by making the import lib .a file from just perldll.def,
rather than the import lib being a build product coming out of g++
linking perl527.dll. The old serial build recipie passed --dllname
to dlltool, my newer code didn't.
Passing $(PERLDLL) to dlltool's -D causes this harmless but scary warning
"dlltool: Path components stripped from dllname, '..\perl527.dll'."
So create PERLDLLBASE to silence the warning.
win32.h: In old GCCs,
https://sourceforge.net/p/mingw/mailman/message/22184185/ a function marked
declspec(dllimport) is not a constant. VC from day 1, and newer GCCs use
the address of a 1 instruction jump stub function if a constant function
pointer is needed to a function from a DLL that wont be known till runtime.
This can be worked around in older GCCs by deoptimizing them to always
use the jump stub for all references, and not the newer GCC and VC way
where x86 call instructions directly read the import table in the caller,
while constant functions ptrs in data or vars always refer to the jump
stubs. Since these are old GCCs, performance isn't the highest priority
and building at all is a more important goal. I suspect gcc 3.4.5 has
been broken since 5.13.6 when the declspec(dllimport) code was added.
---
win32/GNUmakefile | 3 ++-
win32/makefile.mk | 3 ++-
win32/win32.h | 43 +++++++++++++++++++++++++++++++------------
3 files changed, 35 insertions(+), 14 deletions(-)
diff --git a/win32/GNUmakefile b/win32/GNUmakefile
index ac4632b..82bf593 100644
--- a/win32/GNUmakefile
+++ b/win32/GNUmakefile
@@ -963,6 +963,7 @@ PERLIMPLIBBASE ?= perl527$(a)
PERLEXPLIB ?= $(COREDIR)\perl527.exp
PERLSTATICLIB ?= ..\perl527s$(a)
PERLDLL = ..\perl527.dll
+PERLDLLBASE = perl527.dll
# don't let "gmake -n all" try to run "miniperl.exe make_ext.pl"
PLMAKE = gmake
@@ -1478,7 +1479,7 @@ $(PERLEXPLIB) : $(PERLIMPLIB)
$(PERLIMPLIB) : perldll.def
ifeq ($(CCTYPE),GCC)
- $(IMPLIB) -k -d perldll.def -l $(PERLIMPLIB) -e $(PERLEXPLIB)
+ $(IMPLIB) -k -d perldll.def -D $(PERLDLLBASE) -l $(PERLIMPLIB) -e $(PERLEXPLIB)
else
lib -def:perldll.def -machine:$(ARCHITECTURE) /OUT:$(PERLIMPLIB)
endif
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 57563c4..265e93b 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -937,6 +937,7 @@ PERLIMPLIB *= $(COREDIR)\perl527$(a)
PERLEXPLIB *= $(COREDIR)\perl527.exp
PERLSTATICLIB *= ..\perl527s$(a)
PERLDLL = ..\perl527.dll
+PERLDLLBASE = perl527.dll
#EUMM on Win32 isn't ready for parallel make, so only allow this file to be parallel
#$(MAKE) will contain the -P that this makefile was called with, which is bad for
@@ -1427,7 +1428,7 @@ perldll.def : $(HAVEMINIPERL) $(CONFIGPM) ..\embed.fnc ..\makedef.pl
$(PERLEXPLIB) $(PERLIMPLIB) .UPDATEALL : perldll.def
.IF "$(CCTYPE)" == "GCC"
- $(IMPLIB) -k -d perldll.def -l $(PERLIMPLIB) -e $(PERLEXPLIB)
+ $(IMPLIB) -k -d perldll.def -D $(PERLDLLBASE) -l $(PERLIMPLIB) -e $(PERLEXPLIB)
.ELSE #VC family
lib -def:perldll.def -machine:$(ARCHITECTURE) /OUT:$(PERLIMPLIB)
.ENDIF
diff --git a/win32/win32.h b/win32/win32.h
index c3fbe9b..1f05a27 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -103,23 +103,42 @@
* The XS code in the re extension is special, in that it redefines
* core APIs locally, so don't mark them as "dllimport" because GCC
* cannot handle this situation.
+ *
+ * Certain old GCCs will not allow the function pointer of dllimport marked
+ * function to be "const". This was fixed later on. Since this is a
+ * deoptimization, target "gcc version 3.4.5 (mingw-vista special r3)" only,
+ * The GCC bug was fixed in GCC patch "varasm.c (initializer_constant_valid_p):
+ * Don't deny DECL_DLLIMPORT_P on functions", which probably was first released
+ * in GCC 4.3.0, this #if can be expanded upto but not including 4.3.0 if more
+ * deployed GCC are found that wont build with the follow error, initializer
+ * element is a PerlIO func exported from perl5xx.dll.
+ *
+ * encoding.xs:610: error: initializer element is not constant
+ * encoding.xs:610: error: (near initialization for `PerlIO_encode.Open')
*/
-#if !defined(PERLDLL) && !defined(PERL_EXT_RE_BUILD)
-# ifdef __cplusplus
-# define PERL_CALLCONV extern "C" __declspec(dllimport)
-# ifdef _MSC_VER
-# define PERL_CALLCONV_NO_RET extern "C" __declspec(dllimport) __declspec(noreturn)
+
+#if (defined(__GNUC__) && defined(__MINGW32__) && \
+ !defined(__MINGW64_VERSION_MAJOR) && !defined(__clang__) && \
+ ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ <= 5))))
+/* use default fallbacks from perl.h for this particular GCC */
+#else
+# if !defined(PERLDLL) && !defined(PERL_EXT_RE_BUILD)
+# ifdef __cplusplus
+# define PERL_CALLCONV extern "C" __declspec(dllimport)
+# ifdef _MSC_VER
+# define PERL_CALLCONV_NO_RET extern "C" __declspec(dllimport) __declspec(noreturn)
+# endif
+# else
+# define PERL_CALLCONV __declspec(dllimport)
+# ifdef _MSC_VER
+# define PERL_CALLCONV_NO_RET __declspec(dllimport) __declspec(noreturn)
+# endif
# endif
-# else
-# define PERL_CALLCONV __declspec(dllimport)
+# else /* MSVC noreturn support inside the interp */
# ifdef _MSC_VER
-# define PERL_CALLCONV_NO_RET __declspec(dllimport) __declspec(noreturn)
+# define PERL_CALLCONV_NO_RET __declspec(noreturn)
# endif
# endif
-#else /* MSVC noreturn support inside the interp */
-# ifdef _MSC_VER
-# define PERL_CALLCONV_NO_RET __declspec(noreturn)
-# endif
#endif
#ifdef _MSC_VER
--
2.5.0.windows.1
|
From @steve-m-hayOn Sat, 07 Apr 2018 15:45:42 -0700, bulk88 wrote:
Thanks for the patch (and for spotting the breakage - I hadn't built with gcc 3.4.5 for quite a while). I can confirm that without the patch blead currently doesn't build, and with the patch all is well. But I have two test failures from that build. Do you see this too? ext/XS-APItest/t/call_checker.t - fails one test C:\Dev\Git\perl\t>.\perl harness -v ../ext/XS-APItest/t/call_checker.t # fail 67ac4520!=6478b0d8 at APItest.xs line 3210 at t/call_checker.t line 9. ok 26 Test Summary Report ../ext/XS-APItest/t/call_checker.t (Wstat: 256 Tests: 78 Failed: 1) C:\Dev\Git\perl\t>.\perl harness -v ../ext/XS-APItest/t/win32.t Test Summary Report ../ext/XS-APItest/t/win32.t (Wstat: 1280 Tests: 116 Failed: 0) |
The RT System itself - Status changed from 'new' to 'open' |
From @bulk88On Wed, 11 Apr 2018 05:27:39 -0700, shay wrote:
Known problem, https://rt.perl.org/Ticket/Display.html?id=78502 https://perl5.git.perl.org/perl.git/commitdiff/ad6ab6c50 the declspec(dllimport) was added specifically 3 weeks after call_checker.t was commited. So the same symbol name func ptrs being != between libperl.dll and XS DLLs has always been there. I can imagine subtle bugs with XS libraries that patch function pointers in core and want to know if its the original p5p supplied func ptr in the var or a unk 3rd party func ptr or their own func ptr. You can't detect if its a p5p func ptr or not anymore. But I'd say for patch/hook chains, dont devs save the old func ptr, put in their own func ptr, then call the old func ptr from the body of their new func, not caring if the old func ptr is original to p5p or yet another hook? On old Mingws, either use declspec(dllimport) and get the same func ptrs, but then you can't use those symbols in a const/static global data (a PerlIO vtable), or dont use declspec(dllimport) but now you can create const global data in a XS DLL with symbols from libperl.dll . I tried removing the "const" from the perlio vtable by commenting out #define PERLIO_FUNCS_CONST in perl.h, still got the const initializer warning. static PerlIO_funcs PerlIO_encode = { I also tried to move that var into the boot XSUB, again const init error, until I removed "static" which made it a C auto scoped to the boot XSUB and it stopped erroring. Putting this in the boot XSUB also works. PerlIO_encode.fsize = sizeof(PerlIO_funcs); Commit https://perl5.git.perl.org/perl.git/commitdiff/ad6ab6c50 did break Mingw 3.4.5 like this Running Makefile.PL in ext/Win32CORE C:\perl521\srcnew\win32> This was fixed in https://perl5.git.perl.org/perl.git/50fd59617d035069f1af09e538c403b3e05768b3 and perl built sucessfully (other problems seem to exist at this point, Carp.pm syntax errors). I tried more bisecting but I ran into build bugs I fixed 2014-2015 so not much builds around that era for me.
If you comment out the last test in ../ext/XS-APItest/t/win32.t, the Comctl32Version() test does it still crash? I disable the comctrl DLL with a private patch so I get, note exit code "2", not your "5" which is a truncated 0xC0000005. My run of the test ok 95 - check good drive v Test Summary Report ../ext/XS-APItest/t/win32.t (Wstat: 512 Tests: 116 Failed: 0) -- |
From @steve-m-hayOn 11 April 2018 at 17:38, bulk88 via RT <perlbug-followup@perl.org> wrote:
With the last test removed (specifically, with the Comctl32Version() |
From @steve-m-hayThanks again - the patch is now applied in blead commit 1b30b4a. (I tried some later MinGW gccs (4.4.0, 4.5.0 and 4.8.1) and found the win32.h part was not necessary for them so I left the version check exactly as you had it.) |
From [Unknown Contact. See original ticket]Thanks again - the patch is now applied in blead commit 1b30b4a. (I tried some later MinGW gccs (4.4.0, 4.5.0 and 4.8.1) and found the win32.h part was not necessary for them so I left the version check exactly as you had it.) |
@steve-m-hay - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#133084 (status was 'resolved')
Searchable as RT133084$
The text was updated successfully, but these errors were encountered: