Skip to content

Commit

Permalink
tools/docker: rework python jobs
Browse files Browse the repository at this point in the history
* use manylinux_2_28
* use muslinux_1_2

ref: https://github.com/pypa/manylinux?tab=readme-ov-file#docker-images
  • Loading branch information
Mizux committed Jan 17, 2025
1 parent d4b9dd8 commit 91d2df4
Show file tree
Hide file tree
Showing 9 changed files with 469 additions and 155 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_BUILD_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')

$$(foreach stage,${PYTHON_STAGES},$$(eval $$(call musllinux_inner,$1,$2,$${stage})))

alpine_export_targets = $(addprefix python_, $(addsuffix _alpine_export, ${PYTHON_PLATFORMS}))
.PHONY: ${alpine_export_targets}
${alpine_export_targets}: python_%_alpine_export: python_%_alpine_build | export
.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.

13 changes: 7 additions & 6 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 Down
60 changes: 60 additions & 0 deletions tools/docker/python/amd64/musllinux.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
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
WORKDIR /root
RUN git clone -b "${GIT_BRANCH}" --single-branch "$GIT_URL" /project \
&& cd /project \
&& git reset --hard "${GIT_SHA1}"
WORKDIR /project

COPY build-musllinux.sh .
RUN chmod a+x "build-musllinux.sh"

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

FROM build as test
RUN ./build-musllinux.sh test

## Build project
#FROM devel AS build
#RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_DEPS=ON -DBUILD_PYTHON=ON -DVENV_USE_SYSTEM_SITE_PACKAGES=ON \
# -DBUILD_CXX_SAMPLES=OFF -DBUILD_CXX_EXAMPLES=OFF
#RUN cmake --build build -v -j8
## Rename wheel package ortools-version+musl-....
#RUN cp build/python/dist/ortools-*.whl .
#RUN NAME=$(ls *.whl | sed -e "s/\(ortools-[0-9\.]\+\)/\1+musl/") && mv *.whl "${NAME}"
#RUN rm build/python/dist/ortools-*.whl
#RUN mv *.whl build/python/dist/
#
#FROM build AS test
#RUN cmake --build build --target 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 Down
Loading

0 comments on commit 91d2df4

Please sign in to comment.