summaryrefslogtreecommitdiff
path: root/numpy/distutils
diff options
context:
space:
mode:
authorDeveloper-Ecosystem-Engineering <65677710+Developer-Ecosystem-Engineering@users.noreply.github.com>2021-11-18 14:31:58 -0800
committerGitHub <noreply@github.com>2021-11-18 14:31:58 -0800
commit5e9ce0c0529e3085498ac892941a020a65c7369a (patch)
treea70d9e941549b4a51b493f1b170ef33ce0d5a217 /numpy/distutils
parent2ff7ab64d4e7d5928e96ca95b85350aa9caa2b63 (diff)
parent056abda14dab7fa8daf7a1ab44144aeb2250c216 (diff)
downloadnumpy-5e9ce0c0529e3085498ac892941a020a65c7369a.tar.gz
Merge branch 'numpy:main' into as_min_max
Diffstat (limited to 'numpy/distutils')
-rw-r--r--numpy/distutils/ccompiler.py17
-rw-r--r--numpy/distutils/ccompiler_opt.py32
-rw-r--r--numpy/distutils/checks/cpu_asimdfhm.c4
-rw-r--r--numpy/distutils/command/build_clib.py79
-rw-r--r--numpy/distutils/command/build_ext.py57
-rw-r--r--numpy/distutils/extension.py4
-rw-r--r--numpy/distutils/log.py22
-rw-r--r--numpy/distutils/mingw32ccompiler.py98
-rw-r--r--numpy/distutils/misc_util.py15
-rw-r--r--numpy/distutils/tests/test_ccompiler_opt.py6
-rw-r--r--numpy/distutils/tests/test_log.py32
-rw-r--r--numpy/distutils/tests/test_system_info.py4
-rw-r--r--numpy/distutils/unixccompiler.py13
13 files changed, 233 insertions, 150 deletions
diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py
index 4495c8fee..713b8c72f 100644
--- a/numpy/distutils/ccompiler.py
+++ b/numpy/distutils/ccompiler.py
@@ -23,7 +23,8 @@ from numpy.distutils.exec_command import (
)
from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32, \
get_num_build_jobs, \
- _commandline_dep_string
+ _commandline_dep_string, \
+ sanitize_cxx_flags
# globals for parallel build management
import threading
@@ -143,12 +144,18 @@ def CCompiler_spawn(self, cmd, display=None):
except subprocess.CalledProcessError as exc:
o = exc.output
s = exc.returncode
- except OSError:
+ except OSError as e:
# OSError doesn't have the same hooks for the exception
# output, but exec_command() historically would use an
# empty string for EnvironmentError (base class for
# OSError)
- o = b''
+ # o = b''
+ # still that would make the end-user lost in translation!
+ o = f"\n\n{e}\n\n\n"
+ try:
+ o = o.encode(sys.stdout.encoding)
+ except AttributeError:
+ o = o.encode('utf8')
# status previously used by exec_command() for parent
# of OSError
s = 127
@@ -674,7 +681,9 @@ def CCompiler_cxx_compiler(self):
return self
cxx = copy(self)
- cxx.compiler_so = [cxx.compiler_cxx[0]] + cxx.compiler_so[1:]
+ cxx.compiler_cxx = cxx.compiler_cxx
+ cxx.compiler_so = [cxx.compiler_cxx[0]] + \
+ sanitize_cxx_flags(cxx.compiler_so[1:])
if sys.platform.startswith('aix') and 'ld_so_aix' in cxx.linker_so[0]:
# AIX needs the ld_so_aix script included with Python
cxx.linker_so = [cxx.linker_so[0], cxx.compiler_cxx[0]] \
diff --git a/numpy/distutils/ccompiler_opt.py b/numpy/distutils/ccompiler_opt.py
index e7fd494d3..39847c20f 100644
--- a/numpy/distutils/ccompiler_opt.py
+++ b/numpy/distutils/ccompiler_opt.py
@@ -8,7 +8,14 @@ the sources with proper compiler's flags.
instead only focuses on the compiler side, but it creates abstract C headers
that can be used later for the final runtime dispatching process."""
-import sys, io, os, re, textwrap, pprint, inspect, atexit, subprocess
+import atexit
+import inspect
+import os
+import pprint
+import re
+import subprocess
+import textwrap
+
class _Config:
"""An abstract class holds all configurable attributes of `CCompilerOpt`,
@@ -188,7 +195,7 @@ class _Config:
# native usually works only with x86
native = '-march=native',
opt = '-O3',
- werror = '-Werror'
+ werror = '-Werror',
),
clang = dict(
native = '-march=native',
@@ -198,22 +205,22 @@ class _Config:
# cases `-Werror` gets skipped during the availability test due to
# "unused arguments" warnings.
# see https://github.com/numpy/numpy/issues/19624
- werror = '-Werror-implicit-function-declaration -Werror'
+ werror = '-Werror=switch -Werror',
),
icc = dict(
native = '-xHost',
opt = '-O3',
- werror = '-Werror'
+ werror = '-Werror',
),
iccw = dict(
native = '/QxHost',
opt = '/O3',
- werror = '/Werror'
+ werror = '/Werror',
),
msvc = dict(
native = None,
opt = '/O2',
- werror = '/WX'
+ werror = '/WX',
)
)
conf_min_features = dict(
@@ -406,8 +413,8 @@ class _Config:
AVX512_ICL = dict(flags="/Qx:ICELAKE-CLIENT")
)
if on_x86 and self.cc_is_msvc: return dict(
- SSE = dict(flags="/arch:SSE"),
- SSE2 = dict(flags="/arch:SSE2"),
+ SSE = dict(flags="/arch:SSE") if self.cc_on_x86 else {},
+ SSE2 = dict(flags="/arch:SSE2") if self.cc_on_x86 else {},
SSE3 = {},
SSSE3 = {},
SSE41 = {},
@@ -516,7 +523,8 @@ class _Config:
def __init__(self):
if self.conf_tmp_path is None:
- import tempfile, shutil
+ import shutil
+ import tempfile
tmp = tempfile.mkdtemp()
def rm_temp():
try:
@@ -555,6 +563,7 @@ class _Distutils:
flags = kwargs.pop("extra_postargs", []) + flags
if not ccompiler:
ccompiler = self._ccompiler
+
return ccompiler.compile(sources, extra_postargs=flags, **kwargs)
def dist_test(self, source, flags, macros=[]):
@@ -696,7 +705,6 @@ class _Distutils:
)
@staticmethod
def _dist_test_spawn(cmd, display=None):
- from distutils.errors import CompileError
try:
o = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
universal_newlines=True)
@@ -708,8 +716,8 @@ class _Distutils:
except subprocess.CalledProcessError as exc:
o = exc.output
s = exc.returncode
- except OSError:
- o = b''
+ except OSError as e:
+ o = e
s = 127
else:
return None
diff --git a/numpy/distutils/checks/cpu_asimdfhm.c b/numpy/distutils/checks/cpu_asimdfhm.c
index bb437aa40..cb49751c4 100644
--- a/numpy/distutils/checks/cpu_asimdfhm.c
+++ b/numpy/distutils/checks/cpu_asimdfhm.c
@@ -10,8 +10,8 @@ int main(void)
float32x4_t vf = vdupq_n_f32(1.0f);
float32x2_t vlf = vdup_n_f32(1.0f);
- int ret = (int)vget_lane_f32(vfmlal_low_u32(vlf, vlhp, vlhp), 0);
- ret += (int)vgetq_lane_f32(vfmlslq_high_u32(vf, vhp, vhp), 0);
+ int ret = (int)vget_lane_f32(vfmlal_low_f16(vlf, vlhp, vlhp), 0);
+ ret += (int)vgetq_lane_f32(vfmlslq_high_f16(vf, vhp, vhp), 0);
return ret;
}
diff --git a/numpy/distutils/command/build_clib.py b/numpy/distutils/command/build_clib.py
index 0e31a7dee..45201f98f 100644
--- a/numpy/distutils/command/build_clib.py
+++ b/numpy/distutils/command/build_clib.py
@@ -185,6 +185,30 @@ class build_clib(old_build_clib):
for (lib_name, build_info) in libraries:
self.build_a_library(build_info, lib_name, libraries)
+ def assemble_flags(self, in_flags):
+ """ Assemble flags from flag list
+
+ Parameters
+ ----------
+ in_flags : None or sequence
+ None corresponds to empty list. Sequence elements can be strings
+ or callables that return lists of strings. Callable takes `self` as
+ single parameter.
+
+ Returns
+ -------
+ out_flags : list
+ """
+ if in_flags is None:
+ return []
+ out_flags = []
+ for in_flag in in_flags:
+ if callable(in_flag):
+ out_flags += in_flag(self)
+ else:
+ out_flags.append(in_flag)
+ return out_flags
+
def build_a_library(self, build_info, lib_name, libraries):
# default compilers
compiler = self.compiler
@@ -263,7 +287,13 @@ class build_clib(old_build_clib):
include_dirs = build_info.get('include_dirs')
if include_dirs is None:
include_dirs = []
- extra_postargs = build_info.get('extra_compiler_args') or []
+ # Flags can be strings, or callables that return a list of strings.
+ extra_postargs = self.assemble_flags(
+ build_info.get('extra_compiler_args'))
+ extra_cflags = self.assemble_flags(
+ build_info.get('extra_cflags'))
+ extra_cxxflags = self.assemble_flags(
+ build_info.get('extra_cxxflags'))
include_dirs.extend(get_numpy_include_dirs())
# where compiled F90 module files are:
@@ -315,38 +345,45 @@ class build_clib(old_build_clib):
macros=macros + copt_macros,
include_dirs=include_dirs,
debug=self.debug,
- extra_postargs=extra_postargs,
+ extra_postargs=extra_postargs + extra_cxxflags,
ccompiler=cxx_compiler
)
if copt_c_sources:
log.info("compiling C dispatch-able sources")
- objects += self.compiler_opt.try_dispatch(copt_c_sources,
- output_dir=self.build_temp,
- src_dir=copt_build_src,
- macros=macros + copt_macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_postargs)
+ objects += self.compiler_opt.try_dispatch(
+ copt_c_sources,
+ output_dir=self.build_temp,
+ src_dir=copt_build_src,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs + extra_cflags)
if c_sources:
log.info("compiling C sources")
- objects += compiler.compile(c_sources,
- output_dir=self.build_temp,
- macros=macros + copt_macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_postargs + copt_baseline_flags)
+ objects += compiler.compile(
+ c_sources,
+ output_dir=self.build_temp,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=(extra_postargs +
+ copt_baseline_flags +
+ extra_cflags))
if cxx_sources:
log.info("compiling C++ sources")
cxx_compiler = compiler.cxx_compiler()
- cxx_objects = cxx_compiler.compile(cxx_sources,
- output_dir=self.build_temp,
- macros=macros + copt_macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_postargs + copt_baseline_flags)
+ cxx_objects = cxx_compiler.compile(
+ cxx_sources,
+ output_dir=self.build_temp,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=(extra_postargs +
+ copt_baseline_flags +
+ extra_cxxflags))
objects.extend(cxx_objects)
if f_sources or fmodule_sources:
diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py
index b8378d473..7040a2411 100644
--- a/numpy/distutils/command/build_ext.py
+++ b/numpy/distutils/command/build_ext.py
@@ -243,7 +243,8 @@ class build_ext (old_build_ext):
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
+ if not ext.language:
+ ext.language = ext_language
# global language
all_languages.update(ext_languages)
@@ -376,6 +377,9 @@ class build_ext (old_build_ext):
log.info("building '%s' extension", ext.name)
extra_args = ext.extra_compile_args or []
+ extra_cflags = ext.extra_c_compile_args or []
+ extra_cxxflags = ext.extra_cxx_compile_args or []
+
macros = ext.define_macros[:]
for undef in ext.undef_macros:
macros.append((undef,))
@@ -462,38 +466,43 @@ class build_ext (old_build_ext):
macros=macros + copt_macros,
include_dirs=include_dirs,
debug=self.debug,
- extra_postargs=extra_args,
+ extra_postargs=extra_args + extra_cxxflags,
ccompiler=cxx_compiler,
**kws
)
if copt_c_sources:
log.info("compiling C dispatch-able sources")
- c_objects += self.compiler_opt.try_dispatch(copt_c_sources,
- output_dir=output_dir,
- src_dir=copt_build_src,
- macros=macros + copt_macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_args,
- **kws)
+ c_objects += self.compiler_opt.try_dispatch(
+ copt_c_sources,
+ output_dir=output_dir,
+ src_dir=copt_build_src,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_args + extra_cflags,
+ **kws)
if c_sources:
log.info("compiling C sources")
- c_objects += self.compiler.compile(c_sources,
- output_dir=output_dir,
- macros=macros + copt_macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_args + copt_baseline_flags,
- **kws)
+ c_objects += self.compiler.compile(
+ c_sources,
+ output_dir=output_dir,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=(extra_args + copt_baseline_flags +
+ extra_cflags),
+ **kws)
if cxx_sources:
log.info("compiling C++ sources")
- c_objects += cxx_compiler.compile(cxx_sources,
- output_dir=output_dir,
- macros=macros + copt_macros,
- include_dirs=include_dirs,
- debug=self.debug,
- extra_postargs=extra_args + copt_baseline_flags,
- **kws)
+ c_objects += cxx_compiler.compile(
+ cxx_sources,
+ output_dir=output_dir,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=(extra_args + copt_baseline_flags +
+ extra_cxxflags),
+ **kws)
extra_postargs = []
f_objects = []
diff --git a/numpy/distutils/extension.py b/numpy/distutils/extension.py
index c90b5d725..3ede013e0 100644
--- a/numpy/distutils/extension.py
+++ b/numpy/distutils/extension.py
@@ -47,6 +47,8 @@ class Extension(old_Extension):
language=None,
f2py_options=None,
module_dirs=None,
+ extra_c_compile_args=None,
+ extra_cxx_compile_args=None,
extra_f77_compile_args=None,
extra_f90_compile_args=None,):
@@ -83,6 +85,8 @@ class Extension(old_Extension):
# numpy_distutils features
self.f2py_options = f2py_options or []
self.module_dirs = module_dirs or []
+ self.extra_c_compile_args = extra_c_compile_args or []
+ self.extra_cxx_compile_args = extra_cxx_compile_args or []
self.extra_f77_compile_args = extra_f77_compile_args or []
self.extra_f90_compile_args = extra_f90_compile_args or []
diff --git a/numpy/distutils/log.py b/numpy/distutils/log.py
index a8113b9c6..3347f56d6 100644
--- a/numpy/distutils/log.py
+++ b/numpy/distutils/log.py
@@ -87,3 +87,25 @@ _global_color_map = {
# don't use INFO,.. flags in set_verbosity, these flags are for set_threshold.
set_verbosity(0, force=True)
+
+
+_error = error
+_warn = warn
+_info = info
+_debug = debug
+
+
+def error(msg, *a, **kw):
+ _error(f"ERROR: {msg}", *a, **kw)
+
+
+def warn(msg, *a, **kw):
+ _warn(f"WARN: {msg}", *a, **kw)
+
+
+def info(msg, *a, **kw):
+ _info(f"INFO: {msg}", *a, **kw)
+
+
+def debug(msg, *a, **kw):
+ _debug(f"DEBUG: {msg}", *a, **kw)
diff --git a/numpy/distutils/mingw32ccompiler.py b/numpy/distutils/mingw32ccompiler.py
index 541055899..fbe3655c9 100644
--- a/numpy/distutils/mingw32ccompiler.py
+++ b/numpy/distutils/mingw32ccompiler.py
@@ -24,7 +24,6 @@ from numpy.distutils import log
# 3. Force windows to use g77
import distutils.cygwinccompiler
-from distutils.version import StrictVersion
from distutils.unixccompiler import UnixCCompiler
from distutils.msvccompiler import get_build_version as get_build_msvc_version
from distutils.errors import UnknownFileError
@@ -62,35 +61,6 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler):
distutils.cygwinccompiler.CygwinCCompiler.__init__ (self, verbose,
dry_run, force)
- # we need to support 3.2 which doesn't match the standard
- # get_versions methods regex
- if self.gcc_version is None:
- try:
- out_string = subprocess.check_output(['gcc', '-dumpversion'])
- except (OSError, CalledProcessError):
- out_string = "" # ignore failures to match old behavior
- result = re.search(r'(\d+\.\d+)', out_string)
- if result:
- self.gcc_version = StrictVersion(result.group(1))
-
- # A real mingw32 doesn't need to specify a different entry point,
- # but cygwin 2.91.57 in no-cygwin-mode needs it.
- if self.gcc_version <= "2.91.57":
- entry_point = '--entry _DllMain@12'
- else:
- entry_point = ''
-
- if self.linker_dll == 'dllwrap':
- # Commented out '--driver-name g++' part that fixes weird
- # g++.exe: g++: No such file or directory
- # error (mingw 1.0 in Enthon24 tree, gcc-3.4.5).
- # If the --driver-name part is required for some environment
- # then make the inclusion of this part specific to that
- # environment.
- self.linker = 'dllwrap' # --driver-name g++'
- elif self.linker_dll == 'gcc':
- self.linker = 'g++'
-
# **changes: eric jones 4/11/01
# 1. Check for import library on Windows. Build if it doesn't exist.
@@ -113,42 +83,18 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler):
# kind of bad consequences, like using Py_ModuleInit4 instead of
# Py_ModuleInit4_64, etc... So we add it here
if get_build_architecture() == 'AMD64':
- if self.gcc_version < "4.0":
- self.set_executables(
- compiler='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0 -Wall',
- compiler_so='gcc -g -DDEBUG -DMS_WIN64 -mno-cygwin -O0'
- ' -Wall -Wstrict-prototypes',
- linker_exe='gcc -g -mno-cygwin',
- linker_so='gcc -g -mno-cygwin -shared')
- else:
- # gcc-4 series releases do not support -mno-cygwin option
- self.set_executables(
- compiler='gcc -g -DDEBUG -DMS_WIN64 -O0 -Wall',
- compiler_so='gcc -g -DDEBUG -DMS_WIN64 -O0 -Wall -Wstrict-prototypes',
- linker_exe='gcc -g',
- linker_so='gcc -g -shared')
+ self.set_executables(
+ compiler='gcc -g -DDEBUG -DMS_WIN64 -O0 -Wall',
+ compiler_so='gcc -g -DDEBUG -DMS_WIN64 -O0 -Wall '
+ '-Wstrict-prototypes',
+ linker_exe='gcc -g',
+ linker_so='gcc -g -shared')
else:
- if self.gcc_version <= "3.0.0":
- self.set_executables(
- compiler='gcc -mno-cygwin -O2 -w',
- compiler_so='gcc -mno-cygwin -mdll -O2 -w'
- ' -Wstrict-prototypes',
- linker_exe='g++ -mno-cygwin',
- linker_so='%s -mno-cygwin -mdll -static %s' %
- (self.linker, entry_point))
- elif self.gcc_version < "4.0":
- self.set_executables(
- compiler='gcc -mno-cygwin -O2 -Wall',
- compiler_so='gcc -mno-cygwin -O2 -Wall'
- ' -Wstrict-prototypes',
- linker_exe='g++ -mno-cygwin',
- linker_so='g++ -mno-cygwin -shared')
- else:
- # gcc-4 series releases do not support -mno-cygwin option
- self.set_executables(compiler='gcc -O2 -Wall',
- compiler_so='gcc -O2 -Wall -Wstrict-prototypes',
- linker_exe='g++ ',
- linker_so='g++ -shared')
+ self.set_executables(
+ compiler='gcc -O2 -Wall',
+ compiler_so='gcc -O2 -Wall -Wstrict-prototypes',
+ linker_exe='g++ ',
+ linker_so='g++ -shared')
# added for python2.3 support
# we can't pass it through set_executables because pre 2.2 would fail
self.compiler_cxx = ['g++']
@@ -198,10 +144,7 @@ class Mingw32CCompiler(distutils.cygwinccompiler.CygwinCCompiler):
extra_postargs,
build_temp,
target_lang)
- if self.gcc_version < "3.0.0":
- func = distutils.cygwinccompiler.CygwinCCompiler.link
- else:
- func = UnixCCompiler.link
+ func = UnixCCompiler.link
func(*args[:func.__code__.co_argcount])
return
@@ -547,12 +490,12 @@ if sys.platform == 'win32':
# Value from msvcrt.CRT_ASSEMBLY_VERSION under Python 3.3.0
# on Windows XP:
_MSVCRVER_TO_FULLVER['100'] = "10.0.30319.460"
- # Python 3.7 uses 1415, but get_build_version returns 140 ??
- _MSVCRVER_TO_FULLVER['140'] = "14.15.26726.0"
- if hasattr(msvcrt, "CRT_ASSEMBLY_VERSION"):
- major, minor, rest = msvcrt.CRT_ASSEMBLY_VERSION.split(".", 2)
- _MSVCRVER_TO_FULLVER[major + minor] = msvcrt.CRT_ASSEMBLY_VERSION
- del major, minor, rest
+ crt_ver = getattr(msvcrt, 'CRT_ASSEMBLY_VERSION', None)
+ if crt_ver is not None: # Available at least back to Python 3.3
+ maj, min = re.match(r'(\d+)\.(\d)', crt_ver).groups()
+ _MSVCRVER_TO_FULLVER[maj + min] = crt_ver
+ del maj, min
+ del crt_ver
except ImportError:
# If we are here, means python was not built with MSVC. Not sure what
# to do in that case: manifest building will fail, but it should not be
@@ -647,10 +590,9 @@ def generate_manifest(config):
if msver is not None:
if msver >= 8:
check_embedded_msvcr_match_linked(msver)
- ma = int(msver)
- mi = int((msver - ma) * 10)
+ ma_str, mi_str = str(msver).split('.')
# Write the manifest file
- manxml = msvc_manifest_xml(ma, mi)
+ manxml = msvc_manifest_xml(int(ma_str), int(mi_str))
with open(manifest_name(config), "w") as man:
config.temp_files.append(manifest_name(config))
man.write(manxml)
diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py
index c9e051237..b68b3af47 100644
--- a/numpy/distutils/misc_util.py
+++ b/numpy/distutils/misc_util.py
@@ -11,6 +11,7 @@ import multiprocessing
import textwrap
import importlib.util
from threading import local as tlocal
+from functools import reduce
import distutils
from distutils.errors import DistutilsError
@@ -43,7 +44,7 @@ __all__ = ['Configuration', 'get_numpy_include_dirs', 'default_config_dict',
'dot_join', 'get_frame', 'minrelpath', 'njoin',
'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language',
'get_build_architecture', 'get_info', 'get_pkg_info',
- 'get_num_build_jobs']
+ 'get_num_build_jobs', 'sanitize_cxx_flags']
class InstallableLib:
"""
@@ -2478,3 +2479,15 @@ def get_build_architecture():
# systems, so delay the import to here.
from distutils.msvccompiler import get_build_architecture
return get_build_architecture()
+
+
+_cxx_ignore_flags = {'-Werror=implicit-function-declaration', '-std=c99'}
+
+
+def sanitize_cxx_flags(cxxflags):
+ '''
+ Some flags are valid for C but not C++. Prune them.
+ '''
+ return [flag for flag in cxxflags if flag not in _cxx_ignore_flags]
+
+
diff --git a/numpy/distutils/tests/test_ccompiler_opt.py b/numpy/distutils/tests/test_ccompiler_opt.py
index 9c54ed66b..1b27ab07c 100644
--- a/numpy/distutils/tests/test_ccompiler_opt.py
+++ b/numpy/distutils/tests/test_ccompiler_opt.py
@@ -434,7 +434,8 @@ class _Test_CCompilerOpt:
self.expect_flags(
"sse sse2 vsx vsx2 neon neon_fp16",
x86_gcc="-msse -msse2", x86_icc="-msse -msse2",
- x86_iccw="/arch:SSE2", x86_msvc="/arch:SSE2",
+ x86_iccw="/arch:SSE2",
+ x86_msvc="/arch:SSE2" if self.march() == "x86" else "",
ppc64_gcc= "-mcpu=power8",
ppc64_clang="-maltivec -mvsx -mpower8-vector",
armhf_gcc="-mfpu=neon-fp16 -mfp16-format=ieee",
@@ -636,7 +637,8 @@ class _Test_CCompilerOpt:
x86_gcc="avx512f avx2 sse42 sse41 sse2",
x86_icc="avx512f avx2 sse42 sse41 sse2",
x86_iccw="avx512f avx2 sse42 sse41 sse2",
- x86_msvc="avx512f avx2 sse2",
+ x86_msvc="avx512f avx2 sse2"
+ if self.march() == 'x86' else "avx512f avx2",
ppc64="vsx3 vsx2",
armhf="asimddp asimd neon_vfpv4 neon",
# neon, neon_vfpv4, asimd implies each other
diff --git a/numpy/distutils/tests/test_log.py b/numpy/distutils/tests/test_log.py
new file mode 100644
index 000000000..36f49f592
--- /dev/null
+++ b/numpy/distutils/tests/test_log.py
@@ -0,0 +1,32 @@
+import io
+import re
+from contextlib import redirect_stdout
+
+import pytest
+
+from numpy.distutils import log
+
+
+def setup_module():
+ log.set_verbosity(2, force=True) # i.e. DEBUG
+
+
+def teardown_module():
+ log.set_verbosity(0, force=True) # the default
+
+
+r_ansi = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
+
+
+@pytest.mark.parametrize("func_name", ["error", "warn", "info", "debug"])
+def test_log_prefix(func_name):
+ func = getattr(log, func_name)
+ msg = f"{func_name} message"
+ f = io.StringIO()
+ with redirect_stdout(f):
+ func(msg)
+ out = f.getvalue()
+ assert out # sanity check
+ clean_out = r_ansi.sub("", out)
+ line = next(line for line in clean_out.splitlines())
+ assert line == f"{func_name.upper()}: {msg}"
diff --git a/numpy/distutils/tests/test_system_info.py b/numpy/distutils/tests/test_system_info.py
index b722281ad..8c26271af 100644
--- a/numpy/distutils/tests/test_system_info.py
+++ b/numpy/distutils/tests/test_system_info.py
@@ -254,6 +254,10 @@ class TestSystemInfoReading:
finally:
os.chdir(previousDir)
+ HAS_MKL = "mkl_rt" in mkl_info().calc_libraries_info().get("libraries", [])
+
+ @pytest.mark.xfail(HAS_MKL, reason=("`[DEFAULT]` override doesn't work if "
+ "numpy is built with MKL support"))
def test_overrides(self):
previousDir = os.getcwd()
cfg = os.path.join(self._dir1, 'site.cfg')
diff --git a/numpy/distutils/unixccompiler.py b/numpy/distutils/unixccompiler.py
index 733a9fc50..4884960fd 100644
--- a/numpy/distutils/unixccompiler.py
+++ b/numpy/distutils/unixccompiler.py
@@ -5,6 +5,7 @@ unixccompiler - can handle very long argument lists for ar.
import os
import sys
import subprocess
+import shlex
from distutils.errors import CompileError, DistutilsExecError, LibError
from distutils.unixccompiler import UnixCCompiler
@@ -30,15 +31,15 @@ def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts
if 'OPT' in os.environ:
# XXX who uses this?
from sysconfig import get_config_vars
- opt = " ".join(os.environ['OPT'].split())
- gcv_opt = " ".join(get_config_vars('OPT')[0].split())
- ccomp_s = " ".join(self.compiler_so)
+ opt = shlex.join(shlex.split(os.environ['OPT']))
+ gcv_opt = shlex.join(shlex.split(get_config_vars('OPT')[0]))
+ ccomp_s = shlex.join(self.compiler_so)
if opt not in ccomp_s:
ccomp_s = ccomp_s.replace(gcv_opt, opt)
- self.compiler_so = ccomp_s.split()
- llink_s = " ".join(self.linker_so)
+ self.compiler_so = shlex.split(ccomp_s)
+ llink_s = shlex.join(self.linker_so)
if opt not in llink_s:
- self.linker_so = llink_s.split() + opt.split()
+ self.linker_so = self.linker_so + shlex.split(opt)
display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src)