From ec4bbf1451b5a49e42d41a6b6244baba04b37b25 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 13 Sep 2023 23:16:28 +0300 Subject: [PATCH] statically link on posix, add aarch4 wheel build --- .travis.yml | 1 + local/scipy_openblas64/__init__.py | 33 +++++++++++++++++++++--- src/_init_openblas.c | 41 ------------------------------ travis-ci/build_steps.sh | 6 ++++- travis-ci/build_wheel.sh | 2 +- 5 files changed, 36 insertions(+), 47 deletions(-) delete mode 100644 src/_init_openblas.c diff --git a/.travis.yml b/.travis.yml index bb04b5b..40b89dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -86,6 +86,7 @@ install: script: # Build library and collect into libs subdirectory - build_lib "$PLAT" "$INTERFACE64" + - source travis-ci/build_wheel.sh after_success: # Upload libraries to the shared staging area on anaconda.org diff --git a/local/scipy_openblas64/__init__.py b/local/scipy_openblas64/__init__.py index acf85d5..ff0f191 100644 --- a/local/scipy_openblas64/__init__.py +++ b/local/scipy_openblas64/__init__.py @@ -1,3 +1,7 @@ +""" + +""" + import ctypes import os from pathlib import Path @@ -26,14 +30,20 @@ def get_include_dir(): + """Return the include directory needed for compilation + """ return os.path.join(_HERE, "include") def get_lib_dir(): + """Return the lib directory needed for linking + """ return os.path.join(_HERE, "lib") def get_library(): + """Return the lib name needed for linking + """ if sys.platform == "win32": libs = [x for x in os.listdir(get_lib_dir()) if x.endswith(".lib")] return os.path.splitext(libs[0])[0] @@ -41,11 +51,14 @@ def get_library(): return "openblas_python" def get_pkg_config(): + """Return a multi-line string that, when saved to a file, can be used with + pkg-config for build systems like meson + """ if sys.platform == "win32": extralib = "-defaultlib:advapi32 -lgfortran -defaultlib:advapi32 -lgfortran" else: extralib = "-lm -lpthread -lgfortran -lm -lpthread -lgfortran" - return f"""\ + return dedent(f"""\ libdir={get_lib_dir()} includedir={get_include_dir()} openblas_config= {openblas_config} @@ -58,15 +71,27 @@ def get_pkg_config(): Libs: -L${libdir} -l{get_library()} Libs.private: ${extralib} Cflags: -I${includedir} - """ + """) if sys.platform == "win32": os.add_dll_directory(get_lib_dir()) - +def write__distributor_init(target): + """Accepts a Pathlib or string of a directory. + Write a pre-import file that will import scipy_openblas64 before + continuing to import the library. This will load OpenBLAS into the + executable's namespace and make the functions available for use. + """ + fname = os.path.join(target, "_distributor_init.py") + with open(fname, "wt", encoding="utf8") as fid: + fid.write(dedent(f"""\ + """) def _get_openblas_config(): + """Use ctypes to pull out the config string from the OpenBLAS library. + It will be available as `openblas_config` + """ lib_dir = get_lib_dir() if sys.platform == "win32": # Get libopenblas*.lib @@ -78,6 +103,6 @@ def _get_openblas_config(): dll = ctypes.CDLL(os.path.join(lib_dir, libnames[0])) openblas_config = dll.openblas_get_config64_ openblas_config.restype = ctypes.c_char_p - return openblas_config + return openblas_config() openblas_config = _get_openblas_config() diff --git a/src/_init_openblas.c b/src/_init_openblas.c deleted file mode 100644 index d75e6c3..0000000 --- a/src/_init_openblas.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -#ifdef OPENBLAS_USE64BITINT - #define openblas_get_config openblas_get_config64_ -#endif - -extern char* openblas_get_config(void); - -PyObject * -get_config(PyObject *self, PyObject *args) { - const char * config = openblas_get_config(); - return PyUnicode_FromString(config); -} - -static PyMethodDef InitMethods[] = { - {"get_config", get_config, METH_NOARGS, - "Return openblas_get_config(), see https://github.com/xianyi/OpenBLAS/wiki/OpenBLAS-Extensions"}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -static struct PyModuleDef initmodule = { - PyModuleDef_HEAD_INIT, - "_init_openblas", /* name of module */ - NULL, /* module documentation, may be NULL */ - -1, /* size of per-interpreter state of the module, - or -1 if the module keeps state in global variables. */ - InitMethods -}; - -PyMODINIT_FUNC -PyInit__init_openblas(void) -{ - PyObject *m; - - m = PyModule_Create(&initmodule); - if (m == NULL) - return NULL; - - return m; -} diff --git a/travis-ci/build_steps.sh b/travis-ci/build_steps.sh index 934975a..8cda0de 100644 --- a/travis-ci/build_steps.sh +++ b/travis-ci/build_steps.sh @@ -165,7 +165,11 @@ function do_build_lib { git config --global --add safe.directory '*' pushd OpenBLAS patch_source - CFLAGS="$CFLAGS -fvisibility=protected" make BUFFERSIZE=20 DYNAMIC_ARCH=1 USE_OPENMP=0 NUM_THREADS=64 BINARY=$bitness $interface64_flags $target_flags > /dev/null + CFLAGS="$CFLAGS -fvisibility=protected" \ + make BUFFERSIZE=20 DYNAMIC_ARCH=1 \ + USE_OPENMP=0 NUM_THREADS=64 \ + LDFLAGS="-static ${LDFLAGS}" + BINARY=$bitness $interface64_flags $target_flags > /dev/null make PREFIX=$BUILD_PREFIX $interface64_flags install popd stop_spinner diff --git a/travis-ci/build_wheel.sh b/travis-ci/build_wheel.sh index 4a2ff3b..5b7a5d1 100644 --- a/travis-ci/build_wheel.sh +++ b/travis-ci/build_wheel.sh @@ -54,7 +54,7 @@ if [ $(uname) == "Darwin" ]; then for f in dist/*.whl; do mv $f "${f/%any.whl/macosx_10_9_$PLAT.whl}"; done delocate-wheel -v dist/*.whl else - auditwheel repair -w dist dist/*.whl + auditwheel repair -w dist --lib-sdir /lib dist/*.whl rm dist/scipy_openblas*-none-any.whl fi