Find appropriate C compiler for extension module builds
(_config_vars)
| 197 | |
| 198 | |
| 199 | def _find_appropriate_compiler(_config_vars): |
| 200 | """Find appropriate C compiler for extension module builds""" |
| 201 | |
| 202 | # Issue #13590: |
| 203 | # The OSX location for the compiler varies between OSX |
| 204 | # (or rather Xcode) releases. With older releases (up-to 10.5) |
| 205 | # the compiler is in /usr/bin, with newer releases the compiler |
| 206 | # can only be found inside Xcode.app if the "Command Line Tools" |
| 207 | # are not installed. |
| 208 | # |
| 209 | # Furthermore, the compiler that can be used varies between |
| 210 | # Xcode releases. Up to Xcode 4 it was possible to use 'gcc-4.2' |
| 211 | # as the compiler, after that 'clang' should be used because |
| 212 | # gcc-4.2 is either not present, or a copy of 'llvm-gcc' that |
| 213 | # miscompiles Python. |
| 214 | |
| 215 | # skip checks if the compiler was overridden with a CC env variable |
| 216 | if 'CC' in os.environ: |
| 217 | return _config_vars |
| 218 | |
| 219 | # The CC config var might contain additional arguments. |
| 220 | # Ignore them while searching. |
| 221 | cc = oldcc = _config_vars['CC'].split()[0] |
| 222 | if not _find_executable(cc): |
| 223 | # Compiler is not found on the shell search PATH. |
| 224 | # Now search for clang, first on PATH (if the Command LIne |
| 225 | # Tools have been installed in / or if the user has provided |
| 226 | # another location via CC). If not found, try using xcrun |
| 227 | # to find an uninstalled clang (within a selected Xcode). |
| 228 | |
| 229 | # NOTE: Cannot use subprocess here because of bootstrap |
| 230 | # issues when building Python itself (and os.popen is |
| 231 | # implemented on top of subprocess and is therefore not |
| 232 | # usable as well) |
| 233 | |
| 234 | cc = _find_build_tool('clang') |
| 235 | |
| 236 | elif os.path.basename(cc).startswith('gcc'): |
| 237 | # Compiler is GCC, check if it is LLVM-GCC |
| 238 | data = _read_output("'%s' --version" |
| 239 | % (cc.replace("'", "'\"'\"'"),)) |
| 240 | if data and 'llvm-gcc' in data: |
| 241 | # Found LLVM-GCC, fall back to clang |
| 242 | cc = _find_build_tool('clang') |
| 243 | |
| 244 | if not cc: |
| 245 | raise SystemError( |
| 246 | "Cannot locate working compiler") |
| 247 | |
| 248 | if cc != oldcc: |
| 249 | # Found a replacement compiler. |
| 250 | # Modify config vars using new compiler, if not already explicitly |
| 251 | # overridden by an env variable, preserving additional arguments. |
| 252 | for cv in _COMPILER_CONFIG_VARS: |
| 253 | if cv in _config_vars and cv not in os.environ: |
| 254 | cv_split = _config_vars[cv].split() |
| 255 | cv_split[0] = cc if cv != 'CXX' else cc + '++' |
| 256 | _save_modified_value(_config_vars, cv, ' '.join(cv_split)) |
no test coverage detected
searching dependent graphs…