From 2c937116cc0dcd9b26b6070e89a3dc5dcbedc2ae Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Thu, 14 Dec 2023 09:24:14 -0500 Subject: [PATCH 01/13] Distutils C++ support Upstreamed fix from nix, see patch here: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/setuptools/setuptools-distutils-C%2B%2B.patch --- distutils/cygwinccompiler.py | 17 ++++++++++++++--- distutils/sysconfig.py | 20 ++++++++++++++++++-- distutils/unixccompiler.py | 15 ++++++++++++--- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/distutils/cygwinccompiler.py b/distutils/cygwinccompiler.py index b3dbc3be..c683e3ee 100644 --- a/distutils/cygwinccompiler.py +++ b/distutils/cygwinccompiler.py @@ -101,14 +101,19 @@ def __init__(self, verbose=0, dry_run=0, force=0): self.cxx = os.environ.get('CXX', 'g++') self.linker_dll = self.cc + self.linker_dll_cxx = self.cxx shared_option = "-shared" self.set_executables( compiler='%s -mcygwin -O -Wall' % self.cc, compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc, compiler_cxx='%s -mcygwin -O -Wall' % self.cxx, + compiler_so_cxx='%s -mcygwin -mdll -O -Wall' % self.cxx, linker_exe='%s -mcygwin' % self.cc, linker_so=('{} -mcygwin {}'.format(self.linker_dll, shared_option)), + linker_exe_cxx='%s -mcygwin' % self.cxx, + linker_so_cxx=('%s -mcygwin %s' % + (self.linker_dll_cxx, shared_option)), ) # Include the appropriate MSVC runtime library if Python was built @@ -140,9 +145,12 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): raise CompileError(msg) else: # for other files use the C-compiler try: - self.spawn( - self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs - ) + if self.detect_language(src) == 'c++': + self.spawn(self.compiler_so_cxx + cc_args + [src, '-o', obj] + + extra_postargs) + else: + self.spawn( + self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) @@ -278,9 +286,12 @@ def __init__(self, verbose=0, dry_run=0, force=0): self.set_executables( compiler='%s -O -Wall' % self.cc, compiler_so='%s -mdll -O -Wall' % self.cc, + compiler_so_cxx='%s -mdll -O -Wall' % self.cxx, compiler_cxx='%s -O -Wall' % self.cxx, linker_exe='%s' % self.cc, linker_so='{} {}'.format(self.linker_dll, shared_option), + linker_exe_cxx='%s' % self.cxx, + linker_so_cxx='%s %s' % (self.linker_dll_cxx, shared_option) ) def runtime_library_dir_option(self, dir): diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index 5fb811c4..bab4ab69 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -300,6 +300,7 @@ def customize_compiler(compiler): # noqa: C901 cflags, ccshared, ldshared, + ldcxxshared, shlib_suffix, ar, ar_flags, @@ -309,11 +310,14 @@ def customize_compiler(compiler): # noqa: C901 'CFLAGS', 'CCSHARED', 'LDSHARED', + 'LDCXXSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS', ) + cxxflags = cflags + if 'CC' in os.environ: newcc = os.environ['CC'] if 'LDSHARED' not in os.environ and ldshared.startswith(cc): @@ -325,19 +329,27 @@ def customize_compiler(compiler): # noqa: C901 cxx = os.environ['CXX'] if 'LDSHARED' in os.environ: ldshared = os.environ['LDSHARED'] + if 'LDCXXSHARED' in os.environ: + ldcxxshared = os.environ['LDCXXSHARED'] if 'CPP' in os.environ: cpp = os.environ['CPP'] else: cpp = cc + " -E" # not always if 'LDFLAGS' in os.environ: ldshared = ldshared + ' ' + os.environ['LDFLAGS'] + ldcxxshared = ldcxxshared + ' ' + os.environ['LDFLAGS'] if 'CFLAGS' in os.environ: - cflags = cflags + ' ' + os.environ['CFLAGS'] + cflags = os.environ['CFLAGS'] ldshared = ldshared + ' ' + os.environ['CFLAGS'] + if 'CXXFLAGS' in os.environ: + cxxflags = os.environ['CXXFLAGS'] + ldcxxshared = ldcxxshared + ' ' + os.environ['CXXFLAGS'] if 'CPPFLAGS' in os.environ: cpp = cpp + ' ' + os.environ['CPPFLAGS'] cflags = cflags + ' ' + os.environ['CPPFLAGS'] + cxxflags = cxxflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + ldcxxshared = ldcxxshared + ' ' + os.environ['CPPFLAGS'] if 'AR' in os.environ: ar = os.environ['AR'] if 'ARFLAGS' in os.environ: @@ -346,13 +358,17 @@ def customize_compiler(compiler): # noqa: C901 archiver = ar + ' ' + ar_flags cc_cmd = cc + ' ' + cflags + cxx_cmd = cxx + ' ' + cxxflags compiler.set_executables( preprocessor=cpp, compiler=cc_cmd, compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, + compiler_cxx=cxx_cmd, + compiler_so_cxx=cxx_cmd + ' ' + ccshared, linker_so=ldshared, + linker_so_cxx=ldcxxshared, linker_exe=cc, + linker_exe_cxx=cxx, archiver=archiver, ) diff --git a/distutils/unixccompiler.py b/distutils/unixccompiler.py index d749fe25..0919868a 100644 --- a/distutils/unixccompiler.py +++ b/distutils/unixccompiler.py @@ -115,9 +115,12 @@ class UnixCCompiler(CCompiler): 'preprocessor': None, 'compiler': ["cc"], 'compiler_so': ["cc"], - 'compiler_cxx': ["cc"], + 'compiler_cxx': ["c++"], + 'compiler_so_cxx': ["c++"], 'linker_so': ["cc", "-shared"], + 'linker_so_cxx': ["c++", "-shared"], 'linker_exe': ["cc"], + 'linker_exe_cxx': ["c++", "-shared"], 'archiver': ["ar", "-cr"], 'ranlib': None, } @@ -181,8 +184,13 @@ def preprocess( def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = compiler_fixup(self.compiler_so, cc_args + extra_postargs) + compiler_so_cxx = compiler_fixup(self.compiler_so_cxx, cc_args + extra_postargs) try: - self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) + if self.detect_language(src) == 'c++': + self.spawn(compiler_so_cxx + cc_args + [ src, '-o', obj] + + extra_postargs) + else: + self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) @@ -250,7 +258,8 @@ def link( # building an executable or linker_so (with shared options) # when building a shared library. building_exe = target_desc == CCompiler.EXECUTABLE - linker = (self.linker_exe if building_exe else self.linker_so)[:] + linker = (self.linker_exe if building_exe else (self.linker_so_cxx if + target_lang == "c++" else self.linker_so))[:] if target_lang == "c++" and self.compiler_cxx: env, linker_ne = _split_env(linker) From 26f4723dbcbc32f44be33e849eca86f15317612a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Feb 2024 13:29:18 -0500 Subject: [PATCH 02/13] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20?= =?UTF-8?q?(delint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distutils/cygwinccompiler.py | 16 ++++++++++------ distutils/unixccompiler.py | 14 ++++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/distutils/cygwinccompiler.py b/distutils/cygwinccompiler.py index c683e3ee..d767c6d3 100644 --- a/distutils/cygwinccompiler.py +++ b/distutils/cygwinccompiler.py @@ -112,8 +112,7 @@ def __init__(self, verbose=0, dry_run=0, force=0): linker_exe='%s -mcygwin' % self.cc, linker_so=('{} -mcygwin {}'.format(self.linker_dll, shared_option)), linker_exe_cxx='%s -mcygwin' % self.cxx, - linker_so_cxx=('%s -mcygwin %s' % - (self.linker_dll_cxx, shared_option)), + linker_so_cxx=('%s -mcygwin %s' % (self.linker_dll_cxx, shared_option)), ) # Include the appropriate MSVC runtime library if Python was built @@ -146,11 +145,16 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): else: # for other files use the C-compiler try: if self.detect_language(src) == 'c++': - self.spawn(self.compiler_so_cxx + cc_args + [src, '-o', obj] + - extra_postargs) + self.spawn( + self.compiler_so_cxx + + cc_args + + [src, '-o', obj] + + extra_postargs + ) else: self.spawn( - self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs) + self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs + ) except DistutilsExecError as msg: raise CompileError(msg) @@ -291,7 +295,7 @@ def __init__(self, verbose=0, dry_run=0, force=0): linker_exe='%s' % self.cc, linker_so='{} {}'.format(self.linker_dll, shared_option), linker_exe_cxx='%s' % self.cxx, - linker_so_cxx='%s %s' % (self.linker_dll_cxx, shared_option) + linker_so_cxx='%s %s' % (self.linker_dll_cxx, shared_option), ) def runtime_library_dir_option(self, dir): diff --git a/distutils/unixccompiler.py b/distutils/unixccompiler.py index 0919868a..2b1bbace 100644 --- a/distutils/unixccompiler.py +++ b/distutils/unixccompiler.py @@ -187,8 +187,9 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so_cxx = compiler_fixup(self.compiler_so_cxx, cc_args + extra_postargs) try: if self.detect_language(src) == 'c++': - self.spawn(compiler_so_cxx + cc_args + [ src, '-o', obj] + - extra_postargs) + self.spawn( + compiler_so_cxx + cc_args + [src, '-o', obj] + extra_postargs + ) else: self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: @@ -258,8 +259,13 @@ def link( # building an executable or linker_so (with shared options) # when building a shared library. building_exe = target_desc == CCompiler.EXECUTABLE - linker = (self.linker_exe if building_exe else (self.linker_so_cxx if - target_lang == "c++" else self.linker_so))[:] + linker = ( + self.linker_exe + if building_exe + else ( + self.linker_so_cxx if target_lang == "c++" else self.linker_so + ) + )[:] if target_lang == "c++" and self.compiler_cxx: env, linker_ne = _split_env(linker) From fbac766736c5a3807968ec4ad9f5a0ca9b96a458 Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Tue, 13 Feb 2024 19:33:55 -0500 Subject: [PATCH 03/13] Adjust tests further to accommodate C++ support. --- distutils/sysconfig.py | 2 +- distutils/tests/test_sysconfig.py | 4 ++-- distutils/tests/test_unixccompiler.py | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index bab4ab69..ab80e821 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -339,7 +339,7 @@ def customize_compiler(compiler): # noqa: C901 ldshared = ldshared + ' ' + os.environ['LDFLAGS'] ldcxxshared = ldcxxshared + ' ' + os.environ['LDFLAGS'] if 'CFLAGS' in os.environ: - cflags = os.environ['CFLAGS'] + cflags = cflags + ' ' + os.environ['CFLAGS'] ldshared = ldshared + ' ' + os.environ['CFLAGS'] if 'CXXFLAGS' in os.environ: cxxflags = os.environ['CXXFLAGS'] diff --git a/distutils/tests/test_sysconfig.py b/distutils/tests/test_sysconfig.py index f656be60..4879d720 100644 --- a/distutils/tests/test_sysconfig.py +++ b/distutils/tests/test_sysconfig.py @@ -132,7 +132,7 @@ def test_customize_compiler(self): assert comp.exes['compiler_so'] == ( 'env_cc --sc-cflags ' '--env-cflags ' '--env-cppflags --sc-ccshared' ) - assert comp.exes['compiler_cxx'] == 'env_cxx --env-cxx-flags' + assert comp.exes['compiler_cxx'] == 'env_cxx --env-cxx-flags --sc-cflags --env-cppflags' assert comp.exes['linker_exe'] == 'env_cc' assert comp.exes['linker_so'] == ( 'env_ldshared --env-ldflags --env-cflags' ' --env-cppflags' @@ -160,7 +160,7 @@ def test_customize_compiler(self): assert comp.exes['preprocessor'] == 'sc_cc -E' assert comp.exes['compiler'] == 'sc_cc --sc-cflags' assert comp.exes['compiler_so'] == 'sc_cc --sc-cflags --sc-ccshared' - assert comp.exes['compiler_cxx'] == 'sc_cxx' + assert comp.exes['compiler_cxx'] == 'sc_cxx --sc-cflags' assert comp.exes['linker_exe'] == 'sc_cc' assert comp.exes['linker_so'] == 'sc_ldshared' assert comp.shared_lib_extension == 'sc_shutil_suffix' diff --git a/distutils/tests/test_unixccompiler.py b/distutils/tests/test_unixccompiler.py index 2763db9c..ad08a173 100644 --- a/distutils/tests/test_unixccompiler.py +++ b/distutils/tests/test_unixccompiler.py @@ -260,9 +260,13 @@ def test_cc_overrides_ldshared_for_cxx_correctly(self): def gcv(v): if v == 'LDSHARED': return 'gcc-4.2 -bundle -undefined dynamic_lookup ' + elif v == 'LDCXXSHARED': + return 'g++-4.2 -bundle -undefined dynamic_lookup ' elif v == 'CXX': return 'g++-4.2' - return 'gcc-4.2' + elif v == 'CC': + return 'gcc-4.2' + return '' def gcvs(*args, _orig=sysconfig.get_config_vars): if args: From 9f176ac9ea2688e05aa4cb50a75da9bebf7e174a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Feb 2024 19:39:55 -0500 Subject: [PATCH 04/13] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20?= =?UTF-8?q?(delint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- distutils/tests/test_sysconfig.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/distutils/tests/test_sysconfig.py b/distutils/tests/test_sysconfig.py index 4879d720..60a4ba30 100644 --- a/distutils/tests/test_sysconfig.py +++ b/distutils/tests/test_sysconfig.py @@ -132,7 +132,10 @@ def test_customize_compiler(self): assert comp.exes['compiler_so'] == ( 'env_cc --sc-cflags ' '--env-cflags ' '--env-cppflags --sc-ccshared' ) - assert comp.exes['compiler_cxx'] == 'env_cxx --env-cxx-flags --sc-cflags --env-cppflags' + assert ( + comp.exes['compiler_cxx'] + == 'env_cxx --env-cxx-flags --sc-cflags --env-cppflags' + ) assert comp.exes['linker_exe'] == 'env_cc' assert comp.exes['linker_so'] == ( 'env_ldshared --env-ldflags --env-cflags' ' --env-cppflags' From 51749270038f117f8f3103523bb37fd73bb4fe29 Mon Sep 17 00:00:00 2001 From: Samuel Cormier-Iijima Date: Fri, 1 Mar 2024 22:16:58 -0500 Subject: [PATCH 05/13] Ignore sysconfig variables for LDCXXSHARED as it appears not to exist on PyPy. --- distutils/sysconfig.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index ab80e821..3c729893 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -300,7 +300,6 @@ def customize_compiler(compiler): # noqa: C901 cflags, ccshared, ldshared, - ldcxxshared, shlib_suffix, ar, ar_flags, @@ -310,13 +309,13 @@ def customize_compiler(compiler): # noqa: C901 'CFLAGS', 'CCSHARED', 'LDSHARED', - 'LDCXXSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS', ) cxxflags = cflags + ldcxxshared = "" if 'CC' in os.environ: newcc = os.environ['CC'] From a04913a51327c64f807e85119fd750485bbceb0a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 13:33:48 -0400 Subject: [PATCH 06/13] Add type declaration for runtime_library_dir_option, making explicit the different return types one might expect. --- distutils/unixccompiler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/distutils/unixccompiler.py b/distutils/unixccompiler.py index caf4cd33..a54481c0 100644 --- a/distutils/unixccompiler.py +++ b/distutils/unixccompiler.py @@ -13,6 +13,8 @@ * link shared library handled by 'cc -shared' """ +from __future__ import annotations + import itertools import os import re @@ -281,7 +283,7 @@ def _is_gcc(self): compiler = os.path.basename(shlex.split(cc_var)[0]) return "gcc" in compiler or "g++" in compiler - def runtime_library_dir_option(self, dir): + def runtime_library_dir_option(self, dir: str) -> str | list[str]: # XXX Hackish, at the very least. See Python bug #445902: # https://bugs.python.org/issue445902 # Linkers on different platforms need different options to From d2581bf30b6cfaa64f8b570b368a6f4ed5a710ff Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 13:47:03 -0400 Subject: [PATCH 07/13] Add 'consolidate_linker_args' wrapper to protect the old behavior for now. Closes pypa/distutils#246. --- distutils/compat/__init__.py | 15 +++++++++++++++ distutils/compat/py38.py | 23 +++++++++++++++++++++++ distutils/tests/test_unixccompiler.py | 17 +++++++++-------- distutils/unixccompiler.py | 5 +++-- 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 distutils/compat/__init__.py create mode 100644 distutils/compat/py38.py diff --git a/distutils/compat/__init__.py b/distutils/compat/__init__.py new file mode 100644 index 00000000..b7be7267 --- /dev/null +++ b/distutils/compat/__init__.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from .py38 import removeprefix + + +def consolidate_linker_args(args: list[str]) -> str: + """ + Ensure the return value is a string for backward compatibility. + + Retain until at least 2024-10-31. + """ + + if not all(arg.startswith('-Wl,') for arg in args): + return args + return '-Wl,' + ','.join(removeprefix(arg, '-Wl,') for arg in args) diff --git a/distutils/compat/py38.py b/distutils/compat/py38.py new file mode 100644 index 00000000..0af38140 --- /dev/null +++ b/distutils/compat/py38.py @@ -0,0 +1,23 @@ +import sys + +if sys.version_info < (3, 9): + + def removesuffix(self, suffix): + # suffix='' should not call self[:-0]. + if suffix and self.endswith(suffix): + return self[: -len(suffix)] + else: + return self[:] + + def removeprefix(self, prefix): + if self.startswith(prefix): + return self[len(prefix) :] + else: + return self[:] +else: + + def removesuffix(self, suffix): + return self.removesuffix(suffix) + + def removeprefix(self, prefix): + return self.removeprefix(prefix) diff --git a/distutils/tests/test_unixccompiler.py b/distutils/tests/test_unixccompiler.py index f17edf2f..6f05fa69 100644 --- a/distutils/tests/test_unixccompiler.py +++ b/distutils/tests/test_unixccompiler.py @@ -4,6 +4,7 @@ import sys import unittest.mock as mock from distutils import sysconfig +from distutils.compat import consolidate_linker_args from distutils.errors import DistutilsPlatformError from distutils.unixccompiler import UnixCCompiler from distutils.util import _clear_cached_macosx_ver @@ -149,10 +150,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) def gcv(v): if v == 'CC': @@ -161,10 +162,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) # GCC non-GNULD sys.platform = 'bar' @@ -189,10 +190,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) # non-GCC GNULD sys.platform = 'bar' @@ -204,10 +205,10 @@ def gcv(v): return 'yes' sysconfig.get_config_var = gcv - assert self.cc.rpath_foo() == [ + assert self.cc.rpath_foo() == consolidate_linker_args([ '-Wl,--enable-new-dtags', '-Wl,-rpath,/foo', - ] + ]) # non-GCC non-GNULD sys.platform = 'bar' diff --git a/distutils/unixccompiler.py b/distutils/unixccompiler.py index a54481c0..0248bde8 100644 --- a/distutils/unixccompiler.py +++ b/distutils/unixccompiler.py @@ -22,6 +22,7 @@ import sys from . import sysconfig +from .compat import consolidate_linker_args from ._log import log from ._macos_compat import compiler_fixup from ._modified import newer @@ -315,11 +316,11 @@ def runtime_library_dir_option(self, dir: str) -> str | list[str]: # For all compilers, `-Wl` is the presumed way to pass a # compiler option to the linker if sysconfig.get_config_var("GNULD") == "yes": - return [ + return consolidate_linker_args([ # Force RUNPATH instead of RPATH "-Wl,--enable-new-dtags", "-Wl,-rpath," + dir, - ] + ]) else: return "-Wl,-R" + dir From 98eee7f74c93fb84226d18f370f883956e644619 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 14:03:03 -0400 Subject: [PATCH 08/13] Exclude compat package from coverage. --- .coveragerc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.coveragerc b/.coveragerc index 35b98b1d..bcef31d9 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,6 +2,9 @@ omit = # leading `*/` for pytest-dev/pytest-cov#456 */.tox/* + + # local + */compat/* disable_warnings = couldnt-parse From ef297f26182823d54acfe3719416aa2661706b29 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Apr 2024 16:40:21 -0400 Subject: [PATCH 09/13] Extend the retention of the compatibility. --- distutils/compat/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/compat/__init__.py b/distutils/compat/__init__.py index b7be7267..b1ee3fe8 100644 --- a/distutils/compat/__init__.py +++ b/distutils/compat/__init__.py @@ -7,7 +7,7 @@ def consolidate_linker_args(args: list[str]) -> str: """ Ensure the return value is a string for backward compatibility. - Retain until at least 2024-10-31. + Retain until at least 2024-04-31. See pypa/distutils#246 """ if not all(arg.startswith('-Wl,') for arg in args): From 95088c5886327cca5c01426cc9ea0d1063677f26 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 1 Aug 2024 21:07:41 -0400 Subject: [PATCH 10/13] Harmonize '-shared' parameter for C and C++ in Mingw32CCompiler --- distutils/cygwinccompiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/cygwinccompiler.py b/distutils/cygwinccompiler.py index f0704ee7..10a0f7a8 100644 --- a/distutils/cygwinccompiler.py +++ b/distutils/cygwinccompiler.py @@ -288,7 +288,7 @@ def __init__(self, verbose=False, dry_run=False, force=False): self.set_executables( compiler=f'{self.cc} -O -Wall', compiler_so=f'{self.cc} -shared -O -Wall', - compiler_so_cxx=f'{self.cxx} -mdll -O -Wall', + compiler_so_cxx=f'{self.cxx} -shared -O -Wall', compiler_cxx=f'{self.cxx} -O -Wall', linker_exe=f'{self.cc}', linker_so=f'{self.linker_dll} {shared_option}', From edc380824b28facc37a12722b1ba52377aef4336 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 1 Aug 2024 21:37:36 -0400 Subject: [PATCH 11/13] In sysconfig.customize_compiler, initialize ldcxxshared from config vars. --- distutils/sysconfig.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index 31bdbec1..847a26ba 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -304,6 +304,7 @@ def customize_compiler(compiler): # noqa: C901 cflags, ccshared, ldshared, + ldcxxshared, shlib_suffix, ar, ar_flags, @@ -313,13 +314,13 @@ def customize_compiler(compiler): # noqa: C901 'CFLAGS', 'CCSHARED', 'LDSHARED', + 'LDCXXSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS', ) cxxflags = cflags - ldcxxshared = "" if 'CC' in os.environ: newcc = os.environ['CC'] From 3e4b457a2eb451b97de26bc6cc1d12153ebb8dce Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 2 Aug 2024 10:23:15 -0400 Subject: [PATCH 12/13] Refactored customize_compiler to reduce logical branches and extract _add_flags logic. Reduces cyclomatic complexity so it passes QA checks. --- distutils/sysconfig.py | 66 ++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index 847a26ba..8929deab 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -287,7 +287,7 @@ def _customize_macos(): ) -def customize_compiler(compiler): # noqa: C901 +def customize_compiler(compiler): """Do any platform-specific customization of a CCompiler instance. Mainly needed on Unix, so we can plug in the information that @@ -329,40 +329,32 @@ def customize_compiler(compiler): # noqa: C901 # command for LDSHARED as well ldshared = newcc + ldshared[len(cc) :] cc = newcc - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'LDCXXSHARED' in os.environ: - ldcxxshared = os.environ['LDCXXSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - ldcxxshared = ldcxxshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = cflags + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CXXFLAGS' in os.environ: - cxxflags = os.environ['CXXFLAGS'] - ldcxxshared = ldcxxshared + ' ' + os.environ['CXXFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - cxxflags = cxxflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - ldcxxshared = ldcxxshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags + cxx = os.environ.get('CXX', cxx) + ldshared = os.environ.get('LDSHARED', ldshared) + ldcxxshared = os.environ.get('LDCXXSHARED', ldcxxshared) + cpp = os.environ.get( + 'CPP', + cc + " -E", # not always + ) + ldshared = _add_flags(ldshared, 'LD') + ldcxxshared = _add_flags(ldcxxshared, 'LD') + cflags = _add_flags(cflags, 'C') + ldshared = _add_flags(ldshared, 'C') + cxxflags = os.environ.get('CXXFLAGS', cxxflags) + ldcxxshared = _add_flags(ldcxxshared, 'CXX') + cpp = _add_flags(cpp, 'CPP') + cflags = _add_flags(cflags, 'CPP') + cxxflags = _add_flags(cxxflags, 'CPP') + ldshared = _add_flags(ldshared, 'CPP') + ldcxxshared = _add_flags(ldcxxshared, 'CPP') + + ar = os.environ.get('AR', ar) + + archiver = ar + ' ' + os.environ.get('ARFLAGS', ar_flags) cc_cmd = cc + ' ' + cflags cxx_cmd = cxx + ' ' + cxxflags + compiler.set_executables( preprocessor=cpp, compiler=cc_cmd, @@ -577,3 +569,13 @@ def get_config_var(name): warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) return get_config_vars().get(name) + + +def _add_flags(value: str, type: str) -> str: + """ + Add any flags from the environment for the given type. + + type is the prefix to FLAGS in the environment key (e.g. "C" for "CFLAGS"). + """ + flags = os.environ.get(f'{type}FLAGS') + return f'{value} {flags}' if flags else value From fcef96367a0aef5bcf58027553ca36d50805210c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 2 Aug 2024 10:27:14 -0400 Subject: [PATCH 13/13] Don't add flags when the value is None, such as when on PyPy, LDCXXSHARED is unset. --- distutils/sysconfig.py | 1 + 1 file changed, 1 insertion(+) diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py index 8929deab..fbdd5d73 100644 --- a/distutils/sysconfig.py +++ b/distutils/sysconfig.py @@ -571,6 +571,7 @@ def get_config_var(name): return get_config_vars().get(name) +@pass_none def _add_flags(value: str, type: str) -> str: """ Add any flags from the environment for the given type.