summaryrefslogtreecommitdiff
path: root/numpy/distutils/command/build_ext.py
diff options
context:
space:
mode:
authorRalf Gommers <ralf.gommers@gmail.com>2022-01-24 12:30:21 +0100
committerRalf Gommers <ralf.gommers@gmail.com>2022-01-24 12:30:21 +0100
commit1e83f8355336bd722af3ae2608735fa53218ece9 (patch)
tree9cb65fd890d131e7b6a2b4b04797d07fb04711c9 /numpy/distutils/command/build_ext.py
parent6218e76bc590e9253ed8d4c4b18c74aa81332b15 (diff)
downloadnumpy-1e83f8355336bd722af3ae2608735fa53218ece9.tar.gz
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.
Diffstat (limited to 'numpy/distutils/command/build_ext.py')
-rw-r--r--numpy/distutils/command/build_ext.py30
1 files changed, 23 insertions, 7 deletions
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)