Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
## OpenBLAS v0.3.34 (v0.3.34)

### 0.3.34.237.0 (2026-09~06)
### 0.3.34.237.1 (2026-10-09)

- Build every manylinux, musllinux and macOS wheel without a runtime
dependency on libgfortran, and therefore without libquadmath, which is only
ever pulled in as a dependency of libgfortran itself. This shrinks the
wheels and simplifies licensing.

- Update windows devstudio 2022 to 2026


### 0.3.34.237.0 (2026-09-06)
- pick up a fix for SVE indentification

### 0.3.34.106.0 (2026-08~08)
### 0.3.34.106.0 (2026-08-08)
- pick up a fix for windows threading

### 0.3.34.0.0 (2026-07-17)
Expand Down
29 changes: 2 additions & 27 deletions ci-repair-wheel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,8 @@ else
# rm dist/scipy_openblas*-none-any.whl
# rm {dest_dir}/*.whl

# Add an RPATH to libgfortran:
# https://github.com/pypa/auditwheel/issues/451
# Use zipfile since the manylinux images do not have `zip`
python3 -c "
import re, sys, zipfile, pathlib
whl = next(pathlib.Path(sys.argv[1]).glob('*.whl'))
with zipfile.ZipFile(whl, 'a') as z:
members = [m for m in z.namelist() if re.search(r'libgfortran', m)]
z.extractall(members=members)
" "$1"
patchelf --force-rpath --set-rpath '$ORIGIN' */lib/libgfortran*
python3 -c "
import sys, zipfile, pathlib, glob
whl = next(pathlib.Path(sys.argv[1]).glob('*.whl'))
patched = {f: pathlib.Path(f).read_bytes() for f in glob.glob('*/lib/libgfortran*')}

# Read all original entries, replacing patched one
entries = {}
with zipfile.ZipFile(whl, 'r') as z:
for item in z.infolist():
entries[item] = patched.get(item.filename, z.read(item.filename))

# Rewrite the archive
with zipfile.ZipFile(whl, 'w', compression=zipfile.ZIP_DEFLATED) as z:
for item, data in entries.items():
z.writestr(item, data)
" "$1"
# No libgfortran rpath fixup (auditwheel #451) any more: the wheels
# bundle no libgfortran, which is the only reason it was ever needed.
mkdir -p /output
# copy libs/openblas*.tar.gz to dist/
cp libs/openblas*.tar.gz /output/
Expand Down
25 changes: 25 additions & 0 deletions ci-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,28 @@ fi

$PYTHON -m pip install pkgconf
$PYTHON -m pkgconf scipy-openblas --cflags

# Check that the installed wheel carries no Fortran runtime.
source tools/gfortran_compat.sh

if [ "${INTERFACE64}" != "1" ]; then
pkgdir=$($PYTHON -c "import scipy_openblas32 as m, pathlib; print(pathlib.Path(m.__file__).parent)")
else
pkgdir=$($PYTHON -c "import scipy_openblas64 as m, pathlib; print(pathlib.Path(m.__file__).parent)")
fi
echo "checking installed package $pkgdir"

openblas_lib=$(ls "$pkgdir"/lib/libscipy_openblas*.so "$pkgdir"/lib/libscipy_openblas*.dylib 2>/dev/null | head -1 || true)
if [ -z "$openblas_lib" ]; then
echo "FAIL: no OpenBLAS library found under $pkgdir/lib"
exit 1
fi

# The library needs no Fortran runtime, so the wheel must not ship one.
found=$(find "$pkgdir" \( -name 'libgfortran*' -o -name 'libquadmath*' \) -print)
if [ -n "$found" ]; then
echo "FAIL: the wheel still bundles the Fortran runtime:"
echo "$found"
exit 1
fi
assert_no_fortran_runtime "$openblas_lib"
80 changes: 80 additions & 0 deletions patches/0001-allow-building-without-libgfortran.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
diff --git a/Makefile.system b/Makefile.system
index e8e732e9c..9b05ed213 100644
--- a/Makefile.system
+++ b/Makefile.system
@@ -1207,15 +1207,17 @@ FCOMMON_OPT += -Wall
FCOMMON_OPT += -frecursive
# work around ABI problem with passing single-character arguments
FCOMMON_OPT += -fno-optimize-sibling-calls
-#Don't include -lgfortran, when NO_LAPACK=1 or lsbcc
+#Don't include -lgfortran, when NO_LAPACK=1 or lsbcc or NO_LIBGFORTRAN=1
ifneq ($(NOFORTRAN), 1)
ifneq ($(NOFORTRAN), 2)
ifneq ($(NO_LAPACK), 1)
+ifneq ($(NO_LIBGFORTRAN), 1)
EXTRALIB += -lgfortran
endif
endif
endif
endif
+endif
ifdef NO_BINARY_MODE
ifeq ($(ARCH), $(filter $(ARCH),mips64))
ifdef BINARY64
@@ -1917,6 +1919,43 @@ export CROSS
export CROSS_SUFFIX
export NOFORTRAN
export C_LAPACK
+# NO_LIBGFORTRAN=1 builds a library with no runtime dependency on the Fortran
+# runtime. LIBGFORTRAN_COMPAT must point at an archive supplying the few
+# libgfortran entry points the Fortran LAPACK sources reference; the link
+# fails loudly if it does not cover them all. libquadmath goes away along
+# with libgfortran, being only ever a dependency of libgfortran itself.
+#
+# The archive is kept out of EXTRALIB on purpose: EXTRALIB is what
+# Makefile.install writes into the installed .pc file, and a build-time
+# absolute path has no business being there. It goes into
+# LIBGFORTRAN_COMPAT_LINK, which the shared-library link rules add directly,
+# and into FEXTRALIB, which is what the macOS dylib rule uses.
+#
+# Kept here, at the end and at top level, so it sees the final value of
+# FEXTRALIB whatever the USE_OPENMP and compiler conditionals above did.
+ifeq ($(NO_LIBGFORTRAN), 1)
+FEXTRALIB := $(filter-out -lgfortran -lquadmath,$(FEXTRALIB))
+ifneq ($(LIBGFORTRAN_COMPAT), )
+ifeq ($(OSNAME), Darwin)
+# ld64 has no --exclude-libs and needs none: the dylib link passes
+# -Wl,-exported_symbols_list,osx.def, which holds only the BLAS and LAPACK
+# names, so whatever the compat archive brings in is unexported already.
+# -dead_strip_dylibs is what macOS needs instead. The dylib is linked by the
+# gfortran driver, which appends -lgfortran itself whatever FEXTRALIB says;
+# this drops the load command of a dylib no symbol resolves to, taking
+# libgfortran -- and with it libgfortran's own libquadmath dependency -- out
+# of the result.
+LIBGFORTRAN_COMPAT_LINK = $(LIBGFORTRAN_COMPAT) -Wl,-dead_strip_dylibs
+else
+LIBGFORTRAN_COMPAT_LINK = -Wl,--exclude-libs,$(notdir $(LIBGFORTRAN_COMPAT)) $(LIBGFORTRAN_COMPAT)
+endif
+FEXTRALIB += $(LIBGFORTRAN_COMPAT_LINK)
+endif
+endif
+
+export LIBGFORTRAN_COMPAT
+export LIBGFORTRAN_COMPAT_LINK
+export NO_LIBGFORTRAN
export NO_FBLAS
export EXTRALIB
export CEXTRALIB
diff --git a/exports/Makefile b/exports/Makefile
index c4633143b..55f086297 100644
--- a/exports/Makefile
+++ b/exports/Makefile
@@ -213,7 +213,7 @@ else
ifneq ($(C_COMPILER), LSB)
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o ../$(LIBSONAME) \
-Wl,--whole-archive $< -Wl,--no-whole-archive \
- -Wl,-soname,$(INTERNALNAME) $(EXTRALIB)
+ -Wl,-soname,$(INTERNALNAME) $(EXTRALIB) $(LIBGFORTRAN_COMPAT_LINK)
$(CC) $(CFLAGS) $(LDFLAGS) -w -o linktest linktest.c ../$(LIBSONAME) $(FEXTRALIB) && echo OK.
else
#for LSB
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "scipy-openblas64"
# v0.3.34-237-g1ad90fb1
version = "0.3.34.237.0"
version = "0.3.34.237.1"
requires-python = ">=3.7"
description = "Provides OpenBLAS for python packaging"
readme = "README.md"
Expand Down
Loading
Loading