Skip to content

Commit 034158e

Browse files
committed
Add support for building extensions using MinGW compilers
1 parent 45295fc commit 034158e

File tree

5 files changed

+33
-11
lines changed

5 files changed

+33
-11
lines changed

distutils/ccompiler.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from .file_util import move_file
1919
from .dir_util import mkpath
2020
from .dep_util import newer_group
21-
from .util import split_quoted, execute
21+
from .util import split_quoted, execute, is_mingw
2222
from . import log
2323

2424

@@ -1042,6 +1042,10 @@ def get_default_compiler(osname=None, platform=None):
10421042
osname = os.name
10431043
if platform is None:
10441044
platform = sys.platform
1045+
# Mingw is a special case where sys.platform is 'win32' but we
1046+
# want to use the 'mingw32' compiler, so check it first
1047+
if is_mingw():
1048+
return 'mingw32'
10451049
for pattern, compiler in _default_compilers:
10461050
if (
10471051
re.match(pattern, platform) is not None

distutils/command/build_ext.py

+11-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from ..sysconfig import get_config_h_filename
2222
from ..dep_util import newer_group
2323
from ..extension import Extension
24-
from ..util import get_platform
24+
from ..util import get_platform, is_mingw
2525
from distutils import log
2626
from . import py37compat
2727

@@ -190,7 +190,7 @@ def finalize_options(self): # noqa: C901
190190
# for extensions under windows use different directories
191191
# for Release and Debug builds.
192192
# also Python's library directory must be appended to library_dirs
193-
if os.name == 'nt':
193+
if os.name == 'nt' and not is_mingw():
194194
# the 'libs' directory is for binary installs - we assume that
195195
# must be the *native* platform. But we don't really support
196196
# cross-compiling via a binary install anyway, so we let it go.
@@ -218,14 +218,18 @@ def finalize_options(self): # noqa: C901
218218
new_lib = os.path.join(new_lib, suffix)
219219
self.library_dirs.append(new_lib)
220220

221-
# For extensions under Cygwin, Python's library directory must be
221+
# For extensions under Cygwin and MinGW, Python's library directory must be
222222
# appended to library_dirs
223-
if sys.platform[:6] == 'cygwin':
223+
if sys.platform[:6] == 'cygwin' or is_mingw():
224224
if not sysconfig.python_build:
225+
config_dir_name = os.path.basename(sysconfig.get_config_var('LIBPL'))
225226
# building third party extensions
226227
self.library_dirs.append(
227228
os.path.join(
228-
sys.prefix, "lib", "python" + get_python_version(), "config"
229+
sys.prefix,
230+
"lib",
231+
"python" + get_python_version(),
232+
config_dir_name,
229233
)
230234
)
231235
else:
@@ -741,7 +745,7 @@ def get_libraries(self, ext): # noqa: C901
741745
# pyconfig.h that MSVC groks. The other Windows compilers all seem
742746
# to need it mentioned explicitly, though, so that's what we do.
743747
# Append '_d' to the python import library on debug builds.
744-
if sys.platform == "win32":
748+
if sys.platform == "win32" and not is_mingw():
745749
from .._msvccompiler import MSVCCompiler
746750

747751
if not isinstance(self.compiler, MSVCCompiler):
@@ -771,7 +775,7 @@ def get_libraries(self, ext): # noqa: C901
771775
# A native build on an Android device or on Cygwin
772776
if hasattr(sys, 'getandroidapilevel'):
773777
link_libpython = True
774-
elif sys.platform == 'cygwin':
778+
elif sys.platform == 'cygwin' or is_mingw():
775779
link_libpython = True
776780
elif '_PYTHON_HOST_PLATFORM' in os.environ:
777781
# We are cross-compiling for one of the relevant platforms

distutils/cygwinccompiler.py

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ def get_msvcr():
5757
return ['ucrt', 'vcruntime140']
5858
else:
5959
raise ValueError("Unknown MS Compiler version %s " % msc_ver)
60+
else:
61+
return []
6062

6163

6264
_runtime_library_dirs_msg = (

distutils/sysconfig.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,11 @@ def get_python_inc(plat_specific=0, prefix=None):
120120
"""
121121
default_prefix = BASE_EXEC_PREFIX if plat_specific else BASE_PREFIX
122122
resolved_prefix = prefix if prefix is not None else default_prefix
123+
# MinGW imitates posix like layout, but os.name != posix
124+
os_name = os.name if not sysconfig.get_platform().startswith("mingw") else "posix"
125+
inc_fun = f'_get_python_inc_{os_name}'
123126
try:
124-
getter = globals()[f'_get_python_inc_{os.name}']
127+
getter = globals()[inc_fun]
125128
except KeyError:
126129
raise DistutilsPlatformError(
127130
"I don't know where Python installs its C header files "
@@ -236,7 +239,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
236239
else:
237240
prefix = plat_specific and EXEC_PREFIX or PREFIX
238241

239-
if os.name == "posix":
242+
if os.name == "posix" or sysconfig.get_platform().startswith('mingw'):
240243
if plat_specific or standard_lib:
241244
# Platform-specific modules (any module from a non-pure-Python
242245
# module distribution) or standard Python library modules.
@@ -265,7 +268,7 @@ def customize_compiler(compiler): # noqa: C901
265268
Mainly needed on Unix, so we can plug in the information that
266269
varies across Unices and is stored in Python's Makefile.
267270
"""
268-
if compiler.compiler_type == "unix":
271+
if compiler.compiler_type in ["unix", "cygwin", "mingw32"]:
269272
if sys.platform == "darwin":
270273
# Perform first-time customization of compiler-related
271274
# config vars on OS X now that we know we need a compiler.

distutils/util.py

+9
Original file line numberDiff line numberDiff line change
@@ -511,3 +511,12 @@ def rfc822_escape(header):
511511
lines = header.split('\n')
512512
sep = '\n' + 8 * ' '
513513
return sep.join(lines)
514+
515+
516+
def is_mingw():
517+
"""Returns True if the current platform is mingw.
518+
519+
Python compiled with Mingw-w64 has sys.platform == 'win32' and
520+
get_platform() starts with 'mingw'.
521+
"""
522+
return sys.platform == 'win32' and get_platform().startswith('mingw')

0 commit comments

Comments
 (0)