From: Sisyphus Date: Tue, 10 Nov 2009 03:56:14 +0000 (-0500) Subject: Add mingw64 support X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=fa58a56f3cdf71021d7d7a49e98845f57652a3fe;p=p5sagit%2Fp5-mst-13.2.git Add mingw64 support Hi, Using the attached patch to the blead source (as of a few hours ago), I can build perl with the following OS/compiler/make combos. On 32-bit XP: MSVC++ 7.0 / dmake (uses win32/makefile.mk) MSVC++ 7.0 / nmake (uses win32/Makefile) Borland C++ 5.5.1 / dmake mingw.org's gcc-4.3.0 / dmake mingw.org's gcc-3.4.5 / dmake mingw-w64.sf's 32-bit gcc-4.4.3 / dmake (There's a bug with that last compiler on XP. The perl it builds on XP hangs on XP, but runs ok if copied across to Vista. I think this is unrelated to the patches - probably even unrelated to perl. Without these patches perl will not even build using that last compiler.) On 64-bit Vista: 32-bit MSVC++ 7.0 / nmake (uses win32/Makefile) 32-bit MSVC++ 7.0 / dmake (uses win32/makfile.mk) 32-bit Borland C++ 5.5.1 / dmake mingw.org's 32-bit gcc-4.4.0 / dmake mingw.org's 32-bit gcc-3.4.5 / dmake mingw-w64.sf's 32-bit gcc-4.4.3 / dmake mingw-w64.sf's 64-bit gcc-4.4.3 / dmake mingw-w64.sf's 64-bit x86_64-w64-mingw32-gcc-4.4.3 / dmake 64-bit MicrosoftPlatform SDK for Windows Server 2003 R2 / dmake (uses win32/makefile.mk) 64-bit MicrosoftPlatform SDK for Windows Server 2003 R2 / nmake (uses win32/Makefile) Not all of those builds pass all tests - but where the removal of the patches still permits perl to build, the same tests still fail. That is, *nothing* is lost by including these patches - but there are significant gains. Each of the above builds was done according to the normal win32 configuration parameters - ie multi-threaded, non debug. No unusual config settings were applied. (I did build one debug perl on Vista using mingw-w64.sf's 32-bit gcc-4.4.3 and it built fine.) Please feel free to apply these patches (with or without modification) - and, yes, you're more than welcome to blame me if they cause any breakages ;-) Of course, some of those compilers (Borland, Microsoft, and the compilers from mingw.org) already build perl *without* having to apply any patches. It's just the other compilers that need the patches. The purpose of testing with Borland, Microsoft, and the mingw.org compilers is just to check that these patches don't break them. As a final check, I've done a build on my aging linux (mandrake-9.1) box, gcc-3.2.2. I built with '-des -Duselongdouble -Duse64bitint -Dusedevel'. No problem with that, either. If there's additional testing requirements please let me know, and I'll try to oblige. I believe the patch applied successfully for me - see below my sig for the output. Cheers, Rob Rob@desktop2 ~/GIT/blead $ patch -p0 above on how to get it. =item MinGW release 1 with gcc @@ -396,7 +416,16 @@ may end up building against the installed perl's lib/CORE directory rather than the one being tested. You will have to make sure that CCTYPE is set correctly and that -CCHOME points to wherever you installed your compiler. +CCHOME points to wherever you installed your compiler. If building with +gcc-4.x.x, you'll also need to uncomment the assignment to GCC_4XX and +uncomment the assignment to the appropriate GCCHELPERDLL in the makefile.mk. + +If building with the cross-compiler provided by +mingw-w64.sourceforge.net you'll need to uncomment the line that sets +GCCCROSS in the makefile.mk. Do this only if it's the cross-compiler - ie +only if the bin folder doesn't contain a gcc.exe. (The cross-compiler +does not provide a gcc.exe, g++.exe, ar.exe, etc. Instead, all of these +executables are prefixed with 'x86_64-w64-mingw32-'.) The default value for CCHOME in the makefiles for Visual C++ may not be correct for some versions. Make sure the default exists diff --git a/XSUB.h b/XSUB.h index 5334cfc..f23df37 100644 --- a/XSUB.h +++ b/XSUB.h @@ -478,6 +478,12 @@ Rethrows a previously caught exception. See L. # undef setservent #endif /* NETWARE */ +/* to avoid warnings: "xyz" redefined */ +#ifdef WIN32 +# undef popen +# undef pclose +#endif /* WIN32 */ + # undef socketpair # define mkdir PerlDir_mkdir diff --git a/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Win32.pm b/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Win32.pm index d3a5a4d..15d4b3d 100644 --- a/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Win32.pm +++ b/cpan/ExtUtils-MakeMaker/lib/ExtUtils/MM_Win32.pm @@ -32,7 +32,8 @@ our $VERSION = '6.55_02'; $ENV{EMXSHELL} = 'sh'; # to run `commands` my $BORLAND = $Config{'cc'} =~ /^bcc/i ? 1 : 0; -my $GCC = $Config{'cc'} =~ /^gcc/i ? 1 : 0; +my $GCC = $Config{'cc'} =~ /\bgcc$/i ? 1 : 0; +my $DLLTOOL = $Config{'dlltool'} || 'dlltool'; =head2 Overridden methods @@ -309,9 +310,9 @@ $(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP). '); if ($GCC) { push(@m, - q{ dlltool --def $(EXPORT_LIST) --output-exp dll.exp + q{ }.$DLLTOOL.q{ --def $(EXPORT_LIST) --output-exp dll.exp $(LD) -o $@ -Wl,--base-file -Wl,dll.base $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp - dlltool --def $(EXPORT_LIST) --base-file dll.base --output-exp dll.exp + }.$DLLTOOL.q{ --def $(EXPORT_LIST) --base-file dll.base --output-exp dll.exp $(LD) -o $@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) dll.exp }); } elsif ($BORLAND) { push(@m, diff --git a/dist/threads/threads.xs b/dist/threads/threads.xs index 7d0ad23..5d98a59 100755 --- a/dist/threads/threads.xs +++ b/dist/threads/threads.xs @@ -1,11 +1,17 @@ #define PERL_NO_GET_CONTEXT +/* Workaround for mingw 32-bit compiler by mingw-w64.sf.net - has to come before any #include. + * It also defines USE_NO_MINGW_SETJMP_TWO_ARGS for the mingw.org 32-bit compilers ... but + * that's ok as that compiler makes no use of that symbol anyway */ +#if defined(WIN32) && defined(__MINGW32__) && !defined(__MINGW64__) +# define USE_NO_MINGW_SETJMP_TWO_ARGS 1 +#endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* Workaround for XSUB.h bug under WIN32 */ #ifdef WIN32 # undef setjmp -# if !defined(__BORLANDC__) +# if defined(USE_NO_MINGW_SETJMP_TWO_ARGS) || (!defined(__BORLANDC__) && !defined(__MINGW64__)) # define setjmp(x) _setjmp(x) # endif #endif diff --git a/handy.h b/handy.h index d291eb6..9ec64e0 100644 --- a/handy.h +++ b/handy.h @@ -190,8 +190,13 @@ typedef U64TYPE U64; # define INT64_C(c) CAT2(c,L) # define UINT64_C(c) CAT2(c,UL) # else -# define INT64_C(c) ((I64TYPE)(c)) -# define UINT64_C(c) ((U64TYPE)(c)) +# if defined(_WIN64) && defined(_MSC_VER) +# define INT64_C(c) CAT2(c,I64) +# define UINT64_C(c) CAT2(c,UI64) +# else +# define INT64_C(c) ((I64TYPE)(c)) +# define UINT64_C(c) ((U64TYPE)(c)) +# endif # endif # endif # endif diff --git a/op.c b/op.c index 8293fab..bd783d7 100644 --- a/op.c +++ b/op.c @@ -5774,7 +5774,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block) if (PL_madskills) { if (strEQ(name, "import")) { PL_formfeed = MUTABLE_SV(cv); - Perl_warner(aTHX_ packWARN(WARN_VOID), "%lx\n", (long)cv); + Perl_warner(aTHX_ packWARN(WARN_VOID), UVxf"\n", (UV)cv); } } GvCVGEN(gv) = 0; diff --git a/pp_pack.c b/pp_pack.c index 18f17f7..03eaf7f 100644 --- a/pp_pack.c +++ b/pp_pack.c @@ -321,10 +321,17 @@ S_mul128(pTHX_ SV *sv, U8 m) # define DO_BO_UNPACK_PC(var) DO_BO_UNPACK_PTR(var, i, int, char) # define DO_BO_PACK_PC(var) DO_BO_PACK_PTR(var, i, int, char) # elif PTRSIZE == LONGSIZE -# define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, l, long, void) -# define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, l, long, void) -# define DO_BO_UNPACK_PC(var) DO_BO_UNPACK_PTR(var, l, long, char) -# define DO_BO_PACK_PC(var) DO_BO_PACK_PTR(var, l, long, char) +# if LONGSIZE < IVSIZE && IVSIZE == 8 +# define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, 64, IV, void) +# define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, 64, IV, void) +# define DO_BO_UNPACK_PC(var) DO_BO_UNPACK_PTR(var, 64, IV, char) +# define DO_BO_PACK_PC(var) DO_BO_PACK_PTR(var, 64, IV, char) +# else +# define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, l, IV, void) +# define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, l, IV, void) +# define DO_BO_UNPACK_PC(var) DO_BO_UNPACK_PTR(var, l, IV, char) +# define DO_BO_PACK_PC(var) DO_BO_PACK_PTR(var, l, IV, char) +# endif # elif PTRSIZE == IVSIZE # define DO_BO_UNPACK_P(var) DO_BO_UNPACK_PTR(var, l, IV, void) # define DO_BO_PACK_P(var) DO_BO_PACK_PTR(var, l, IV, void) diff --git a/util.c b/util.c index 5e5758d..0aab786 100644 --- a/util.c +++ b/util.c @@ -5366,7 +5366,7 @@ Perl_get_hash_seed(pTHX) * help. Sum in another random number that will * fill in the low bits. */ myseed += - (UV)(Drand01() * (NV)((1 << ((UVSIZE * 8 - RANDBITS))) - 1)); + (UV)(Drand01() * (NV)((((UV)1) << ((UVSIZE * 8 - RANDBITS))) - 1)); #endif /* RANDBITS < (UVSIZE * 8) */ if (myseed == 0) { /* Superparanoia. */ myseed = (UV)(Drand01() * (NV)UV_MAX); /* One more chance. */ diff --git a/win32/makefile.mk b/win32/makefile.mk index d46db1b..a392472 100644 --- a/win32/makefile.mk +++ b/win32/makefile.mk @@ -112,7 +112,7 @@ USE_LARGE_FILES *= define #CCTYPE *= MSVC90 # Borland 5.02 or later #CCTYPE *= BORLAND -# MinGW with gcc-2.95.2 or later +# MinGW or mingw-w64 with gcc-2.95.2 or later CCTYPE *= GCC # @@ -220,6 +220,29 @@ CCINCDIR *= $(CCHOME)\include CCLIBDIR *= $(CCHOME)\lib # +# If building with gcc-4.x.x (or x86_64-w64-mingw32-gcc-4.x.x), then +# uncomment the following assignment to GCC_4XX, make sure that CCHOME +# has been set correctly above, and uncomment the appropriate +# GCCHELPERDLL line. +# The name of the dll can change, depending upon which vendor has supplied +# your 4.x.x compiler, and upon the values of "x". +# (The dll will be in your mingw/bin folder, so check there if you're +# unsure about the correct name.) +# Without these corrections, the op/taint.t test script will fail. +# +#GCC_4XX *= define +#GCCHELPERDLL *= $(CCHOME)\bin\libgcc_s_sjlj-1.dll +#GCCHELPERDLL *= $(CCHOME)\bin\libgcc_s_dw2-1.dll +#GCCHELPERDLL *= $(CCHOME)\bin\libgcc_s_1.dll + +# +# uncomment this if you are using x86_64-w64-mingw32 cross-compiler +# ie if your gcc executable is called 'x86_64-w64-mingw32-gcc' +# instead of the usual 'gcc'. +# +#GCCCROSS *= define + +# # Additional compiler flags can be specified here. # BUILDOPT *= $(BUILDOPTEXTRA) @@ -475,11 +498,15 @@ LINK_FLAGS += -L"$(CCLIBDIR)\Release" .ELIF "$(CCTYPE)" == "GCC" -CC = gcc -LINK32 = g++ -LIB32 = ar rc -IMPLIB = dlltool -RSC = windres +.IF "$(GCCCROSS)" == "define" +ARCHPREFIX = x86_64-w64-mingw32- +.ENDIF + +CC = $(ARCHPREFIX)gcc +LINK32 = $(ARCHPREFIX)g++ +LIB32 = $(ARCHPREFIX)ar rc +IMPLIB = $(ARCHPREFIX)dlltool +RSC = $(ARCHPREFIX)windres i = .i o = .o @@ -491,6 +518,9 @@ a = .a INCLUDES = -I.\include -I. -I.. -I$(COREDIR) DEFINES = -DWIN32 $(CRYPT_FLAG) +.IF "$(WIN64)" == "define" +DEFINES += -DWIN64 -DCONSERVATIVE +.ENDIF LOCDEFS = -DPERLDLL -DPERL_CORE SUBSYS = console CXX_FLAG = -xc++ @@ -783,8 +813,18 @@ CFGH_TMPL = config_H.bc .ELIF "$(CCTYPE)" == "GCC" +.IF "$(WIN64)" == "define" +.IF "$(GCCCROSS)" == "define" +CFGSH_TMPL = config.gc64 +CFGH_TMPL = config_H.gc64 +.ELSE +CFGSH_TMPL = config.gc64nox +CFGH_TMPL = config_H.gc64nox +.ENDIF +.ELSE CFGSH_TMPL = config.gc CFGH_TMPL = config_H.gc +.ENDIF PERLIMPLIB = ..\libperl511$(a) PERLSTATICLIB = ..\libperl511s$(a) @@ -1220,7 +1260,7 @@ $(PERLDLL): perldll.def $(PERLDLL_OBJ) $(PERLDLL_RES) Extensions_static $(mktmp $(LKPRE) $(PERLDLL_OBJ) \ $(shell @type Extensions_static) \ $(LIBFILES) $(LKPOST)) - dlltool --output-lib $(PERLIMPLIB) \ + $(IMPLIB) --output-lib $(PERLIMPLIB) \ --dllname $(PERLDLL:b).dll \ --def perldll.def \ --base-file perl.base \ @@ -1582,6 +1622,11 @@ test-prep : all utils .ELSE $(XCOPY) $(GLOBEXE) ..\t\$(NULL) .ENDIF +.IF "$(CCTYPE)" == "GCC" +.IF "$(GCC_4XX)" == "define" + $(XCOPY) $(GCCHELPERDLL) ..\t\$(NULL) +.ENDIF +.ENDIF test : $(RIGHTMAKE) test-prep cd ..\t && $(PERLEXE) -I..\lib harness $(TEST_SWITCHES) $(TEST_FILES) diff --git a/win32/perlhost.h b/win32/perlhost.h index c2473c9..d486246 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -1747,7 +1747,7 @@ win32_start_child(LPVOID arg) parent_message_hwnd = w32_message_hwnd; w32_message_hwnd = win32_create_message_window(); if (parent_message_hwnd != NULL) - PostMessage(parent_message_hwnd, WM_USER_MESSAGE, w32_pseudo_id, (LONG)w32_message_hwnd); + PostMessage(parent_message_hwnd, WM_USER_MESSAGE, w32_pseudo_id, (LPARAM)w32_message_hwnd); /* push a zero on the stack (we are the child) */ { diff --git a/win32/win32.c b/win32/win32.c index 41fae60..e6674e1 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -2014,7 +2014,7 @@ win32_uname(struct utsname *name) GetSystemInfo(&info); #if (defined(__BORLANDC__)&&(__BORLANDC__<=0x520)) \ - || (defined(__MINGW32__) && !defined(_ANONYMOUS_UNION)) + || (defined(__MINGW32__) && !defined(_ANONYMOUS_UNION) && !defined(__MINGW_EXTENSION)) procarch = info.u.s.wProcessorArchitecture; #else procarch = info.wProcessorArchitecture; diff --git a/win32/win32.h b/win32/win32.h index c14367a..3916b2e 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -58,6 +58,23 @@ #define WIN32_LEAN_AND_MEAN #include +/* + * Bug in winbase.h in mingw-w64 4.4.0-1 at least... they + * do #define GetEnvironmentStringsA GetEnvironmentStrings and fail + * to declare GetEnvironmentStringsA. + */ +#if defined(__MINGW64__) && defined(GetEnvironmentStringsA) && !defined(UNICODE) +#ifdef __cplusplus +extern "C" { +#endif +#undef GetEnvironmentStringsA +WINBASEAPI LPCH WINAPI GetEnvironmentStringsA(VOID); +#define GetEnvironmentStrings GetEnvironmentStringsA +#ifdef __cplusplus +} +#endif +#endif + #ifdef WIN32_LEAN_AND_MEAN /* C file is NOT a Perl5 original. */ #define CONTEXT PERL_CONTEXT /* Avoid conflict of CONTEXT defs. */ #endif /*WIN32_LEAN_AND_MEAN */