From c99407ae56502478800d66dcdd87c421594815f6 Mon Sep 17 00:00:00 2001
From: Naveen M K <naveen521kk@gmail.com>
Date: Wed, 23 Jun 2021 18:12:12 +0530
Subject: [PATCH 051/N] Fix extension suffix for c-extensions on mingw

Python is compiled with various compilers which previously
had same platform tags or extension suffix. This can be error
prone while loading c-extensions, so now each compiler or
runtime has a different extension suffix.

Also, changed all extension to end with .pyd rather than
.dll file.

Fixes https://github.com/msys2/MINGW-packages/issues/8843

Signed-off-by: Naveen M K <naveen521kk@gmail.com>
---
 Makefile.pre.in      |  6 ++--
 Python/dynload_win.c |  6 ----
 configure.ac         | 77 +++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/Makefile.pre.in b/Makefile.pre.in
index cef9b3b..80cfff7 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -175,6 +175,7 @@ CONFINCLUDEPY=	$(CONFINCLUDEDIR)/python$(LDVERSION)
 # Symbols used for using shared libraries
 SHLIB_SUFFIX=	@SHLIB_SUFFIX@
 EXT_SUFFIX=	@EXT_SUFFIX@
+PYD_PLATFORM_TAG = @PYD_PLATFORM_TAG@
 LDSHARED=	@LDSHARED@ $(PY_LDFLAGS)
 BLDSHARED=	@BLDSHARED@ $(PY_CORE_LDFLAGS)
 LDCXXSHARED=	@LDCXXSHARED@ $(PY_LDFLAGS)
@@ -1763,8 +1764,7 @@ Python/dynload_hpux.o: $(srcdir)/Python/dynload_hpux.c Makefile
 
 Python/dynload_win.o: $(srcdir)/Python/dynload_win.c Makefile
 	$(CC) -c $(PY_CORE_CFLAGS) \
-		-DSHLIB_SUFFIX='"$(SHLIB_SUFFIX)"' \
-		-DEXT_SUFFIX='"$(EXT_SUFFIX)"' \
+		-DPYD_PLATFORM_TAG='"$(PYD_PLATFORM_TAG)"' \
 		-o $@ $(srcdir)/Python/dynload_win.c
 
 Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(srcdir)/Include/pydtrace.h
@@ -2722,7 +2722,7 @@ libainstall: all scripts
 	@if test "$(STATIC_LIBPYTHON)" = 1; then \
 		if test -d $(LIBRARY); then :; else \
 			if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \
-				if test "$(SHLIB_SUFFIX)" = .dll; then \
+				if test "$(SHLIB_SUFFIX)" = .dll -o "$(SHLIB_SUFFIX)" = .pyd; then \
 					$(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \
 				else \
 					$(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \
diff --git a/Python/dynload_win.c b/Python/dynload_win.c
index 386a2c3..b993b00 100644
--- a/Python/dynload_win.c
+++ b/Python/dynload_win.c
@@ -10,12 +10,6 @@
 #include <windows.h>
 
 const char *_PyImport_DynLoadFiletab[] = {
-#ifdef EXT_SUFFIX
-    EXT_SUFFIX, /* include SOABI flags where is encoded debug */
-#endif
-#ifdef SHLIB_SUFFIX
-    "-abi" PYTHON_ABI_STRING SHLIB_SUFFIX,
-#endif
     PYD_TAGGED_SUFFIX,
     PYD_UNTAGGED_SUFFIX,
     NULL
diff --git a/configure.ac b/configure.ac
index 8632d79..55f94f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3594,7 +3594,7 @@ if test -z "$SHLIB_SUFFIX"; then
 	*)	   SHLIB_SUFFIX=.so;;
 	esac
 	case $host_os in
-	mingw*)    SHLIB_SUFFIX=.dll;;
+	mingw*)    SHLIB_SUFFIX=.pyd;;
 	esac
 fi
 AC_MSG_RESULT([$SHLIB_SUFFIX])
@@ -6543,6 +6543,68 @@ esac
 # check for endianness
 AC_C_BIGENDIAN
 
+AC_SUBST(PYD_PLATFORM_TAG)
+# Special case of PYD_PLATFORM_TAG with python build with mingw.
+# Python can with compiled with clang or gcc and linked
+# to msvcrt or ucrt. To avoid conflicts between them
+# we are selecting the extension as based on the compiler
+# and the runtime they link to
+#   gcc + x86_64 + msvcrt = cp{version number}-x86_64
+#   gcc + i686 + msvcrt = cp{version number}-i686
+#   gcc + x86_64 + ucrt = cp{version number}-x86_64-ucrt
+#   clang + x86_64 + ucrt = cp{version number}-x86_64-clang
+#   clang + i686 + ucrt = cp{version number}-i686-clang
+
+PYD_PLATFORM_TAG=""
+case $host in
+  *-*-mingw*)
+    # check if we are linking to ucrt
+    AC_MSG_CHECKING(whether linking to ucrt)
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+    #include <stdio.h>
+    #ifndef _UCRT
+        #error no ucrt
+    #endif
+    int main(){ return 0; }
+    ]])],[linking_to_ucrt=yes],[linking_to_ucrt=no])
+    AC_MSG_RESULT($linking_to_ucrt)
+    ;;
+esac
+case $host_os in
+    mingw*)
+  AC_MSG_CHECKING(PYD_PLATFORM_TAG)
+  case $host in
+  i686-*-mingw*)
+    if test -n "${cc_is_clang}"; then
+      # it is CLANG32
+      PYD_PLATFORM_TAG="mingw_i686_clang"
+    else
+      if test $linking_to_ucrt = no; then
+        PYD_PLATFORM_TAG="mingw_i686"
+      else
+        PYD_PLATFORM_TAG="mingw_i686_ucrt"
+      fi
+    fi
+    ;;
+  x86_64-*-mingw*)
+    if test -n "${cc_is_clang}"; then
+      # it is CLANG64
+      PYD_PLATFORM_TAG="mingw_x86_64_clang"
+    else
+      if test $linking_to_ucrt = no; then
+        PYD_PLATFORM_TAG="mingw_x86_64"
+      else
+        PYD_PLATFORM_TAG="mingw_x86_64_ucrt"
+      fi
+    fi
+    ;;
+  aarch64-*-mingw*)
+    PYD_PLATFORM_TAG+="mingw_aarch64"
+    ;;
+  esac
+  AC_MSG_RESULT($PYD_PLATFORM_TAG)
+esac
+
 # ABI version string for Python extension modules.  This appears between the
 # periods in shared library file names, e.g. foo.<SOABI>.so.  It is calculated
 # from the following attributes which affect the ABI of this Python build (in
@@ -6577,7 +6639,12 @@ if test "$Py_DEBUG" = 'true'; then
 fi
 
 AC_SUBST([EXT_SUFFIX])
-EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
+VERSION_NO_DOTS=$(echo $LDVERSION | tr -d .)
+if test -n "${PYD_PLATFORM_TAG}"; then
+  EXT_SUFFIX=".cp${VERSION_NO_DOTS}-${PYD_PLATFORM_TAG}${SHLIB_SUFFIX}"
+else
+  EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX}
+fi
 
 AC_MSG_CHECKING([LDVERSION])
 LDVERSION='$(VERSION)$(ABIFLAGS)'
@@ -7325,12 +7392,6 @@ case "$ac_cv_computed_gotos" in yes*)
   AC_DEFINE([HAVE_COMPUTED_GOTOS], [1],
   [Define if the C compiler supports computed gotos.])
 esac
-case $host_os in
-    mingw*)
-	dnl Synchronized with _PyImport_DynLoadFiletab (dynload_win.c)
-	dnl Do not use more then one dot on this platform !
-	EXT_SUFFIX=-$SOABI$SHLIB_SUFFIX;;
-esac
 
 case $ac_sys_system in
 AIX*)
