diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index bbd61d9c..c2b34608 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -115,6 +115,7 @@ jobs: fi sed -e "s/bin/lib/" -i local/scipy_openblas64/lib/cmake/openblas/OpenBLASConfig.cmake sed -e "s/dll/lib/" -i local/scipy_openblas64/lib/cmake/openblas/OpenBLASConfig.cmake + mkdir local/scipy_openblas64/lib/pkgconfig if [[ "${INTERFACE64}" != "1" ]]; then mv local/scipy_openblas64 local/scipy_openblas32 # rewrite the name of the project to scipy-openblas32 @@ -125,6 +126,9 @@ jobs: sed -e "s/cflags =.*/cflags = '-DBLAS_SYMBOL_PREFIX=scipy_'/" -i local/scipy_openblas32/__init__.py sed -e "s/openblas64/openblas32/" -i local/scipy_openblas32/__init__.py sed -e "s/openblas64/openblas32/" -i local/scipy_openblas32/__main__.py + PYTHONPATH=$PWD/local python -c "import scipy_openblas32 as s; print(s.get_pkg_config(use_prefix=True))" > local/scipy_openblas32/lib/pkgconfig/scipy-openblas.pc + else + PYTHONPATH=$PWD/local python -c "import scipy_openblas64 as s; print(s.get_pkg_config(use_prefix=True))" > local/scipy_openblas64/lib/pkgconfig/scipy-openblas.pc fi echo "" >> LICENSE.txt echo "----" >> LICENSE.txt @@ -153,6 +157,8 @@ jobs: python -m pip install --no-index --find-links dist scipy_openblas64 python -m scipy_openblas64 python -c "import scipy_openblas64; print(scipy_openblas64.get_pkg_config())" + python -m pip install pkgconf + python -m pkgconf scipy-openblas --cflags - name: Test 32-bit interface wheel if: matrix.INTERFACE64 != '1' @@ -160,6 +166,8 @@ jobs: python -m pip install --no-index --find-links dist scipy_openblas32 python -m scipy_openblas32 python -c "import scipy_openblas32; print(scipy_openblas32.get_pkg_config())" + python -m pip install pkgconf + python -m pkgconf scipy-openblas --cflags - uses: conda-incubator/setup-miniconda@v3.1.1 with: diff --git a/README.md b/README.md index 650b06dc..813b16a4 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ First, tarballs are built using `build_lib` in `tools/build_steps.sh` (on posix in a docker and drectly on macos) or `tools/build_steps_windows.sh` on windows. Then the shared object and header files from the tarball are used to build the -wheel via `tools/build_wheel.sh`, and the wheels uploaded to +wheel via `tools/build_prepare_wheel.sh` and `pip build wheel`, and the wheels uploaded to https://anaconda.org/scientific=python-nightly-wheels/scipy_openblas32 and https://anaconda.org/scientific=python-nightly-wheels/scipy_openblas64 via `tools/upload_to_anaconda_staging.sh`. For a release, the wheels are uploaded diff --git a/ci-before-build.sh b/ci-before-build.sh index 83fbe493..1288d9da 100755 --- a/ci-before-build.sh +++ b/ci-before-build.sh @@ -73,4 +73,4 @@ unset -f popd source build-openblas.sh # Build wheel -source tools/build_prepare.sh +source tools/build_prepare_wheel.sh diff --git a/ci-test.sh b/ci-test.sh index 1a553636..326a5822 100755 --- a/ci-test.sh +++ b/ci-test.sh @@ -20,3 +20,6 @@ else # $PYTHON -m pip install --no-index --find-links /tmp/cibuildwheel/repaired_wheel scipy_openblas64 $PYTHON -m scipy_openblas64 fi + +$PYTHON -m pip install pkgconf +$PYTHON -m pkgconf scipy-openblas --cflags diff --git a/local/scipy_openblas64/__init__.py b/local/scipy_openblas64/__init__.py index 3d34ef76..59e7214a 100644 --- a/local/scipy_openblas64/__init__.py +++ b/local/scipy_openblas64/__init__.py @@ -60,17 +60,20 @@ def get_library(fullname=False): # remove the leading lib from libscipy_openblas* return os.path.splitext(libs[0])[0][3:] -def get_pkg_config(use_preloading=False): +def get_pkg_config(use_preloading=False, use_prefix=False): """Return a multi-line string that, when saved to a file, can be used with pkg-config for build systems like meson If use_preloading is True then on posix the ``Libs:`` directive will not add ``f"-L{get_library()}" so that at runtime this module must be imported before the target module + + If use_prefix is True, then `pcfiledir` will be used and the file should be + stored in `dirname(__file__)/lib/pkgconfig` for use with pkgconf-pypi """ - machine = platform.machine().lower() extralib = "" if sys.platform == "win32": + machine = platform.machine().lower() if machine != "arm64": extralib = "-defaultlib:advapi32 -lgfortran -lquadmath" libs_flags = f"-L${{libdir}} -l{get_library()}" @@ -81,9 +84,16 @@ def get_pkg_config(use_preloading=False): else: libs_flags = f"${{libdir}}/{get_library(fullname=True)} -Wl,-rpath,${{libdir}}" cflags = "-DBLAS_SYMBOL_PREFIX=scipy_ -DBLAS_SYMBOL_SUFFIX=64_ -DHAVE_BLAS_ILP64 -DOPENBLAS_ILP64_NAMING_SCHEME" + if use_prefix: + libdir = "${pcfiledir}/../../lib" + incdir = "${pcfiledir}/../../include" + else: + # Don't use `$prefix` since the file may be located outside the package tree + libdir = get_lib_dir() + incdir = get_include_dir() return dedent(f"""\ - libdir={get_lib_dir()} - includedir={get_include_dir()} + libdir={libdir} + includedir={incdir} openblas_config= {get_openblas_config()} version={get_openblas_config().split(" ")[1]} extralib={extralib} diff --git a/pyproject.toml b/pyproject.toml index c538cb82..9922c2c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta" [project] name = "scipy-openblas64" # v0.3.30-359-g29fab2b9 -version = "0.3.30.359.1" +version = "0.3.30.359.2" requires-python = ">=3.7" description = "Provides OpenBLAS for python packaging" readme = "README.md" @@ -57,3 +57,6 @@ environment-pass = [ ] [tool.cibuildwheel.linux] environment = { CC = "/opt/clang/bin/clang", CXX = "/opt/clang/bin/clang++", LDFLAGS = "-fuse-ld=lld" } + +[project.entry-points.pkg_config] +scipy-openblas = 'scipy_openblas64.lib.pkgconfig' diff --git a/tools/build_prepare.sh b/tools/build_prepare_wheel.sh similarity index 82% rename from tools/build_prepare.sh rename to tools/build_prepare_wheel.sh index dbfc303d..a6ef2604 100644 --- a/tools/build_prepare.sh +++ b/tools/build_prepare_wheel.sh @@ -11,7 +11,6 @@ PYTHON=${PYTHON:-python3.9} mkdir -p local/openblas mkdir -p dist -$PYTHON -m pip install wheel auditwheel tar -C local/scipy_openblas64 --strip-components=2 -xf libs/openblas.tar.gz @@ -40,6 +39,7 @@ if [ $(uname) == "Darwin" ]; then fi rm -rf local/scipy_openblas64/lib/pkgconfig +mkdir local/scipy_openblas64/lib/pkgconfig echo "" >> LICENSE.txt echo "----" >> LICENSE.txt echo "" >> LICENSE.txt @@ -49,6 +49,11 @@ else cat tools/LICENSE_linux.txt >> LICENSE.txt fi +if [ "$(uname)" == "Darwin" -a "${PLAT}" == "x86_64" ]; then + PYTHON="arch -x86_64 python3" +else + PYTHON=python3 +fi if [ "${INTERFACE64}" != "1" ]; then # rewrite the name of the project to scipy-openblas32 # this is a hack, but apparently there is no other way to change the name @@ -63,6 +68,9 @@ if [ "${INTERFACE64}" != "1" ]; then sed -e "s/openblas64/openblas32/" -i.bak local/scipy_openblas32/__main__.py sed -e "s/openblas64/openblas32/" -i.bak local/scipy_openblas32/__init__.py rm local/scipy_openblas32/*.bak + PYTHONPATH=$PWD/local $PYTHON -c "import scipy_openblas32 as s; print(s.get_pkg_config(use_prefix=True))" > local/scipy_openblas32/lib/pkgconfig/scipy-openblas.pc +else + PYTHONPATH=$PWD/local $PYTHON -c "import scipy_openblas64 as s; print(s.get_pkg_config(use_prefix=True))" > local/scipy_openblas64/lib/pkgconfig/scipy-openblas.pc fi rm -rf dist/* diff --git a/tools/build_steps_win_arm64.bat b/tools/build_steps_win_arm64.bat index 21c997c4..9b78ce0c 100755 --- a/tools/build_steps_win_arm64.bat +++ b/tools/build_steps_win_arm64.bat @@ -118,20 +118,23 @@ if errorlevel 1 exit /b 1 echo Build complete. Returning to Batch. +cd ../.. if "%if_bits%"=="32" ( echo Rewrite to scipy_openblas32 - cd ../.. set out_pyproject=pyproject_64_32.toml powershell -Command "(Get-Content 'pyproject.toml') -replace 'openblas64', 'openblas32' | Set-Content !out_pyproject!" - powershell -Command "(Get-Content 'local\scipy_openblas32\__main__.py') -replace 'openblas64', 'openblas32' | Out-File 'local\scipy_openblas32\__main__.py' -Encoding utf8" - powershell -Command "(Get-Content 'local\scipy_openblas32\__init__.py') -replace 'openblas64', 'openblas32' | Out-File 'local\scipy_openblas32\__init__.py' -Encoding utf8" - powershell -Command "(Get-Content 'local\scipy_openblas32\__init__.py') -replace 'openblas_get_config64_', 'openblas_get_config' | Out-File 'local\scipy_openblas32\__init__.py' -Encoding utf8" - powershell -Command "(Get-Content 'local\scipy_openblas32\__init__.py') -replace 'cflags =.*', 'cflags = \"-DBLAS_SYMBOL_PREFIX=scipy_\"' | Out-File 'local\scipy_openblas32\__init__.py' -Encoding utf8" + cd local + move scipy_openblas64 scipy_openblas32 + powershell -Command "(Get-Content 'scipy_openblas32\__main__.py') -replace 'openblas64', 'openblas32' | Out-File 'scipy_openblas32\__main__.py' -Encoding utf8" + powershell -Command "(Get-Content 'scipy_openblas32\__init__.py') -replace 'openblas64', 'openblas32' | Out-File 'scipy_openblas32\__init__.py' -Encoding utf8" + powershell -Command "(Get-Content 'scipy_openblas32\__init__.py') -replace 'openblas_get_config64_', 'openblas_get_config' | Out-File 'scipy_openblas32\__init__.py' -Encoding utf8" + powershell -Command "(Get-Content 'scipy_openblas32\__init__.py') -replace 'cflags =.*', 'cflags = \"-DBLAS_SYMBOL_PREFIX=scipy_\"' | Out-File 'local\scipy_openblas32\__init__.py' -Encoding utf8" + cd .. ) :: Prepare destination directory cd OpenBLAS/build -echo Preparing destination directory at %DEST_DIR%... +echo Preparing destination directory at %DEST_DIR% if not exist "%DEST_DIR%\lib\cmake\OpenBLAS" mkdir "%DEST_DIR%\lib\cmake\OpenBLAS" if not exist "%DEST_DIR%\include" mkdir "%DEST_DIR%\include" @@ -167,12 +170,34 @@ if exist openblas_config.h copy /Y openblas_config.h "%DEST_DIR%\include\" echo Copying LAPACKE header files... xcopy /Y "..\lapack-netlib\lapacke\include\*.h" "%DEST_DIR%\include\" if errorlevel 1 exit /b 1 - + +echo Create pkgconfig scipy-openblas.pc +cd ../../local +if errorlevel 1 ( + echo Current directory %CD%, cannot cd ../../local + exit /b 1 +) +if "%if_bits%"=="32" ( + mkdir scipy_openblas32\lib\pkgconfig + python -c "import scipy_openblas32 as s; print(s.get_pkg_config(use_prefix=True))" > scipy_openblas32/lib/pkgconfig/scipy-openblas.pc +) else ( + mkdir scipy_openblas64\lib\pkgconfig + python -c "import scipy_openblas64 as s; print(s.get_pkg_config(use_prefix=True))" > scipy_openblas64/lib/pkgconfig/scipy-openblas.pc +) +if errorlevel 1 ( + echo could not construct scipy-openblas.pc + exit /b 1 +) + :: Move back to the root directory -cd ../.. +cd .. +if errorlevel 1 ( + echo Current directory %CD%, cannot cd .. + exit /b 1 +) :: Build the Wheel & Install It -echo Running 'python -m build' to build the wheel... +echo Running 'python -m build' to build the wheel in %CD% python -c "import build" 2>NUL || pip install build if "%if_bits%"=="64" ( python -m build @@ -208,5 +233,10 @@ echo Installing wheel: %WHEEL_FILE% pip install "%WHEEL_FILE%" if errorlevel 1 exit /b 1 +echo Testing +python -m pip install pkgconf +python -m pkgconf scipy-openblas --cflags +if errorlevel 1 exit /b 1 + echo Done. exit /b 0 diff --git a/tools/build_wheel.sh b/tools/build_wheel.sh deleted file mode 100644 index cb3aa921..00000000 --- a/tools/build_wheel.sh +++ /dev/null @@ -1,52 +0,0 @@ -#! /bin/bash -# Needs: -# $INTERFACE64 ("1" or "0") -# $PLAT (x86_64, i686, arm64, aarch64, s390x, ppc64le) - -set -xe - -if [[ ! -e tools/build_prepare.sh ]];then - cd /openblas -fi - -source tools/build_prepare.sh - -$PYTHON -m pip wheel -w dist -v . - -echo "Repairing wheel with auditwheel" -auditwheel repair -w dist --lib-sdir /lib dist/*.whl -echo "Wheel repaired." - -rm dist/*none-linux*.whl - -ls -l dist/ - -# Add an RPATH to libgfortran: -# https://github.com/pypa/auditwheel/issues/451 -if [ "$MB_ML_LIBC" == "musllinux" ]; then - apk add zip -else - yum install -y zip -fi -unzip dist/*.whl "*libgfortran*" -patchelf --force-rpath --set-rpath '$ORIGIN' */lib/libgfortran* -zip dist/*.whl */lib/libgfortran* - -echo "Final wheel contents:" - -ls -l dist/ - -echo "Testing the wheel" - -# Test that the wheel works with a different python -PYTHON=python3.11 - -if [ "${INTERFACE64}" != "1" ]; then - $PYTHON -m pip install --no-index --find-links dist scipy_openblas32 - $PYTHON -m scipy_openblas32 -else - $PYTHON -m pip install --no-index --find-links dist scipy_openblas64 - $PYTHON -m scipy_openblas64 -fi - -echo "Wheel test successful."