Skip to content

Commit

Permalink
Merge pull request #117 from isuruf/ccache
Browse files Browse the repository at this point in the history
When building C++ extensions, replace all of linker command
  • Loading branch information
jaraco committed Mar 19, 2022
2 parents b7e7582 + a823eba commit cd61528
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 7 deletions.
37 changes: 37 additions & 0 deletions distutils/tests/test_unixccompiler.py
Expand Up @@ -3,6 +3,7 @@
import sys
import unittest
from test.support import run_unittest
from unittest.mock import patch

from .py38compat import EnvironmentVarGuard

Expand Down Expand Up @@ -214,6 +215,42 @@ def gcvs(*args, _orig=sysconfig.get_config_vars):
sysconfig.customize_compiler(self.cc)
self.assertEqual(self.cc.linker_so[0], 'my_cc')

@unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
def test_cc_overrides_ldshared_for_cxx_correctly(self):
"""
Ensure that setting CC env variable also changes default linker
correctly when building C++ extensions.
pypa/distutils#126
"""
def gcv(v):
if v == 'LDSHARED':
return 'gcc-4.2 -bundle -undefined dynamic_lookup '
elif v == 'CXX':
return 'g++-4.2'
return 'gcc-4.2'

def gcvs(*args, _orig=sysconfig.get_config_vars):
if args:
return list(map(sysconfig.get_config_var, args))
return _orig()

sysconfig.get_config_var = gcv
sysconfig.get_config_vars = gcvs
with patch.object(self.cc, 'spawn', return_value=None) as mock_spawn, \
patch.object(self.cc, '_need_link', return_value=True), \
patch.object(self.cc, 'mkpath', return_value=None), \
EnvironmentVarGuard() as env:
env['CC'] = 'ccache my_cc'
env['CXX'] = 'my_cxx'
del env['LDSHARED']
sysconfig.customize_compiler(self.cc)
self.assertEqual(self.cc.linker_so[0:2], ['ccache', 'my_cc'])
self.cc.link(None, [], 'a.out', target_lang='c++')
call_args = mock_spawn.call_args[0][0]
expected = ['my_cxx', '-bundle', '-undefined', 'dynamic_lookup']
assert call_args[:4] == expected

@unittest.skipIf(sys.platform == 'win32', "can't test on Windows")
def test_explicit_ldshared(self):
# Issue #18080:
Expand Down
44 changes: 37 additions & 7 deletions distutils/unixccompiler.py
Expand Up @@ -72,6 +72,34 @@ def _split_aix(cmd):
return cmd[:pivot], cmd[pivot:]


def _linker_params(linker_cmd, compiler_cmd):
"""
The linker command usually begins with the compiler
command (possibly multiple elements), followed by zero or more
params for shared library building.
If the LDSHARED env variable overrides the linker command,
however, the commands may not match.
Return the best guess of the linker parameters by stripping
the linker command. If the compiler command does not
match the linker command, assume the linker command is
just the first element.
>>> _linker_params('gcc foo bar'.split(), ['gcc'])
['foo', 'bar']
>>> _linker_params('gcc foo bar'.split(), ['other'])
['foo', 'bar']
>>> _linker_params('ccache gcc foo bar'.split(), 'ccache gcc'.split())
['foo', 'bar']
>>> _linker_params(['gcc'], ['gcc'])
[]
"""
c_len = len(compiler_cmd)
pivot = c_len if linker_cmd[:c_len] == compiler_cmd else 1
return linker_cmd[pivot:]


class UnixCCompiler(CCompiler):

compiler_type = 'unix'
Expand Down Expand Up @@ -201,18 +229,20 @@ def link(self, target_desc, objects,
ld_args.extend(extra_postargs)
self.mkpath(os.path.dirname(output_filename))
try:
linker = (
self.linker_exe
if target_desc == CCompiler.EXECUTABLE else
self.linker_so
)[:]
# Select a linker based on context: linker_exe when
# 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)[:]

if target_lang == "c++" and self.compiler_cxx:
env, linker_ne = _split_env(linker)
aix, linker_na = _split_aix(linker_ne)
_, compiler_cxx_ne = _split_env(self.compiler_cxx)
_, linker_exe_ne = _split_env(self.linker_exe)

linker_na[0] = compiler_cxx_ne[0]
linker = env + aix + linker_na
params = _linker_params(linker_na, linker_exe_ne)
linker = env + aix + compiler_cxx_ne + params

linker = compiler_fixup(linker, ld_args)

Expand Down

0 comments on commit cd61528

Please sign in to comment.