From 1e83f8355336bd722af3ae2608735fa53218ece9 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Mon, 24 Jan 2022 12:30:21 +0100 Subject: BUG: distutils: fix building mixed C/Fortran extensions In SciPy we had a couple of cases where we build a Python extension with C source files but linked against static libraries built from Fortran code. Those should be using the Fortran linker, but this was broken in 1.22.0 by gh-19713 (the PR that introduced C++ in NumPy). This fixes a few issues in the `build_ext` command, and documents better what is going on there. Should close SciPy issues 8325 and 15414. --- numpy/distutils/command/build_ext.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'numpy/distutils/command/build_ext.py') diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py index 7040a2411..36a62eb1a 100644 --- a/numpy/distutils/command/build_ext.py +++ b/numpy/distutils/command/build_ext.py @@ -231,20 +231,36 @@ class build_ext (old_build_ext): l = ext.language or self.compiler.detect_language(ext.sources) if l: ext_languages.add(l) + # reset language attribute for choosing proper linker + # + # When we build extensions with multiple languages, we have to + # choose a linker. The rules here are: + # 1. if there is Fortran code, always prefer the Fortran linker, + # 2. otherwise prefer C++ over C, + # 3. Users can force a particular linker by using + # `language='c'` # or 'c++', 'f90', 'f77' + # in their config.add_extension() calls. if 'c++' in ext_languages: ext_language = 'c++' - elif 'f90' in ext_languages: + else: + ext_language = 'c' # default + + has_fortran = False + if 'f90' in ext_languages: ext_language = 'f90' + has_fortran = True elif 'f77' in ext_languages: ext_language = 'f77' - else: - ext_language = 'c' # default - if l and l != ext_language and ext.language: - log.warn('resetting extension %r language from %r to %r.' % - (ext.name, l, ext_language)) - if not ext.language: + has_fortran = True + + if not ext.language or has_fortran: + if l and l != ext_language and ext.language: + log.warn('resetting extension %r language from %r to %r.' % + (ext.name, l, ext_language)) + ext.language = ext_language + # global language all_languages.update(ext_languages) -- cgit v1.2.1