Skip to content

Commit a85dc40

Browse files
committed
Modernize Dockerfile to build against current Python and GraphBLAS
The Dockerfile had bit-rotted: the python:3.10-slim-buster base image no longer builds (Debian buster apt repos are gone), and the most recent commit simultaneously dropped Python <=3.10 support in pyproject.toml while leaving the Dockerfile pinned to Python 3.10. Several install paths and cmake flags were also out of date for SuiteSparse:GraphBLAS 10.x. Changes: - Bump base image from python:3.10-slim-buster (EOL) to python:3.12-slim-bookworm. Update hardcoded python3.10 site-packages paths to python3.12 in three places. - Update GraphBLAS header copy: 10.x installs the header at /usr/include/suitesparse/GraphBLAS.h, not /usr/include/GraphBLAS.h, and create_headers.py looks for it at ${sys.prefix}/include/suitesparse/GraphBLAS.h. - Replace deprecated `python3 setup.py install` with `pip install --no-build-isolation --no-deps .`. The pip-driven path is required by modern setuptools, and pip is added to the build-time install list along with pycparser/setuptools/wheel/setuptools-git-versioning which the build now needs explicitly. - Add cmake flags matching CI in suitesparse.sh: -DCMAKE_BUILD_TYPE=Release, -DJITINIT=2, -DGRAPHBLAS_USE_JIT=OFF. The JIT flags avoid segfaults in tests; without them GraphBLAS may attempt JIT compilation at runtime. - Replace stale -DGBCOMPACT cmake flag with the current name -DCOMPACT, and give ARG COMPACT a default of 0 so the substitution is non-empty when the build-arg is omitted. - Make `git tag ${VERSION}` idempotent: wrap with `(... || true)` so the build does not fail when ${VERSION} matches an existing tag in the source tree (which is now the case for the current 10.3.1.0 release tag). - Fix Docker COPY collapsing the libgraphblas symlink chain (libgraphblas.so -> .so.10 -> .so.10.3.1) into three identical 67MB regular files. Copy only the real versioned library (libgraphblas.so.*.*.*) and recreate symlinks via `ln -sf` in a RUN step. Apply the same fix to libgomp in the final stage. This removes the `ldconfig: ... is not a symbolic link` warnings and saves ~130MB. - Cleanup: remove unused `ARG SUITESPARSE` redeclaration in the psg stage, fix the lowercase `as` -> `AS` for FromAsCasing warnings, and switch `ENV PYTHONUNBUFFERED 1` to the modern `ENV key=value` form. - Drop the bizarre `WORKDIR /build/GraphBLAS/build` that was set *before* the GraphBLAS git clone, producing the path /build/GraphBLAS/build/GraphBLAS/build. The clone now happens directly under /build. Built and verified by running the doctests inside the produced image: $ docker build --build-arg SUITESPARSE=v10.3.1 \\ --build-arg VERSION=10.3.1.0 \\ -t psg-test:latest . $ docker run --rm psg-test:latest python3 -c " import suitesparse_graphblas; suitesparse_graphblas.initialize() from suitesparse_graphblas.tests.test_doctest import test_run_doctests test_run_doctests()" -> 268 doctests pass, supports_complex=True
1 parent 61813ca commit a85dc40

1 file changed

Lines changed: 41 additions & 17 deletions

File tree

Dockerfile

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,71 @@
1-
ARG BASE_CONTAINER=python:3.10-slim-buster
2-
FROM ${BASE_CONTAINER} as suitesparse
1+
ARG BASE_CONTAINER=python:3.12-slim-bookworm
2+
FROM ${BASE_CONTAINER} AS suitesparse
33
ENV DEBIAN_FRONTEND=noninteractive
44

55
RUN apt-get update && apt-get install -yq build-essential cmake git
66

77
ARG SUITESPARSE
8-
ARG COMPACT
8+
ARG COMPACT=0
99

1010
WORKDIR /build
1111
RUN git clone https://github.com/eliben/pycparser.git --depth 1
1212

13-
WORKDIR /build/GraphBLAS/build
13+
# Use `-DJITINIT=2` so that the JIT functionality is available, but disabled by default.
14+
# Level 2, "run", means that pre-JIT kernels may be used, which does not require a compiler at runtime.
15+
# Disable JIT entirely to avoid segfaulting in tests (matches CI in suitesparse.sh).
1416
RUN git clone https://github.com/DrTimothyAldenDavis/GraphBLAS.git --depth 1 --branch ${SUITESPARSE} \
1517
&& cd GraphBLAS/build \
16-
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DGBCOMPACT=${COMPACT} \
18+
&& cmake .. \
19+
-DCMAKE_BUILD_TYPE=Release \
20+
-DCMAKE_INSTALL_PREFIX=/usr \
21+
-DCOMPACT=${COMPACT} \
22+
-DJITINIT=2 \
23+
-DGRAPHBLAS_USE_JIT=OFF \
1724
&& make -j$(nproc) \
1825
&& make install
1926

20-
FROM ${BASE_CONTAINER} as psg
21-
ARG SUITESPARSE
27+
FROM ${BASE_CONTAINER} AS psg
2228
ARG VERSION
23-
ENV PYTHONUNBUFFERED 1
29+
ENV PYTHONUNBUFFERED=1
2430

25-
COPY --from=suitesparse /usr/include/GraphBLAS.h /usr/local/include/
26-
COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas* /usr/lib/x86_64-linux-gnu/
27-
COPY --from=suitesparse /build/pycparser/utils/fake_libc_include/* /usr/local/lib/python3.10/site-packages/pycparser/utils/fake_libc_include/
31+
COPY --from=suitesparse /usr/include/suitesparse/GraphBLAS.h /usr/local/include/suitesparse/GraphBLAS.h
32+
# Copy only the real versioned library; recreate symlinks (Docker COPY collapses cross-stage symlinks).
33+
COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas.so.*.*.* /usr/lib/x86_64-linux-gnu/
34+
RUN cd /usr/lib/x86_64-linux-gnu \
35+
&& REAL=$(ls libgraphblas.so.*.*.*) \
36+
&& SOMAJOR=libgraphblas.so.$(echo "$REAL" | sed -E 's/libgraphblas\.so\.([0-9]+).*/\1/') \
37+
&& ln -sf "$REAL" "$SOMAJOR" \
38+
&& ln -sf "$SOMAJOR" libgraphblas.so \
39+
&& ldconfig
2840

2941
RUN apt-get update && apt-get install -yq build-essential git
30-
RUN pip3 install numpy cffi pytest cython
42+
RUN pip3 install --break-system-packages numpy cffi pytest cython pycparser setuptools wheel setuptools-git-versioning
43+
44+
COPY --from=suitesparse /build/pycparser/utils/fake_libc_include/* /usr/local/lib/python3.12/site-packages/pycparser/utils/fake_libc_include/
3145

3246
RUN mkdir -p /psg
3347
ADD . /psg
3448

3549
WORKDIR /psg
36-
RUN git tag ${VERSION} && \
50+
# `git tag || true` so the build is idempotent when ${VERSION} already matches an existing tag in the source tree.
51+
RUN (git tag ${VERSION} || true) && \
3752
python3 suitesparse_graphblas/create_headers.py && \
38-
python3 setup.py install && \
53+
pip3 install --break-system-packages --no-build-isolation --no-deps . && \
3954
ldconfig
4055

4156
#RUN pytest --pyargs suitesparse_graphblas.tests
4257
RUN apt-get -y --purge remove git python3-pip && apt-get clean
4358

4459
FROM ${BASE_CONTAINER}
45-
COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas* /usr/lib/x86_64-linux-gnu/
46-
COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgomp* /usr/lib/x86_64-linux-gnu/
47-
COPY --from=psg /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
60+
COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgraphblas.so.*.*.* /usr/lib/x86_64-linux-gnu/
61+
COPY --from=suitesparse /usr/lib/x86_64-linux-gnu/libgomp.so.*.*.* /usr/lib/x86_64-linux-gnu/
62+
COPY --from=psg /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
63+
RUN cd /usr/lib/x86_64-linux-gnu \
64+
&& GBREAL=$(ls libgraphblas.so.*.*.*) \
65+
&& GBSOMAJOR=libgraphblas.so.$(echo "$GBREAL" | sed -E 's/libgraphblas\.so\.([0-9]+).*/\1/') \
66+
&& ln -sf "$GBREAL" "$GBSOMAJOR" \
67+
&& ln -sf "$GBSOMAJOR" libgraphblas.so \
68+
&& GMREAL=$(ls libgomp.so.*.*.*) \
69+
&& GMSOMAJOR=libgomp.so.$(echo "$GMREAL" | sed -E 's/libgomp\.so\.([0-9]+).*/\1/') \
70+
&& ln -sf "$GMREAL" "$GMSOMAJOR" \
71+
&& ldconfig

0 commit comments

Comments
 (0)