summaryrefslogtreecommitdiff
path: root/numpy/core/setup.py
diff options
context:
space:
mode:
authorHood Chatham <roberthoodchatham@gmail.com>2022-03-05 16:00:54 -0800
committerHood Chatham <roberthoodchatham@gmail.com>2022-03-07 12:17:37 -0800
commit3e4d87b1ba76b245dcbf45bb26b1f7118861f286 (patch)
tree2abb65c7cb317f25565f8a1390fb7f01c2c6de32 /numpy/core/setup.py
parent64cfb046e86692daa1119ba1b1de2ab50d00afde (diff)
downloadnumpy-3e4d87b1ba76b245dcbf45bb26b1f7118861f286.tar.gz
MAINT, BLD Fix math feature detection for wasm
The web assembly linker is strict about function types, it is unwilling to link a function defined with signature say `double f(double, double)` to an invocation with signature `void f(void)`. This causes trouble in `numpy/core/setup.py` in the functions `check_math_capabilities` and `check_mathlib`. This patch fixes the problem by giving config.try_link the correct function signatures for these functions. In particular I added a separate header file with all the math declarations. It would be be possible to just include 'math.h' but we also need to parse the declarations to figure out how to call the functions. If f has arguments type1, type2, type3, we want to call it like f((type1)0, (type2)0, (type3)0). Anyways it is easier to parse the arguments out of our feature_detection_math.h than to worry about the possibility that someone will have a differently formatted system math.h. We do a test where we include both math.h and feature_detection_math.h to ensure consistency between the signatures. I also separated out the fcntl functions, backtrace and madvise, and strtold_l. This is because they require separate headers. strtold_l requires testing both with the locale.h header and with the xlocale.h header (this seems to vary even among different linuxes). All of the functions I moved out of OPTIONAL_STDFUNCS are absent on windows and some are absent on OSX so separating them out of the OPTIONAL_STDFUNCS should mildly improve the speed of feature detection on mac and windows (since they have all the functions remaining in OPTIONAL_STDFUNCS).
Diffstat (limited to 'numpy/core/setup.py')
-rw-r--r--numpy/core/setup.py79
1 files changed, 61 insertions, 18 deletions
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index f6b31075d..abc1b54b1 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -129,32 +129,48 @@ def win32_checks(deflist):
deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
def check_math_capabilities(config, ext, moredefs, mathlibs):
- def check_func(func_name):
- return config.check_func(func_name, libraries=mathlibs,
- decl=True, call=True)
-
- def check_funcs_once(funcs_name):
- decl = dict([(f, True) for f in funcs_name])
- st = config.check_funcs_once(funcs_name, libraries=mathlibs,
- decl=decl, call=decl)
+ def check_func(
+ func_name,
+ decl=False,
+ headers=["feature_detection_math.h"],
+ ):
+ return config.check_func(
+ func_name,
+ libraries=mathlibs,
+ decl=decl,
+ call=True,
+ call_args=FUNC_CALL_ARGS[func_name],
+ headers=headers,
+ )
+
+ def check_funcs_once(funcs_name, headers=["feature_detection_math.h"]):
+ call = dict([(f, True) for f in funcs_name])
+ call_args = dict([(f, FUNC_CALL_ARGS[f]) for f in funcs_name])
+ st = config.check_funcs_once(
+ funcs_name,
+ libraries=mathlibs,
+ decl=False,
+ call=call,
+ call_args=call_args,
+ headers=headers,
+ )
if st:
moredefs.extend([(fname2def(f), 1) for f in funcs_name])
return st
- def check_funcs(funcs_name):
+ def check_funcs(funcs_name, headers=["feature_detection_math.h"]):
# Use check_funcs_once first, and if it does not work, test func per
# func. Return success only if all the functions are available
- if not check_funcs_once(funcs_name):
+ if not check_funcs_once(funcs_name, headers=headers):
# Global check failed, check func per func
for f in funcs_name:
- if check_func(f):
+ if check_func(f, headers=headers):
moredefs.append((fname2def(f), 1))
return 0
else:
return 1
#use_msvc = config.check_decl("_MSC_VER")
-
if not check_funcs_once(MANDATORY_FUNCS):
raise SystemError("One of the required function to build numpy is not"
" available (the list is %s)." % str(MANDATORY_FUNCS))
@@ -169,15 +185,34 @@ def check_math_capabilities(config, ext, moredefs, mathlibs):
for f in OPTIONAL_STDFUNCS_MAYBE:
if config.check_decl(fname2def(f),
headers=["Python.h", "math.h"]):
- OPTIONAL_STDFUNCS.remove(f)
+ if f in OPTIONAL_STDFUNCS:
+ OPTIONAL_STDFUNCS.remove(f)
+ else:
+ OPTIONAL_FILE_FUNCS.remove(f)
+
check_funcs(OPTIONAL_STDFUNCS)
+ check_funcs(OPTIONAL_FILE_FUNCS, headers=["feature_detection_stdio.h"])
+ check_funcs(OPTIONAL_MISC_FUNCS, headers=["feature_detection_misc.h"])
+
+
for h in OPTIONAL_HEADERS:
if config.check_func("", decl=False, call=False, headers=[h]):
h = h.replace(".", "_").replace(os.path.sep, "_")
moredefs.append((fname2def(h), 1))
+ # Try with both "locale.h" and "xlocale.h"
+ locale_headers = [
+ "stdlib.h",
+ "xlocale.h",
+ "feature_detection_locale.h",
+ ]
+ if not check_funcs(OPTIONAL_LOCALE_FUNCS, headers=locale_headers):
+ # It didn't work with xlocale.h, maybe it will work with locale.h?
+ locale_headers[1] = "locale.h"
+ check_funcs(OPTIONAL_LOCALE_FUNCS, headers=locale_headers)
+
for tup in OPTIONAL_INTRINSICS:
headers = None
if len(tup) == 2:
@@ -398,20 +433,28 @@ def check_types(config_cmd, ext, build_dir):
def check_mathlib(config_cmd):
# Testing the C math library
mathlibs = []
- mathlibs_choices = [[], ['m'], ['cpml']]
- mathlib = os.environ.get('MATHLIB')
+ mathlibs_choices = [[], ["m"], ["cpml"]]
+ mathlib = os.environ.get("MATHLIB")
if mathlib:
- mathlibs_choices.insert(0, mathlib.split(','))
+ mathlibs_choices.insert(0, mathlib.split(","))
for libs in mathlibs_choices:
- if config_cmd.check_func("exp", libraries=libs, decl=True, call=True):
+ if config_cmd.check_func(
+ "log",
+ libraries=libs,
+ call_args="0",
+ decl="double log(double);",
+ call=True
+ ):
mathlibs = libs
break
else:
raise RuntimeError(
"math library missing; rerun setup.py after setting the "
- "MATHLIB env variable")
+ "MATHLIB env variable"
+ )
return mathlibs
+
def visibility_define(config):
"""Return the define value to use for NPY_VISIBILITY_HIDDEN (may be empty
string)."""