Skip to content

Commit

Permalink
tools/docker: rework python wheel generation
Browse files Browse the repository at this point in the history
* use of muslinux_1_2 instead of alpine
* use of manylinux_2_28
  * Fix auditwheel repair
  • Loading branch information
Mizux committed Jan 22, 2025
1 parent fab05c8 commit 4b5c09a
Show file tree
Hide file tree
Showing 9 changed files with 463 additions and 164 deletions.
99 changes: 61 additions & 38 deletions tools/docker/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,25 @@ help:
@echo -e "\t${BOLD}test_archives${RESET}: Test each OR-Tools archives for all ${BOLD}<distro>${RESET} and ${BOLD}<lang>${RESET}."
@echo
@echo -e "${BOLD}PYTHON TARGETS${RESET}"
@echo -e "\t${BOLD}python${RESET}: Build alpine and manylinux2014 python 'ortools' wheel packages (3.8+)."
@echo -e "\t${BOLD}python${RESET}: Build musllinux and manylinux python 'ortools' wheel packages (3.8+)."
@echo -e "\t${BOLD}python_<platform>${RESET}: Build all python 'ortools' wheel packages (3.8+) for a specific platform."
@echo -e "\t${BOLD}python_<platform>_<step>${RESET}: Build all python 'ortools' wheel packages (3.8+) for a specific platform."
@echo -e "\t${BOLD}python_<target>_<step>${RESET}: Build python 'ortools' wheel packages (3.8+) for a specific target."
@echo -e "\t${BOLD}save_python_<target>${RESET}: Save python 'ortools' image."
@echo -e "\t${BOLD}clean_python_<target>${RESET}: Clean manylinux2014 and alpine python 'ortools' wheel packages."
@echo -e "\t${BOLD}clean_python_<target>${RESET}: Clean manylinux and musllinux python 'ortools' wheel packages."
@echo -e "\t${BOLD}sh_python_<target>${RESET}: Run a container using the python 'ortools' image."
@echo
@echo -e "\t${BOLD}<platform>${RESET}:"
@echo -e "\t\t${BOLD}amd64${RESET}"
@echo -e "\t\t${BOLD}arm64v8${RESET}"
@echo -e "\t\t${BOLD}arm64${RESET}"
@echo
@echo -e "\t${BOLD}<target>${RESET}:"
@echo -e "\t\t${BOLD}<platform>_<distro>${RESET}"
@echo -e "\t\t${BOLD}<platform>_manylinux_cp<version>${RESET}"
@echo
@echo -e "\t${BOLD}<distro>${RESET}:"
@echo -e "\t\t${BOLD}alpine${RESET} (latest)"
@echo -e "\t\t${BOLD}manylinux${RESET} (manylinux2014)"
@echo -e "\t\t${BOLD}musllinux${RESET} (musllinux_1_2)"
@echo -e "\t\t${BOLD}manylinux${RESET} (manylinux_2_28)"
@echo
@echo -e "\t${BOLD}<version>${RESET}:"
@echo -e "\t\t${BOLD}38${RESET} Python3.8"
Expand All @@ -68,7 +68,7 @@ help:
@echo -e "\t\t${BOLD}test${RESET}"
@echo -e "\t\t${BOLD}export${RESET}"
@echo -e "\te.g. 'make python_amd64_manylinux_cp39_export'"
@echo -e "\te.g. 'make python_arm64v8_alpine_export'"
@echo -e "\te.g. 'make python_arm64_musllinux_export'"
@echo
@echo
@echo -e "${BOLD}ARCHIVE TARGETS${RESET}"
Expand Down Expand Up @@ -187,8 +187,8 @@ test_delivery: test_archives
# $* stem
# $< first prerequist
# $@ target name
PYTHON_PLATFORMS := amd64 arm64v8
PYTHON_DISTROS := manylinux alpine
PYTHON_PLATFORMS := amd64 arm64
PYTHON_DISTROS := manylinux musllinux
PYTHON_STAGES := env devel build test

export:
Expand Down Expand Up @@ -230,9 +230,8 @@ python_$1_manylinux_cp$2_$3: python/$1/manylinux.Dockerfile export/python/manyli

.PHONY: save_python_$1_manylinux_cp$2_$3
save_python_$1_manylinux_cp$2_$3: cache/python/docker_$1_manylinux_cp$2_$3.tar
cache/python/docker_$1_manylinux_cp$2_$3.tar: python_$1_manylinux_cp$2_$3
cache/python/docker_$1_manylinux_cp$2_$3.tar: python_$1_manylinux_cp$2_$3 | cache/python
@rm -f $$@
mkdir -p cache/python/
docker save ${IMAGE}:$$< -o $$@

.PHONY: clean_python_$1_manylinux_cp$2_$3
Expand Down Expand Up @@ -266,7 +265,7 @@ python_$1_manylinux_cp$2_export: python_$1_manylinux_cp$2_build
endef

$(foreach version,${PYTHON_VERSIONS},$(eval $(call manylinux_outer,amd64,${version})))
$(foreach version,${PYTHON_VERSIONS},$(eval $(call manylinux_outer,arm64v8,${version})))
$(foreach version,${PYTHON_VERSIONS},$(eval $(call manylinux_outer,arm64,${version})))

# Merge
define manylinux_merge =
Expand All @@ -281,60 +280,84 @@ clean_python_$1_manylinux_$2: $(addprefix clean_python_$1_manylinux_cp, $(addsuf
endef

$(foreach stage,${PYTHON_STAGES} export,$(eval $(call manylinux_merge,amd64,${stage})))
$(foreach stage,${PYTHON_STAGES} export,$(eval $(call manylinux_merge,arm64v8,${stage})))
$(foreach stage,${PYTHON_STAGES} export,$(eval $(call manylinux_merge,arm64,${stage})))

## ALPINE ##
export/python/alpine: | export/python
## MUSLLINUX ##
export/python/musllinux: | export/python
-mkdir -p $@

define alpine_loop =
#$$(info alpine_loop: PLATFORM:'$1' STAGE:'$2')
export/python/musllinux/build-musllinux.sh: python/build-musllinux.sh | export/python/musllinux
cp $< $@

define musllinux_inner =
#$$(info musllinux_inner: PLATFORM:'$1' VERSION:'$2' STAGE:'$3')

.PHONY: python_$1_alpine_$2
python_$1_alpine_$2: python/$1/alpine.Dockerfile | export/python/alpine
.PHONY: python_$1_musllinux_cp$2_$3
python_$1_musllinux_cp$2_$3: python/$1/musllinux.Dockerfile | export/python/musllinux/build-musllinux.sh
@docker image rm -f ${IMAGE}:$$@ 2>/dev/null
${DOCKER_BUILD_CMD} \
${DOCKER_BUILDX_CMD} --platform linux/$1 \
--tag ${IMAGE}:$$@ \
--build-arg GIT_BRANCH=${OR_TOOLS_BRANCH} \
--build-arg GIT_SHA1=${OR_TOOLS_SHA1} \
--build-arg OR_TOOLS_PATCH=${OR_TOOLS_PATCH} \
--target=$2 \
--build-arg PYTHON_VERSION=$2 \
--target=$3 \
-f $$< \
export/python/alpine
export/python/musllinux

.PHONY: save_python_$1_alpine_$2
save_python_$1_alpine_$2: cache/python/docker_$1_alpine_$2.tar
cache/python/docker_$1_alpine_$2.tar: python_$1_alpine_$2 | cache/python
.PHONY: save_python_$1_musllinux_cp$2_$3
save_python_$1_musllinux_cp$2_$3: cache/python/docker_$1_musllinux_cp$2_$3.tar
cache/python/docker_$1_musllinux_cp$2_$3.tar: python_$1_musllinux_cp$2_$3 | cache/python
@rm -f $$@
docker save ${IMAGE}:$$< -o $$@

.PHONY: clean_python_$1_alpine_$2
clean_python_$1_alpine_$2: python/$1/alpine.Dockerfile | export/python/alpine
docker image rm -f ${IMAGE}:python_$1_alpine_$2 2>/dev/null
rm -f cache/python/docker_$1_alpine_$2.tar
.PHONY: clean_python_$1_musllinux_cp$2_$3
clean_python_$1_musllinux_cp$2_$3: python/$1/musllinux.Dockerfile | export/python/musllinux/build-musllinux.sh
docker image rm -f ${IMAGE}:python_$1_musllinux_cp$2_$3 2>/dev/null
rm -f cache/python/docker_$1_musllinux_cp$2_$3.tar

# Debug purpose
.PHONY: sh_python_$1_alpine_$2
sh_python_$1_alpine_$2: python_$1_alpine_$2
.PHONY: sh_python_$1_musllinux_cp$2_$3
sh_python_$1_musllinux_cp$2_$3: python_$1_musllinux_cp$2_$3
${DOCKER_RUN_CMD} \
-v `pwd`/export:/export \
-it \
--name ortools_$$< \
${IMAGE}:$$<
endef

$(foreach stage,${PYTHON_STAGES},$(eval $(call alpine_loop,amd64,${stage})))
$(foreach stage,${PYTHON_STAGES},$(eval $(call alpine_loop,arm64v8,${stage})))
define musllinux_outer =
#$$(info musllinux_outer: PLATFORM: '$1' VERSION: '$2')

alpine_export_targets = $(addprefix python_, $(addsuffix _alpine_export, ${PYTHON_PLATFORMS}))
.PHONY: ${alpine_export_targets}
${alpine_export_targets}: python_%_alpine_export: python_%_alpine_build | export
$$(foreach stage,${PYTHON_STAGES},$$(eval $$(call musllinux_inner,$1,$2,$${stage})))

.PHONY: python_$1_musllinux_cp$2_export
python_$1_musllinux_cp$2_export: python_$1_musllinux_cp$2_build
${DOCKER_RUN_CMD} \
-v `pwd`/export:/export \
-it \
--name ortools_$< \
${IMAGE}:$< \
--name ortools_$$< \
${IMAGE}:$$< \
"cp build*/python/dist/*.whl /export/python"
endef

$(foreach version,${PYTHON_VERSIONS},$(eval $(call musllinux_outer,amd64,${version})))
$(foreach version,${PYTHON_VERSIONS},$(eval $(call musllinux_outer,arm64,${version})))

# Merge
define musllinux_merge =
#$$(info musllinux_merge: PLATFORM:'$1' STAGE:'$2')

.PHONY: python_$1_musllinux_$2
python_$1_musllinux_$2: $(addprefix python_$1_musllinux_cp, $(addsuffix _$2, ${PYTHON_VERSIONS}))
.PHONY: save_python_$1_musllinux_$2
save_python_$1_musllinux_$2: $(addprefix save_python_$1_musllinux_cp, $(addsuffix _$2, ${PYTHON_VERSIONS}))
.PHONY: clean_python_$1_musllinux_$2
clean_python_$1_musllinux_$2: $(addprefix clean_python_$1_musllinux_cp, $(addsuffix _$2, ${PYTHON_VERSIONS}))
endef

$(foreach stage,${PYTHON_STAGES} export,$(eval $(call musllinux_merge,amd64,${stage})))
$(foreach stage,${PYTHON_STAGES} export,$(eval $(call musllinux_merge,arm64,${stage})))

## MERGE DISTRO ##
define python_distro_merge =
Expand All @@ -349,7 +372,7 @@ clean_python_$1_$2: $(addprefix clean_python_$1_, $(addsuffix _$2, ${PYTHON_DIST
endef

$(foreach stage,${PYTHON_STAGES} export,$(eval $(call python_distro_merge,amd64,${stage})))
$(foreach stage,${PYTHON_STAGES} export,$(eval $(call python_distro_merge,arm64v8,${stage})))
$(foreach stage,${PYTHON_STAGES} export,$(eval $(call python_distro_merge,arm64,${stage})))

## MERGE PLATFORM ##
define clean_python_platform =
Expand Down
52 changes: 0 additions & 52 deletions tools/docker/python/amd64/alpine.Dockerfile

This file was deleted.

20 changes: 11 additions & 9 deletions tools/docker/python/amd64/manylinux.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
FROM quay.io/pypa/manylinux2014_x86_64:latest AS env
# note: CMake 3.30.5 and SWIG 4.2.1 are already installed
FROM quay.io/pypa/manylinux_2_28_x86_64:latest AS env
# note: Almalinux:8 based image with
# CMake 3.31.2 and SWIG 4.3.0 already installed

RUN yum -y update \
&& yum -y install \
RUN dnf -y update \
&& dnf -y install \
curl wget \
git patch \
which pkgconfig autoconf libtool \
make gcc-c++ \
redhat-lsb openssl-devel pcre2-devel \
zlib-devel unzip zip \
&& yum clean all \
&& rm -rf /var/cache/yum
&& dnf clean all \
&& rm -rf /var/cache/dnf
ENTRYPOINT ["/usr/bin/bash", "-c"]
CMD ["/usr/bin/bash"]

Expand All @@ -36,13 +37,14 @@ RUN git clone -b "${GIT_BRANCH}" --single-branch "$GIT_URL" /project \
&& git reset --hard "${GIT_SHA1}"
WORKDIR /project

# Copy build script and setup env
ENV PLATFORM x86_64
ARG PYTHON_VERSION
ENV PYTHON_VERSION ${PYTHON_VERSION:-3}
COPY build-manylinux.sh .
RUN chmod a+x "build-manylinux.sh"

FROM devel AS build
ENV PLATFORM x86_64
ARG PYTHON_VERSION
ENV PYTHON_VERSION ${PYTHON_VERSION:-3}
RUN ./build-manylinux.sh build

FROM build as test
Expand Down
46 changes: 46 additions & 0 deletions tools/docker/python/amd64/musllinux.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
FROM quay.io/pypa/musllinux_1_2_x86_64:latest AS env
# CMake 3.31.2 and SWIG 4.3.0 already installed

# Install system build dependencies
ENV PATH=/usr/local/bin:$PATH
RUN apk add --no-cache git build-base linux-headers xfce4-dev-tools
ENTRYPOINT ["/bin/sh", "-c"]
CMD ["/bin/sh"]

## Python
#RUN apk add --no-cache python3-dev py3-pip py3-wheel py3-virtualenv \
# py3-numpy py3-pandas py3-matplotlib
#RUN rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED \
#&& python3 -m pip install absl-py mypy mypy-protobuf

################
## OR-TOOLS ##
################
FROM env AS devel
ENV GIT_URL https://github.com/google/or-tools

ARG GIT_BRANCH
ENV GIT_BRANCH ${GIT_BRANCH:-main}
ARG GIT_SHA1
ENV GIT_SHA1 ${GIT_SHA1:-unknown}

# Download sources
# use GIT_SHA1 to modify the command
# i.e. avoid docker reusing the cache when new commit is pushed
RUN git clone -b "${GIT_BRANCH}" --single-branch "$GIT_URL" /project \
&& cd /project \
&& git reset --hard "${GIT_SHA1}"
WORKDIR /project

# Copy build script and setup env
ENV PLATFORM x86_64
ARG PYTHON_VERSION
ENV PYTHON_VERSION ${PYTHON_VERSION:-3}
COPY build-musllinux.sh .
RUN chmod a+x "build-musllinux.sh"

FROM devel AS build
RUN ./build-musllinux.sh build

FROM build as test
RUN ./build-musllinux.sh test
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# To build it on x86_64 please read
# https://github.com/multiarch/qemu-user-static#getting-started
FROM quay.io/pypa/manylinux2014_aarch64:latest AS env
# note: CMake 3.30.5 and SWIG 4.2.1 are already installed
FROM quay.io/pypa/manylinux_2_28_aarch64:latest AS env
# note: Almalinux:8 based image with
# CMake 3.31.2 and SWIG 4.3.0 already installed

RUN yum -y update \
&& yum -y install \
RUN dnf -y update \
&& dnf -y install \
curl wget \
git patch \
which pkgconfig autoconf libtool \
make gcc-c++ \
redhat-lsb openssl-devel pcre2-devel \
zlib-devel unzip zip \
&& yum clean all \
&& rm -rf /var/cache/yum
&& dnf clean all \
&& rm -rf /var/cache/dnf
ENTRYPOINT ["/usr/bin/bash", "-c"]
CMD ["/usr/bin/bash"]

Expand All @@ -38,13 +39,14 @@ RUN git clone -b "${GIT_BRANCH}" --single-branch "$GIT_URL" /project \
&& git reset --hard "${GIT_SHA1}"
WORKDIR /project

# Copy build script and setup env
ENV PLATFORM aarch64
ARG PYTHON_VERSION
ENV PYTHON_VERSION ${PYTHON_VERSION:-3}
COPY build-manylinux.sh .
RUN chmod a+x "build-manylinux.sh"

FROM devel AS build
ENV PLATFORM aarch64
ARG PYTHON_VERSION
ENV PYTHON_VERSION ${PYTHON_VERSION:-3}
RUN ./build-manylinux.sh build

FROM build as test
Expand Down
Loading

0 comments on commit 4b5c09a

Please sign in to comment.