Skip to content

Distutils C++ support #228

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

Merged
merged 18 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
2c93711
Distutils C++ support
sciyoshi Dec 14, 2023
26f4723
👹 Feed the hobgoblins (delint).
jaraco Feb 13, 2024
fbac766
Adjust tests further to accommodate C++ support.
sciyoshi Feb 14, 2024
9f176ac
👹 Feed the hobgoblins (delint).
jaraco Feb 14, 2024
5174927
Ignore sysconfig variables for LDCXXSHARED as it appears not to exist…
sciyoshi Mar 2, 2024
678e38a
Merge pull request #245 from DimitriPapadopoulos/FURB
jaraco Apr 13, 2024
a04913a
Add type declaration for runtime_library_dir_option, making explicit …
jaraco Apr 13, 2024
d2581bf
Add 'consolidate_linker_args' wrapper to protect the old behavior for…
jaraco Apr 13, 2024
98eee7f
Exclude compat package from coverage.
jaraco Apr 13, 2024
ef297f2
Extend the retention of the compatibility.
jaraco Apr 13, 2024
e5e3cc1
Merge pull request #247 from pypa/hotfix/246-linker-args-list
jaraco Apr 13, 2024
53c82a2
Merge pull request #239 from DimitriPapadopoulos/extra_pairs_of_quotes
jaraco Apr 14, 2024
45740e0
Merge branch 'main' into feature/cpp-support
jaraco Apr 14, 2024
93ab2a5
Merge branch 'main' into feature/cpp-support
jaraco Aug 2, 2024
95088c5
Harmonize '-shared' parameter for C and C++ in Mingw32CCompiler
jaraco Aug 2, 2024
edc3808
In sysconfig.customize_compiler, initialize ldcxxshared from config v…
jaraco Aug 2, 2024
3e4b457
Refactored customize_compiler to reduce logical branches and extract …
jaraco Aug 2, 2024
fcef963
Don't add flags when the value is None, such as when on PyPy, LDCXXSH…
jaraco Aug 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions distutils/cygwinccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,18 @@ def __init__(self, verbose=False, dry_run=False, force=False):
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=f'{self.cc} -mcygwin -O -Wall',
compiler_so=f'{self.cc} -mcygwin -mdll -O -Wall',
compiler_cxx=f'{self.cxx} -mcygwin -O -Wall',
compiler_so_cxx=f'{self.cxx} -mcygwin -mdll -O -Wall',
linker_exe=f'{self.cc} -mcygwin',
linker_so=(f'{self.linker_dll} -mcygwin {shared_option}'),
linker_so=f'{self.linker_dll} -mcygwin {shared_option}',
linker_exe_cxx=f'{self.cxx} -mcygwin',
linker_so_cxx=f'{self.linker_dll_cxx} -mcygwin {shared_option}',
)

# Include the appropriate MSVC runtime library if Python was built
Expand Down Expand Up @@ -138,9 +142,17 @@ 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)

Expand Down Expand Up @@ -276,9 +288,12 @@ 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} -shared -O -Wall',
compiler_cxx=f'{self.cxx} -O -Wall',
linker_exe=f'{self.cc}',
linker_so=f'{self.linker_dll} {shared_option}',
linker_exe_cxx=f'{self.cxx}',
linker_so_cxx=f'{self.linker_dll_cxx} {shared_option}',
)

def runtime_library_dir_option(self, dir):
Expand Down
69 changes: 44 additions & 25 deletions distutils/sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -304,6 +304,7 @@ def customize_compiler(compiler): # noqa: C901
cflags,
ccshared,
ldshared,
ldcxxshared,
shlib_suffix,
ar,
ar_flags,
Expand All @@ -313,50 +314,57 @@ 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):
# If CC is overridden, use that as the default
# 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 'CPP' in os.environ:
cpp = os.environ['CPP']
else:
cpp = cc + " -E" # not always
if 'LDFLAGS' in os.environ:
ldshared = ldshared + ' ' + os.environ['LDFLAGS']
if 'CFLAGS' in os.environ:
cflags = cflags + ' ' + os.environ['CFLAGS']
ldshared = ldshared + ' ' + os.environ['CFLAGS']
if 'CPPFLAGS' in os.environ:
cpp = cpp + ' ' + os.environ['CPPFLAGS']
cflags = cflags + ' ' + os.environ['CPPFLAGS']
ldshared = ldshared + ' ' + 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,
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,
)

Expand Down Expand Up @@ -561,3 +569,14 @@ def get_config_var(name):

warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2)
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.

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
7 changes: 5 additions & 2 deletions distutils/tests/test_sysconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,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'
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'
Expand Down Expand Up @@ -162,7 +165,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'
Expand Down
6 changes: 5 additions & 1 deletion distutils/tests/test_unixccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,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:
Expand Down
21 changes: 18 additions & 3 deletions distutils/unixccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,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,
}
Expand Down Expand Up @@ -187,8 +190,14 @@ 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)

Expand Down Expand Up @@ -256,7 +265,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)[:]
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)
Expand Down
Loading