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] automatically detect GCC vs VC and set VC ver number on Win32 #15515
Comments
From @bulk88Created by @bulk88See attached patch. Perl Info
|
From @bulk880001-automatically-detect-GCC-vs-VC-and-set-VC-ver-number.patchFrom e28311e0a6c2f2e94195d79a2c9e3ee9e208f2e7 Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Sun, 14 Aug 2016 04:34:37 -0400
Subject: [PATCH] automatically detect GCC vs VC and set VC ver number on
Win32
This fixes a bug, if you use gmake, without a GCC in PATH (but you do have
a VC in PATH) GNUMakefile is unusable because target info fatally errors.
I usually keep a strawberry perl's /c/bin dir in PATH for dmake and gmake
on my VC builds, but in 1 build config, I installed gmake to my C:/Windows
dir and did not have SP's /c/bin dir in my PATH, so GNUMakefile was broken
in that case. This patch fixes the bug.
-move the gcc -dumpversion shell outs to the GCC only section in both mkfs
dont run gcc -dumpversion on a VC build
-dont have a default CCTYPE anymore, autodetect it, if user supplies CCTYPE
explicitly on cmd line to make tool, then dont do autodetection (its
faster by 50-100ms to manually specify CCTYPE not call gcc.exe and cl.exe
with the auto detect code), "FREE" detection is unimplemented but seems
to make no difference with VC except for an old rare "free" VC 2003
I personally use a paid VC 2003.
-silence console messages and warnings from a missing gcc.exe causing
"gcc -dumpmachine" to warn or fatally error, gmake doesn't care about
exit code, dmake does
-on dmake, use := instead of *= or =, otherwise the long for loop shell
line runs dozens of times (multiple eval problem)
-on dmake, since GCCBIN macro doesn't exist and dmake mfk is "simpler"
than gmake just call gcc.exe always and not a prefixed version of GCC for
the GCCTARGET macro, it isn't used outside the autodetection code anyways
and if a user neglected to specify CCTYPE it is assumed they neglected to
specify GCCCROSS too
---
win32/GNUmakefile | 36 ++++++++++++++++++++++++++++++------
win32/makefile.mk | 16 +++++++++++++++-
2 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/win32/GNUmakefile b/win32/GNUmakefile
index 763b829..fc7dd30 100644
--- a/win32/GNUmakefile
+++ b/win32/GNUmakefile
@@ -36,10 +36,6 @@ ifeq ($(GCCBIN),i686-w64-mingw32-gcc)
GCCCROSS := i686-w64-mingw32
endif
-GCCTARGET := $(shell $(GCCBIN) -dumpmachine)
-GCCVER1 := $(shell for /f "delims=. tokens=1,2,3" %%i in ('gcc -dumpversion') do echo %%i)
-GCCVER2 := $(shell for /f "delims=. tokens=1,2,3" %%i in ('gcc -dumpversion') do echo %%j)
-GCCVER3 := $(shell for /f "delims=. tokens=1,2,3" %%i in ('gcc -dumpversion') do echo %%k)
##
## Build configuration. Edit the values below to suit your needs.
@@ -178,7 +174,7 @@ USE_LARGE_FILES := define
# Visual C++ 2013 Express Edition (aka Visual C++ 12.0) (free version)
#CCTYPE := MSVC120FREE
# MinGW or mingw-w64 with gcc-3.4.5 or later
-CCTYPE := GCC
+#CCTYPE := GCC
#
# If you are using Intel C++ Compiler uncomment this
@@ -355,6 +351,27 @@ BUILDOPT += -DWIN32_NO_REGISTRY
endif
ifeq ($(CCTYPE),GCC)
+GCCTARGET := $(shell $(GCCBIN) -dumpmachine)
+endif
+
+#no explicit CCTYPE given, do auto detection
+ifeq ($(CCTYPE),)
+GCCTARGET := $(shell $(GCCBIN) -dumpmachine 2>NUL)
+#do we have a GCC?
+ifneq ($(GCCTARGET),)
+CCTYPE := GCC
+else
+#use var to capture 1st line only, not 8th token of lines 2 & 3 in cl.exe output
+#rmving the cmd /c causes the var2b undef4echo but!4"set MSVCVER", cmd.exe bug?
+MSVCVER := $(shell (set MSVCVER=) & (for /f "tokens=8 delims=.^ " \
+ %%i in ('cl ^2^>^&1') do if not defined MSVCVER set /A "MSVCVER=%%i-6") \
+ & cmd /c echo %%MSVCVER%%)
+CCTYPE := MSVC$(MSVCVER)0
+endif
+endif
+
+
+ifeq ($(CCTYPE),GCC)
ifeq ($(GCCTARGET),x86_64-w64-mingw32)
WIN64 := define
PROCESSOR_ARCHITECTURE := x64
@@ -483,6 +500,10 @@ BUILDOPT += -D__USE_MINGW_ANSI_STDIO
MINIBUILDOPT += -D__USE_MINGW_ANSI_STDIO
endif
+GCCVER1 := $(shell for /f "delims=. tokens=1,2,3" %%i in ('gcc -dumpversion') do echo %%i)
+GCCVER2 := $(shell for /f "delims=. tokens=1,2,3" %%i in ('gcc -dumpversion') do echo %%j)
+GCCVER3 := $(shell for /f "delims=. tokens=1,2,3" %%i in ('gcc -dumpversion') do echo %%k)
+
# If you are using GCC, 4.3 or later by default we add the -fwrapv option.
# See https://rt.perl.org/Ticket/Display.html?id=121505
#
@@ -1079,15 +1100,18 @@ CFG_VARS = \
all : info rebasePE Extensions_nonxs $(PERLSTATIC)
info :
+ @echo # CCTYPE=$(CCTYPE)
+ifeq ($(CCTYPE),GCC)
@echo # GCCBIN=$(GCCBIN)
@echo # GCCVER=$(GCCVER1).$(GCCVER2).$(GCCVER3)
@echo # GCCTARGET=$(GCCTARGET)
@echo # GCCCROSS=$(GCCCROSS)
+endif
@echo # WIN64=$(WIN64)
@echo # ARCHITECTURE=$(ARCHITECTURE)
@echo # ARCHNAME=$(ARCHNAME)
@echo # MAKE=$(PLMAKE)
-ifeq ($(GCCTARGET),)
+ifeq ($(CCTYPE),)
@echo Unable to detect gcc and/or architecture!
@exit 1
endif
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 391112b..478da43 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -146,7 +146,7 @@ USE_LARGE_FILES *= define
# Visual C++ 2013 Express Edition (aka Visual C++ 12.0) (free version)
#CCTYPE = MSVC120FREE
# MinGW or mingw-w64 with gcc-3.4.5 or later
-CCTYPE *= GCC
+#CCTYPE = GCC
#
# If you are using GCC, 4.3 or later by default we add the -fwrapv option.
@@ -355,6 +355,20 @@ BUILDOPT += -DPERL_IMPLICIT_SYS
BUILDOPT += -DWIN32_NO_REGISTRY
.ENDIF
+#no explicit CCTYPE given, do auto detection
+.IF "$(CCTYPE)" == ""
+GCCTARGET *= $(shell gcc -dumpmachine 2>NUL & exit /b 0)
+#do we have a GCC?
+.IF "$(GCCTARGET)" != ""
+CCTYPE = GCC
+else
+#use var to capture 1st line only, not 8th token of lines 2 & 3 in cl.exe output
+MSVCVER := $(shell (set MSVCVER=) & (for /f "tokens=8 delims=.^ " \
+ %i in ('cl ^2^>^&1') do @if not defined MSVCVER set /A "MSVCVER=%i-6"))
+CCTYPE := MSVC$(MSVCVER)0
+endif
+endif
+
PROCESSOR_ARCHITECTURE *= x86
.IF "$(WIN64)" == "undef"
--
1.7.9.msysgit.0
|
From @khwilliamsonOn 08/14/2016 09:24 AM, bulk88 (via RT) wrote:
Thanks, applied as 1d4ea28
|
The RT System itself - Status changed from 'new' to 'open' |
From @bulk88On Sun Aug 14 08:54:34 2016, public@khwilliamson.com wrote:
You posted on the wrong ticket. This isn't the "silence MSVC warnings for NATIVE_UTF8_TO_I8/I8_TO_NATIVE_UTF8" one. -- |
From @khwilliamsonOn 08/14/2016 10:35 AM, bulk88 via RT wrote:
I had just realized that. Fixing now... |
From @khwilliamsonOn 08/14/2016 09:54 AM, Karl Williamson wrote:
Oops, That should have been applied as
|
From @khwilliamsonNow fixed by ca30c09 |
@khwilliamson - Status changed from 'open' to 'resolved' |
From @dcollinsnOn Sun Aug 14 09:46:29 2016, khw wrote:
A nitpick with this patch: Makefile.mk lines 236 and on contains the following: .IF "$(CCTYPE)" == "GCC" Previously, CCTYPE was set before this, at line 149 at the latest. Now, it is set after this, at line 358. So builds using this "gcc autodetect" will have an incorrect CCHOME set. I noticed this because the default behavior now detects GCC, but doesn't set CCHOME properly, which causes a few tests in t/op/taint.t to fail. (Example: http://73.193.221.114:8010/#/builders/6/builds/7 ) When I run the test in a real console, I get some missing dll popups, so it seems like an interaction between taint mode and the test trying to spawn a new process. I tried moving the new code in Makefile.mk earlier, to line 151, and the test now passes. However since Makefile.mk is set up as Config followed by Code, that probably isn't the right way to fix this. The attached patch illustrates my current idea. I hope it's correct to reopen this ticket rather than open a new one, since I believe it's caused by the same section of code. -- |
From @dcollinsn0001-win32-Makefile.mk-Fix-use-of-uninitialized-CCTYPE.patchFrom 690b0927891e9f918742329dcac1aa1e82a850b9 Mon Sep 17 00:00:00 2001
From: Dan Collins <dcollinsn@gmail.com>
Date: Sun, 14 Aug 2016 18:10:37 -0400
Subject: [PATCH] win32/Makefile.mk: Fix use of uninitialized CCTYPE
RT #128930 added some code to intelligently divine the CCTYPE
in use. However, CCTYPE is used to set CCHOME before this new
code runs. This patch resolves the issue while keeping a clear
delineation between configuration and code in Makefile.mk.
---
win32/makefile.mk | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 478da43..f52cfc7 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -230,14 +230,13 @@ USE_LARGE_FILES *= define
# set the install locations of the compiler include/libraries
# Running VCVARS32.BAT is *required* when using Visual C.
# Some versions of Visual C don't define MSVCDIR in the environment,
-# so you may have to set CCHOME explicitly (spaces in the path name should
+# so you may have to set MSVCHOME explicitly (spaces in the path name should
# not be quoted)
#
-.IF "$(CCTYPE)" == "GCC"
-CCHOME *= C:\MinGW
-.ELSE
-CCHOME *= $(MSVCDIR)
-.ENDIF
+# One of these will be used as CCHOME, based on the compiler you are using
+#
+GCCHOME *= C:\MinGW
+MSVCHOME *= $(MSVCDIR)
#
# uncomment this if you are using x86_64-w64-mingw32 cross-compiler
@@ -369,6 +368,12 @@ CCTYPE := MSVC$(MSVCVER)0
endif
endif
+.IF "$(CCTYPE)" == "GCC"
+CCHOME *= $(GCCHOME)
+.ELSE
+CCHOME *= $(MSVCHOME)
+.ENDIF
+
PROCESSOR_ARCHITECTURE *= x86
.IF "$(WIN64)" == "undef"
--
2.8.3
|
@dcollinsn - Status changed from 'resolved' to 'open' |
From @khwilliamsonOn 08/14/2016 04:16 PM, Dan Collins via RT wrote:
Yes it is correct |
From @bulk88On Sun Aug 14 15:16:42 2016, dcollinsn@gmail.com wrote:
taint.t starts perl procs with no PATH env var (it was deleted before proc start (open/backticks)). Kindda a miracle from MS that C:/windows/system32 is hardcoded (it isn't absolute, im not going into details) into windows DLL/EXE loader as a search path so even if PATH is missing most procs can start with no drama.
I put the auto detect logic much lower in the file on purpose to keep that "settings at top" vs "logic at bottom" separation and so users editing the top aren't confused by mkf logic. Your patch looks okay except GNUMakefile also needs the same changes. My solution would be to avoid new mkf vars (a tiny tiny bit less mem/cpu) and do something like this # so you may have to set CCHOME explicitly (spaces in the path name should #LATER ON SOMEWHERE BELOW if $CCHOME == '' My Mingw has never ever been in C:\MinGW on any of my machines, since I always use Mingws distributed with strawberry perls, never a standalone mingw. My GCCs are always in C:\strawberry\c\bin\ or C:\sp5XX\c\bin\ so taint.t never passes for me. BTW did you know libgcc_s_sjlj-1.dll and libstdc++-6.dll aren't binary compatible between different Mingw versions? Mingw devs for 10 years had __thiscall used for C++ funcs/methods implemented machine code wise as an alias for __cdecl, then in GCC 4.8 they implemented __thiscall the way MSVC does (this pointer var in a register, everything else on C stack), so you can't install the GCC helper DLLs globally or your are screwed with SEGVs on proc startup since parts of the static linked boilerplane DllMain code in each Mingw compiled DLL use C++ methods new/delete instead of malloc/free for some stupid reason. -- |
From @bulk88I wrote a new patch that implements my idea and fixes the CCHOME set before CCTYPE autodetect code bug. Please test it. -- |
From @bulk880001-perl-128930-tweaks-for-Win32-VC-vs-GCC-detection-mak.patchFrom a97a02c6bdbd7e03113d2ccb555f093524ca9d7a Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Mon, 15 Aug 2016 17:00:18 -0400
Subject: [PATCH] [perl #128930] tweaks for Win32 VC vs GCC detection makefile
code
-fix issue that CCHOME depends on CCTYPE, which in auto detect mode is
set after CCHOME so CCHOME uses uninit CCTYPE var
-also fix else vs .ELSE in makefile.mk
---
win32/GNUmakefile | 45 ++++++++++++++++++++++++---------------------
win32/makefile.mk | 51 +++++++++++++++++++++++++++++----------------------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/win32/GNUmakefile b/win32/GNUmakefile
index fc7dd30..fe1a421 100644
--- a/win32/GNUmakefile
+++ b/win32/GNUmakefile
@@ -238,27 +238,7 @@ USE_LARGE_FILES := define
# so you may have to set CCHOME explicitly (spaces in the path name should
# not be quoted)
#
-ifeq ($(CCTYPE),GCC)
-CCHOME := C:\MinGW
-else
-CCHOME := $(MSVCDIR)
-endif
-
-#
-# Following sets $Config{incpath} and $Config{libpth}
-#
-
-ifneq ($(GCCCROSS),)
-CCINCDIR := $(CCHOME)\$(GCCCROSS)\include
-CCLIBDIR := $(CCHOME)\$(GCCCROSS)\lib
-CCDLLDIR := $(CCLIBDIR)
-ARCHPREFIX := $(GCCCROSS)-
-else
-CCINCDIR := $(CCHOME)\include
-CCLIBDIR := $(CCHOME)\lib
-CCDLLDIR := $(CCHOME)\bin
-ARCHPREFIX :=
-endif
+#CCHOME := C:\MinGW
#
# Additional compiler flags can be specified here.
@@ -370,6 +350,29 @@ CCTYPE := MSVC$(MSVCVER)0
endif
endif
+ifeq ($(CCHOME),)
+ifeq ($(CCTYPE),GCC)
+CCHOME := C:\MinGW
+else
+CCHOME := $(MSVCDIR)
+endif
+endif
+
+#
+# Following sets $Config{incpath} and $Config{libpth}
+#
+
+ifneq ($(GCCCROSS),)
+CCINCDIR := $(CCHOME)\$(GCCCROSS)\include
+CCLIBDIR := $(CCHOME)\$(GCCCROSS)\lib
+CCDLLDIR := $(CCLIBDIR)
+ARCHPREFIX := $(GCCCROSS)-
+else
+CCINCDIR := $(CCHOME)\include
+CCLIBDIR := $(CCHOME)\lib
+CCDLLDIR := $(CCHOME)\bin
+ARCHPREFIX :=
+endif
ifeq ($(CCTYPE),GCC)
ifeq ($(GCCTARGET),x86_64-w64-mingw32)
diff --git a/win32/makefile.mk b/win32/makefile.mk
index 478da43..5f61b4f 100644
--- a/win32/makefile.mk
+++ b/win32/makefile.mk
@@ -233,11 +233,8 @@ USE_LARGE_FILES *= define
# so you may have to set CCHOME explicitly (spaces in the path name should
# not be quoted)
#
-.IF "$(CCTYPE)" == "GCC"
-CCHOME *= C:\MinGW
-.ELSE
-CCHOME *= $(MSVCDIR)
-.ENDIF
+
+#CCHOME *= C:\MinGW
#
# uncomment this if you are using x86_64-w64-mingw32 cross-compiler
@@ -247,20 +244,6 @@ CCHOME *= $(MSVCDIR)
#GCCCROSS *= define
#
-# Following sets $Config{incpath} and $Config{libpth}
-#
-
-.IF "$(GCCCROSS)" == "define"
-CCINCDIR *= $(CCHOME)\x86_64-w64-mingw32\include
-CCLIBDIR *= $(CCHOME)\x86_64-w64-mingw32\lib
-CCDLLDIR *= $(CCLIBDIR)
-.ELSE
-CCINCDIR *= $(CCHOME)\include
-CCLIBDIR *= $(CCHOME)\lib
-CCDLLDIR *= $(CCHOME)\bin
-.ENDIF
-
-#
# Additional compiler flags can be specified here.
#
BUILDOPT *= $(BUILDOPTEXTRA)
@@ -319,6 +302,7 @@ USE_64_BIT_INT *= undef
USE_LONG_DOUBLE *= undef
USE_NO_REGISTRY *= undef
+
.IF "$(USE_IMP_SYS)" == "define"
PERL_MALLOC = undef
.ENDIF
@@ -361,13 +345,36 @@ GCCTARGET *= $(shell gcc -dumpmachine 2>NUL & exit /b 0)
#do we have a GCC?
.IF "$(GCCTARGET)" != ""
CCTYPE = GCC
-else
+.ELSE
#use var to capture 1st line only, not 8th token of lines 2 & 3 in cl.exe output
MSVCVER := $(shell (set MSVCVER=) & (for /f "tokens=8 delims=.^ " \
%i in ('cl ^2^>^&1') do @if not defined MSVCVER set /A "MSVCVER=%i-6"))
CCTYPE := MSVC$(MSVCVER)0
-endif
-endif
+.ENDIF
+.ENDIF
+
+
+.IF "$(CCHOME)" == ""
+.IF "$(CCTYPE)" == "GCC"
+CCHOME *= C:\MinGW
+.ELSE
+CCHOME *= $(MSVCDIR)
+.ENDIF
+.ENDIF
+
+#
+# Following sets $Config{incpath} and $Config{libpth}
+#
+
+.IF "$(GCCCROSS)" == "define"
+CCINCDIR *= $(CCHOME)\x86_64-w64-mingw32\include
+CCLIBDIR *= $(CCHOME)\x86_64-w64-mingw32\lib
+CCDLLDIR *= $(CCLIBDIR)
+.ELSE
+CCINCDIR *= $(CCHOME)\include
+CCLIBDIR *= $(CCHOME)\lib
+CCDLLDIR *= $(CCHOME)\bin
+.ENDIF
PROCESSOR_ARCHITECTURE *= x86
--
1.7.9.msysgit.0
|
From @dcollinsnOn Mon Aug 15 14:01:58 2016, bulk88 wrote:
I've tested that, it works as expected with dmake and mingw-w64. I have not tested the changes to gnumakefile, however. -- |
From @tonycozOn Mon Aug 15 15:01:07 2016, dcollinsn@gmail.com wrote:
This was applied as ca30c09 by khw. Tony |
@tonycoz - Status changed from 'open' to 'pending release' |
@tonycoz - Status changed from 'pending release' to 'open' |
@tonycoz - Status changed from 'open' to 'pending release' |
From @khwilliamsonThank you for filing this report. You have helped make Perl better. With the release today of Perl 5.26.0, this and 210 other issues have been Perl 5.26.0 may be downloaded via: If you find that the problem persists, feel free to reopen this ticket. |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#128930 (status was 'resolved')
Searchable as RT128930$
The text was updated successfully, but these errors were encountered: