diff --git a/.github/workflows/cibuildwheel.yml b/.github/workflows/cibuildwheel.yml index d755dc1..6c934eb 100644 --- a/.github/workflows/cibuildwheel.yml +++ b/.github/workflows/cibuildwheel.yml @@ -22,14 +22,16 @@ jobs: with: python-version: "3.11" - - name: Install cibuildwheel and build dependencies - run: | - python -m pip install --upgrade pip - # Install these on the host so cibuildwheel can resolve the paths - python -m pip install cibuildwheel scipy-openblas delvewheel + - name: Install cibuildwheel + run: | + python -m pip install --upgrade pip + python -m pip install cibuildwheel - - name: Build wheels - run: python -m cibuildwheel --output-dir wheelhouse + - name: Install Windows build dependencies + if: runner.os == 'Windows' + run: | + # Install these on the host so cibuildwheel can resolve the paths + python -m pip install scipy-openblas64 delvewheel - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse diff --git a/_codeql_detected_source_root b/_codeql_detected_source_root new file mode 120000 index 0000000..945c9b4 --- /dev/null +++ b/_codeql_detected_source_root @@ -0,0 +1 @@ +. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f87603b..b8a6ba7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,14 +27,13 @@ environment = { EASYSBA_USE_ACCELERATE = "1", EASYSBA_LAPACK_LIBS = "" } [tool.cibuildwheel.windows] # We already installed these on the host, but we install them in the # build venv as well to be safe for the repair step. -before-build = "pip install scipy-openblas delvewheel" +before-build = "pip install scipy-openblas64 delvewheel" +# Use the repair-wheel-command to bundle the DLL +repair-wheel-command = "python -c \"import scipy_openblas64, subprocess, sys; subprocess.check_call(['delvewheel', 'repair', '--add-path', scipy_openblas64.get_lib_dir(), '-w', sys.argv[1], sys.argv[2]])\" {dest_dir} {wheel}" [tool.cibuildwheel.windows.environment] -EASYSBA_LAPACK_LIBS = "openblas" -# These $(...) commands will now work because scipy-openblas is on the host -INCLUDE = "$(python -c \"import scipy_openblas; print(scipy_openblas.get_include_dir())\");$INCLUDE" -LIB = "$(python -c \"import scipy_openblas; print(scipy_openblas.get_lib_dir())\");$LIB" - -[tool.cibuildwheel.windows.repair-wheel-command] -# Use the repair-wheel-command to bundle the DLL -repair-wheel-command = "python -c \"import scipy_openblas, subprocess, sys; subprocess.check_call(['delvewheel', 'repair', '--add-path', scipy_openblas.get_lib_dir(), '-w', sys.argv[1], sys.argv[2]])\" {dest_dir} {wheel}" +EASYSBA_LAPACK_LIBS = "libscipy_openblas64_" +# Only add the library directory for linking. Do NOT add include directory +# to avoid conflicts with scipy-openblas64's lapack.h (has C99 complex types +# incompatible with MSVC). The project has its own lapack_compat.h header. +LIB = "$(python -c \"import scipy_openblas64; print(scipy_openblas64.get_lib_dir())\");$LIB" diff --git a/src/lapack_compat.h b/src/lapack_compat.h index 0764245..ad74bb6 100644 --- a/src/lapack_compat.h +++ b/src/lapack_compat.h @@ -7,48 +7,53 @@ extern "C" { typedef int lapack_int; +// On Windows with scipy-openblas64, symbols have scipy_ prefix and 64_ suffix +#if defined(_WIN32) || defined(_WIN64) +#define FORTRAN_WRAPPER(name) scipy_##name##64_ +#else #define FORTRAN_WRAPPER(name) name##_ +#endif -void dgeqrf_(const lapack_int *m, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dgeqrf)(const lapack_int *m, const lapack_int *n, double *a, const lapack_int *lda, double *tau, double *work, const lapack_int *lwork, lapack_int *info); -void dorgqr_(const lapack_int *m, const lapack_int *n, const lapack_int *k, +void FORTRAN_WRAPPER(dorgqr)(const lapack_int *m, const lapack_int *n, const lapack_int *k, double *a, const lapack_int *lda, const double *tau, double *work, const lapack_int *lwork, lapack_int *info); -void dtrtrs_(const char *uplo, const char *trans, const char *diag, +void FORTRAN_WRAPPER(dtrtrs)(const char *uplo, const char *trans, const char *diag, const lapack_int *n, const lapack_int *nrhs, const double *a, const lapack_int *lda, double *b, const lapack_int *ldb, lapack_int *info); -void dpotrf_(const char *uplo, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dpotrf)(const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, lapack_int *info); -void dpotrs_(const char *uplo, const lapack_int *n, const lapack_int *nrhs, +void FORTRAN_WRAPPER(dpotrs)(const char *uplo, const lapack_int *n, const lapack_int *nrhs, const double *a, const lapack_int *lda, double *b, const lapack_int *ldb, lapack_int *info); -void dgetrf_(const lapack_int *m, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dgetrf)(const lapack_int *m, const lapack_int *n, double *a, const lapack_int *lda, lapack_int *ipiv, lapack_int *info); -void dgetrs_(const char *trans, const lapack_int *n, const lapack_int *nrhs, +void FORTRAN_WRAPPER(dgetrs)(const char *trans, const lapack_int *n, const lapack_int *nrhs, const double *a, const lapack_int *lda, const lapack_int *ipiv, double *b, const lapack_int *ldb, lapack_int *info); -void dgetri_(const lapack_int *n, double *a, const lapack_int *lda, +void FORTRAN_WRAPPER(dgetri)(const lapack_int *n, double *a, const lapack_int *lda, const lapack_int *ipiv, double *work, const lapack_int *lwork, lapack_int *info); -void dgesdd_(const char *jobz, const lapack_int *m, const lapack_int *n, +void FORTRAN_WRAPPER(dgesdd)(const char *jobz, const lapack_int *m, const lapack_int *n, double *a, const lapack_int *lda, double *s, double *u, const lapack_int *ldu, double *vt, const lapack_int *ldvt, double *work, const lapack_int *lwork, lapack_int *iwork, lapack_int *info); -void dsytrf_(const char *uplo, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dsytrf)(const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, lapack_int *ipiv, double *work, const lapack_int *lwork, lapack_int *info); -void dsytrs_(const char *uplo, const lapack_int *n, const lapack_int *nrhs, +void FORTRAN_WRAPPER(dsytrs)(const char *uplo, const lapack_int *n, const lapack_int *nrhs, const double *a, const lapack_int *lda, const lapack_int *ipiv, double *b, const lapack_int *ldb, lapack_int *info); -void dsytri_(const char *uplo, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dsytri)(const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, const lapack_int *ipiv, double *work, lapack_int *info); -void dpotf2_(const char *uplo, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dpotf2)(const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, lapack_int *info); -void dpotri_(const char *uplo, const lapack_int *n, double *a, +void FORTRAN_WRAPPER(dpotri)(const char *uplo, const lapack_int *n, double *a, const lapack_int *lda, lapack_int *info); #ifdef __cplusplus