Skip to content

Commit

Permalink
Add support for building extensions using MinGW compilers
Browse files Browse the repository at this point in the history
  • Loading branch information
naveen521kk committed Oct 8, 2022
1 parent 45295fc commit fc6ed05
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 11 deletions.
6 changes: 5 additions & 1 deletion distutils/ccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from .file_util import move_file
from .dir_util import mkpath
from .dep_util import newer_group
from .util import split_quoted, execute
from .util import split_quoted, execute, is_mingw
from . import log


Expand Down Expand Up @@ -1042,6 +1042,10 @@ def get_default_compiler(osname=None, platform=None):
osname = os.name
if platform is None:
platform = sys.platform
# Mingw is a special case where sys.platform is 'win32' but we
# want to use the 'mingw32' compiler, so check it first
if is_mingw():
return 'mingw32'
for pattern, compiler in _default_compilers:
if (
re.match(pattern, platform) is not None
Expand Down
18 changes: 11 additions & 7 deletions distutils/command/build_ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from ..sysconfig import get_config_h_filename
from ..dep_util import newer_group
from ..extension import Extension
from ..util import get_platform
from ..util import get_platform, is_mingw
from distutils import log
from . import py37compat

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

# For extensions under Cygwin, Python's library directory must be
# For extensions under Cygwin and MinGW, Python's library directory must be
# appended to library_dirs
if sys.platform[:6] == 'cygwin':
if sys.platform[:6] == 'cygwin' or is_mingw():
if not sysconfig.python_build:
config_dir_name = os.path.basename(sysconfig.get_config_var('LIBPL'))
# building third party extensions
self.library_dirs.append(
os.path.join(
sys.prefix, "lib", "python" + get_python_version(), "config"
sys.prefix,
"lib",
"python" + get_python_version(),
config_dir_name,
)
)
else:
Expand Down Expand Up @@ -741,7 +745,7 @@ def get_libraries(self, ext): # noqa: C901
# pyconfig.h that MSVC groks. The other Windows compilers all seem
# to need it mentioned explicitly, though, so that's what we do.
# Append '_d' to the python import library on debug builds.
if sys.platform == "win32":
if sys.platform == "win32" and not is_mingw():
from .._msvccompiler import MSVCCompiler

if not isinstance(self.compiler, MSVCCompiler):
Expand Down Expand Up @@ -771,7 +775,7 @@ def get_libraries(self, ext): # noqa: C901
# A native build on an Android device or on Cygwin
if hasattr(sys, 'getandroidapilevel'):
link_libpython = True
elif sys.platform == 'cygwin':
elif sys.platform == 'cygwin' or is_mingw():
link_libpython = True
elif '_PYTHON_HOST_PLATFORM' in os.environ:
# We are cross-compiling for one of the relevant platforms
Expand Down
2 changes: 2 additions & 0 deletions distutils/cygwinccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ def get_msvcr():
return ['ucrt', 'vcruntime140']
else:
raise ValueError("Unknown MS Compiler version %s " % msc_ver)
else:
return []


_runtime_library_dirs_msg = (
Expand Down
9 changes: 6 additions & 3 deletions distutils/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,11 @@ def get_python_inc(plat_specific=0, prefix=None):
"""
default_prefix = BASE_EXEC_PREFIX if plat_specific else BASE_PREFIX
resolved_prefix = prefix if prefix is not None else default_prefix
# MinGW imitates posix like layout, but os.name != posix
os_name = os.name if not sysconfig.get_platform().startswith("mingw") else "posix"
inc_fun = f'_get_python_inc_{os_name}'
try:
getter = globals()[f'_get_python_inc_{os.name}']
getter = globals()[inc_fun]
except KeyError:
raise DistutilsPlatformError(
"I don't know where Python installs its C header files "
Expand Down Expand Up @@ -236,7 +239,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
else:
prefix = plat_specific and EXEC_PREFIX or PREFIX

if os.name == "posix":
if os.name == "posix" or sysconfig.get_platform().startswith('mingw'):
if plat_specific or standard_lib:
# Platform-specific modules (any module from a non-pure-Python
# module distribution) or standard Python library modules.
Expand Down Expand Up @@ -265,7 +268,7 @@ def customize_compiler(compiler): # noqa: C901
Mainly needed on Unix, so we can plug in the information that
varies across Unices and is stored in Python's Makefile.
"""
if compiler.compiler_type == "unix":
if compiler.compiler_type in ["unix", "cygwin", "mingw32"]:
if sys.platform == "darwin":
# Perform first-time customization of compiler-related
# config vars on OS X now that we know we need a compiler.
Expand Down
9 changes: 9 additions & 0 deletions distutils/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,12 @@ def rfc822_escape(header):
lines = header.split('\n')
sep = '\n' + 8 * ' '
return sep.join(lines)


def is_mingw():
"""Returns True if the current platform is mingw.
Python compiled with Mingw-w64 has sys.platform == 'win32' and
get_platform() starts with 'mingw'.
"""
return sys.platform == 'win32' and get_platform().startswith('mingw')

0 comments on commit fc6ed05

Please sign in to comment.