Skip to content

Commit 8c24b01

Browse files
authored
Allow manylinux2010 build from manylinux2014 branch (#979)
1 parent 1b2b34b commit 8c24b01

18 files changed

+219
-34
lines changed

build.sh

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,23 @@ else
2424
fi
2525

2626
# setup BASEIMAGE and its specific properties
27-
if [ "${POLICY}" == "manylinux2014" ]; then
27+
if [ "${POLICY}" == "manylinux2010" ]; then
28+
if [ "${PLATFORM}" == "x86_64" ]; then
29+
BASEIMAGE="quay.io/pypa/manylinux2010_x86_64_centos6_no_vsyscall"
30+
elif [ "${PLATFORM}" == "i686" ]; then
31+
BASEIMAGE="${MULTIARCH_PREFIX}centos:6"
32+
else
33+
echo "Policy '${POLICY}' does not support platform '${PLATFORM}'"
34+
exit 1
35+
fi
36+
DEVTOOLSET_ROOTPATH="/opt/rh/devtoolset-8/root"
37+
PREPEND_PATH="${DEVTOOLSET_ROOTPATH}/usr/bin:"
38+
if [ "${PLATFORM}" == "i686" ]; then
39+
LD_LIBRARY_PATH_ARG="${DEVTOOLSET_ROOTPATH}/usr/lib:${DEVTOOLSET_ROOTPATH}/usr/lib/dyninst:/usr/local/lib"
40+
else
41+
LD_LIBRARY_PATH_ARG="${DEVTOOLSET_ROOTPATH}/usr/lib64:${DEVTOOLSET_ROOTPATH}/usr/lib:${DEVTOOLSET_ROOTPATH}/usr/lib64/dyninst:${DEVTOOLSET_ROOTPATH}/usr/lib/dyninst:/usr/local/lib64:/usr/local/lib"
42+
fi
43+
elif [ "${POLICY}" == "manylinux2014" ]; then
2844
if [ "${PLATFORM}" == "s390x" ]; then
2945
BASEIMAGE="s390x/clefos:7"
3046
else

docker/Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH_ARG}
2121
ENV PATH=${PREPEND_PATH}${PATH}
2222
ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
2323

24+
# first fixup mirrors, keep the script around
25+
COPY build_scripts/fixup-mirrors.sh /usr/local/sbin/fixup-mirrors
26+
RUN fixup-mirrors
27+
2428
# setup entrypoint, this will wrap commands with `linux32` with i686 images
2529
COPY build_scripts/install-entrypoint.sh /build_scripts/
2630
RUN bash /build_scripts/install-entrypoint.sh && rm -rf build_scripts
@@ -102,6 +106,12 @@ RUN export SQLITE_AUTOCONF_ROOT=sqlite-autoconf-3340000 && \
102106
export SQLITE_AUTOCONF_DOWNLOAD_URL=https://www.sqlite.org/2020 && \
103107
manylinux-entrypoint /build_scripts/build-sqlite3.sh
104108

109+
COPY build_scripts/build-openssl.sh /build_scripts/
110+
RUN export OPENSSL_ROOT=openssl-1.1.1i && \
111+
export OPENSSL_HASH=e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242 && \
112+
export OPENSSL_DOWNLOAD_URL=https://www.openssl.org/source && \
113+
manylinux-entrypoint /build_scripts/build-openssl.sh
114+
105115
COPY build_scripts/build-cpython.sh /build_scripts/
106116

107117

docker/build_scripts/build-cmake.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ rm -rf /manylinux-rootfs/usr/local/share/cmake-*/Help
3232
strip_ /manylinux-rootfs
3333

3434
# Install
35-
cp -rf /manylinux-rootfs/* /
35+
cp -rlf /manylinux-rootfs/* /
3636

3737

3838
cmake --version

docker/build_scripts/build-git.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ rm -rf ${GIT_ROOT} ${GIT_ROOT}.tar.gz
2828
strip_ /manylinux-rootfs
2929

3030
# Install
31-
cp -rf /manylinux-rootfs/* /
31+
cp -rlf /manylinux-rootfs/* /
3232

3333
git version

docker/build_scripts/build-openssl.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
# Top-level build script called from Dockerfile
3+
4+
# Stop at any error, show all commands
5+
set -exuo pipefail
6+
7+
# Get script directory
8+
MY_DIR=$(dirname "${BASH_SOURCE[0]}")
9+
10+
# Get build utilities
11+
source $MY_DIR/build_utils.sh
12+
13+
# Install a more recent openssl
14+
check_var ${OPENSSL_ROOT}
15+
check_var ${OPENSSL_HASH}
16+
check_var ${OPENSSL_DOWNLOAD_URL}
17+
18+
OPENSSL_VERSION=${OPENSSL_ROOT#*-}
19+
OPENSSL_MIN_VERSION=1.0.2
20+
21+
INSTALLED=$(openssl version | head -1 | awk '{ print $2 }')
22+
SMALLEST=$(echo -e "${INSTALLED}\n${OPENSSL_MIN_VERSION}" | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | head -1)
23+
if [ "${SMALLEST}" == "${OPENSSL_MIN_VERSION}" ]; then
24+
echo "skipping installation of openssl ${OPENSSL_VERSION}, system provides openssl ${INSTALLED} which is newer than openssl ${OPENSSL_MIN_VERSION}"
25+
exit 0
26+
fi
27+
28+
if which yum; then
29+
yum erase -y openssl-devel
30+
else
31+
apt-get remove -y libssl-dev
32+
fi
33+
34+
fetch_source ${OPENSSL_ROOT}.tar.gz ${OPENSSL_DOWNLOAD_URL}
35+
check_sha256sum ${OPENSSL_ROOT}.tar.gz ${OPENSSL_HASH}
36+
tar -xzf ${OPENSSL_ROOT}.tar.gz
37+
pushd ${OPENSSL_ROOT}
38+
./config no-shared -fPIC --prefix=/usr/local/ssl --openssldir=/usr/local/ssl > /dev/null
39+
make > /dev/null
40+
make install_sw > /dev/null
41+
popd
42+
rm -rf ${OPENSSL_ROOT} ${OPENSSL_ROOT}.tar.gz
43+
44+
45+
/usr/local/ssl/bin/openssl version

docker/build_scripts/build-sqlite3.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ rm /manylinux-rootfs/usr/local/lib/libsqlite3.a
2929
strip_ /manylinux-rootfs
3030

3131
# Install
32-
cp -rf /manylinux-rootfs/* /
32+
cp -rlf /manylinux-rootfs/* /
3333

3434
# Clean-up for runtime
3535
rm -rf /manylinux-rootfs/usr/local/bin /manylinux-rootfs/usr/local/include /manylinux-rootfs/usr/local/lib/pkg-config /manylinux-rootfs/usr/local/share

docker/build_scripts/build-swig.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ rm -rf ${SWIG_ROOT}*
3535
strip_ /manylinux-rootfs
3636

3737
# Install
38-
cp -rf /manylinux-rootfs/* /
38+
cp -rlf /manylinux-rootfs/* /
3939

4040
swig -version

docker/build_scripts/finalize.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ deactivate
5656
for PYTHON in /opt/python/*/bin/python; do
5757
# Smoke test to make sure that our Pythons work, and do indeed detect as
5858
# being manylinux compatible:
59-
$PYTHON $MY_DIR/manylinux-check.py
59+
$PYTHON $MY_DIR/manylinux-check.py ${AUDITWHEEL_POLICY} ${AUDITWHEEL_ARCH}
6060
# Make sure that SSL cert checking works
6161
$PYTHON $MY_DIR/ssl-check.py
6262
done

docker/build_scripts/fixup-mirrors.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
# Fix up mirrors once distro reaches EOL
3+
4+
# Stop at any error, show all commands
5+
set -exuo pipefail
6+
7+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ]; then
8+
# Centos 6 is EOL and is no longer available from the usual mirrors, so switch
9+
# to https://vault.centos.org
10+
sed -i 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf
11+
sed -i 's/^mirrorlist/#mirrorlist/g' /etc/yum.repos.d/*.repo
12+
sed -i 's;^.*baseurl=http://mirror;baseurl=https://vault;g' /etc/yum.repos.d/*.repo
13+
sed -i 's;^.*baseurl=http://download.fedoraproject.org/pub;baseurl=https://archives.fedoraproject.org/pub/archive;g' /etc/yum.repos.d/*.repo
14+
fi

docker/build_scripts/install-autoconf.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ rm -rf ${AUTOCONF_ROOT} ${AUTOCONF_ROOT}.tar.gz
3939
strip_ /manylinux-rootfs
4040

4141
# Install
42-
cp -rf /manylinux-rootfs/* /
42+
cp -rlf /manylinux-rootfs/* /
4343

4444
# Remove temporary rootfs
4545
rm -rf /manylinux-rootfs

docker/build_scripts/install-automake.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ rm -rf ${AUTOMAKE_ROOT} ${AUTOMAKE_ROOT}.tar.gz
3737
strip_ /manylinux-rootfs
3838

3939
# Install
40-
cp -rf /manylinux-rootfs/* /
40+
cp -rlf /manylinux-rootfs/* /
4141

4242
# Remove temporary rootfs
4343
rm -rf /manylinux-rootfs
Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
#!/bin/bash
2-
# Top-level build script called from Dockerfile
2+
# Install packages that will be needed at runtime
33

44
# Stop at any error, show all commands
5-
set -ex
5+
set -exuo pipefail
66

7-
# Set build environment variables
8-
MY_DIR=$(dirname "${BASH_SOURCE[0]}")
97

10-
# Dependencies for compiling Python that we want to remove from
11-
# the final image after compiling Python
12-
PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel expat-devel ncurses-devel readline-devel tk-devel gdbm-devel libdb-devel libpcap-devel xz-devel openssl-devel keyutils-libs-devel krb5-devel libcom_err-devel libidn-devel curl-devel perl-devel libffi-devel kernel-devel"
13-
CMAKE_DEPS="openssl-devel zlib-devel libcurl-devel"
8+
# if a devel package is added to COMPILE_DEPS,
9+
# make sure the corresponding library is added to RUNTIME_DEPS if applicable
1410

15-
# Development tools and libraries
16-
yum -y install ${PYTHON_COMPILE_DEPS} ${CMAKE_DEPS}
11+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ] || [ "${AUDITWHEEL_POLICY}" == "manylinux2014" ]; then
12+
PACKAGE_MANAGER=yum
13+
COMPILE_DEPS="zlib-devel bzip2-devel expat-devel ncurses-devel readline-devel tk-devel gdbm-devel libpcap-devel xz-devel openssl openssl-devel keyutils-libs-devel krb5-devel libcom_err-devel libidn-devel curl-devel uuid-devel libffi-devel kernel-headers"
14+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ]; then
15+
COMPILE_DEPS="${COMPILE_DEPS} db4-devel"
16+
else
17+
COMPILE_DEPS="${COMPILE_DEPS} libdb-devel"
18+
fi
19+
else
20+
echo "Unsupported policy: '${AUDITWHEEL_POLICY}'"
21+
exit 1
22+
fi
23+
24+
25+
if [ ${PACKAGE_MANAGER} == yum ]; then
26+
yum -y install ${COMPILE_DEPS}
27+
yum clean all
28+
rm -rf /var/cache/yum
29+
else
30+
echo "Not implemented"
31+
exit 1
32+
fi

docker/build_scripts/install-entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Stop at any error, show all commands
66
set -exuo pipefail
77

8-
if [ "${AUDITWHEEL_PLAT}" == "manylinux2014_i686" ]; then
8+
if [ "${AUDITWHEEL_PLAT}" == "manylinux2010_i686" ] || [ "${AUDITWHEEL_PLAT}" == "manylinux2014_i686" ]; then
99
echo "i386" > /etc/yum/vars/basearch
1010
yum -y update
1111
yum install -y util-linux-ng

docker/build_scripts/install-libtool.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ rm -rf ${LIBTOOL_ROOT} ${LIBTOOL_ROOT}.tar.gz
2626
strip_ /manylinux-rootfs
2727

2828
# Install
29-
cp -rf /manylinux-rootfs/* /
29+
cp -rlf /manylinux-rootfs/* /
3030

3131
# Remove temporary rootfs
3232
rm -rf /manylinux-rootfs

docker/build_scripts/install-libxcrypt.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ rm -rf "v${LIBXCRYPT_VERSION}.tar.gz" "libxcrypt-${LIBXCRYPT_VERSION}"
4141
strip_ /manylinux-rootfs
4242

4343
# Install
44-
cp -rf /manylinux-rootfs/* /
44+
cp -rlf /manylinux-rootfs/* /
4545

4646
# Remove temporary rootfs
4747
rm -rf /manylinux-rootfs

docker/build_scripts/install-patchelf.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ rm -rf ${PATCHELF_VERSION}.tar.gz patchelf-${PATCHELF_VERSION}
2727
strip_ /manylinux-rootfs
2828

2929
# Install
30-
cp -rf /manylinux-rootfs/* /
30+
cp -rlf /manylinux-rootfs/* /
3131

3232
# Remove temporary rootfs
3333
rm -rf /manylinux-rootfs

docker/build_scripts/install-runtime-packages.sh

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,47 @@ MY_DIR=$(dirname "${BASH_SOURCE[0]}")
2424
# PEP is missing the package for libSM.so.6 for RPM based system
2525

2626
# MANYLINUX_DEPS: Install development packages (except for libgcc which is provided by gcc install)
27-
# RUNTIME_DEPS: Runtime dependencies. c.f. build.sh
28-
if [ "${AUDITWHEEL_POLICY}" == "manylinux2014" ]; then
27+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ] || [ "${AUDITWHEEL_POLICY}" == "manylinux2014" ]; then
2928
MANYLINUX_DEPS="glibc-devel libstdc++-devel glib2-devel libX11-devel libXext-devel libXrender-devel mesa-libGL-devel libICE-devel libSM-devel"
30-
RUNTIME_DEPS="zlib bzip2 expat ncurses readline tk gdbm libdb libpcap xz openssl keyutils-libs libkadm5 libcom_err libidn libcurl uuid libffi"
3129
else
3230
echo "Unsupported policy: '${AUDITWHEEL_POLICY}'"
3331
exit 1
3432
fi
3533

36-
BASETOOLS="autoconf automake bison bzip2 diffutils file make patch unzip"
37-
if [ "${AUDITWHEEL_POLICY}" == "manylinux2014" ]; then
34+
# RUNTIME_DEPS: Runtime dependencies. c.f. install-build-packages.sh
35+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ] || [ "${AUDITWHEEL_POLICY}" == "manylinux2014" ]; then
36+
RUNTIME_DEPS="zlib bzip2 expat ncurses readline tk gdbm libpcap xz openssl keyutils-libs libkadm5 libcom_err libidn libcurl uuid libffi"
37+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ]; then
38+
RUNTIME_DEPS="${RUNTIME_DEPS} db4"
39+
else
40+
RUNTIME_DEPS="${RUNTIME_DEPS} libdb"
41+
fi
42+
else
43+
echo "Unsupported policy: '${AUDITWHEEL_POLICY}'"
44+
exit 1
45+
fi
46+
47+
BASETOOLS="autoconf automake bison bzip2 diffutils file hardlink make patch unzip"
48+
if [ "${AUDITWHEEL_POLICY}" == "manylinux2010" ]; then
49+
PACKAGE_MANAGER=yum
50+
BASETOOLS="${BASETOOLS} which"
51+
# See https://unix.stackexchange.com/questions/41784/can-yum-express-a-preference-for-x86-64-over-i386-packages
52+
echo "multilib_policy=best" >> /etc/yum.conf
53+
yum -y update
54+
yum -y install https://archives.fedoraproject.org/pub/archive/epel/6/x86_64/epel-release-6-8.noarch.rpm curl
55+
fixup-mirrors
56+
TOOLCHAIN_DEPS="devtoolset-8-binutils devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-gcc-gfortran yasm"
57+
if [ "${AUDITWHEEL_ARCH}" == "x86_64" ]; then
58+
# Software collection (for devtoolset-8)
59+
yum -y install centos-release-scl
60+
fixup-mirrors
61+
elif [ "${AUDITWHEEL_ARCH}" == "i686" ]; then
62+
# Add libgfortran4 for devtoolset-7 compat
63+
TOOLCHAIN_DEPS="${TOOLCHAIN_DEPS} libgfortran4"
64+
# Install mayeut/devtoolset-8 repo to get devtoolset-8
65+
curl -fsSLo /etc/yum.repos.d/mayeut-devtoolset-8.repo https://copr.fedorainfracloud.org/coprs/mayeut/devtoolset-8-i386/repo/custom-1/mayeut-devtoolset-8-i386-custom-1.repo
66+
fi
67+
elif [ "${AUDITWHEEL_POLICY}" == "manylinux2014" ]; then
3868
PACKAGE_MANAGER=yum
3969
BASETOOLS="${BASETOOLS} which"
4070
# See https://unix.stackexchange.com/questions/41784/can-yum-express-a-preference-for-x86-64-over-i386-packages

docker/build_scripts/manylinux-check.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,44 @@
1-
# Logic copied from PEP 599
1+
# Logic copied from PEP 513, PEP 599
22

33
import sys
44

55

6+
def is_manylinux1_compatible():
7+
# Only Linux, and only x86-64 / i686
8+
from distutils.util import get_platform
9+
if get_platform() not in ["linux-x86_64", "linux-i686"]:
10+
return False
11+
12+
# Check for presence of _manylinux module
13+
try:
14+
import _manylinux
15+
return bool(_manylinux.manylinux1_compatible)
16+
except (ImportError, AttributeError):
17+
# Fall through to heuristic check below
18+
pass
19+
20+
# Check glibc version. CentOS 5 uses glibc 2.5.
21+
return have_compatible_glibc(2, 5)
22+
23+
24+
def is_manylinux2010_compatible():
25+
# Only Linux, and only x86-64 / i686
26+
from distutils.util import get_platform
27+
if get_platform() not in ["linux-x86_64", "linux-i686"]:
28+
return False
29+
30+
# Check for presence of _manylinux module
31+
try:
32+
import _manylinux
33+
return bool(_manylinux.manylinux2010_compatible)
34+
except (ImportError, AttributeError):
35+
# Fall through to heuristic check below
36+
pass
37+
38+
# Check glibc version. CentOS 6 uses glibc 2.12.
39+
return have_compatible_glibc(2, 12)
40+
41+
642
def is_manylinux2014_compatible():
743
# Only Linux, and only supported architectures
844
from distutils.util import get_platform
@@ -58,9 +94,27 @@ def have_compatible_glibc(major, minimum_minor):
5894
return True
5995

6096

61-
if is_manylinux2014_compatible():
62-
print("%s is manylinux2014 compatible" % (sys.executable,))
63-
sys.exit(0)
64-
else:
65-
print("%s is NOT manylinux2014 compatible" % (sys.executable,))
66-
sys.exit(1)
97+
exit_code = 0
98+
99+
if sys.argv[2] in {"x86_64", "i686"} and (sys.argv[1] in {"manylinux1", "manylinux2010", "manylinux2014"} or sys.argv[1].startswith("manylinux_")):
100+
if is_manylinux1_compatible():
101+
print("%s %s is manylinux1 compatible" % (sys.argv[1], sys.executable))
102+
else:
103+
print("%s %s is NOT manylinux1 compatible" % (sys.argv[1], sys.executable))
104+
exit_code = 1
105+
106+
if sys.argv[2] in {"x86_64", "i686"} and (sys.argv[1] in {"manylinux2010", "manylinux2014"} or sys.argv[1].startswith("manylinux_")):
107+
if is_manylinux2010_compatible():
108+
print("%s %s is manylinux2010 compatible" % (sys.argv[1], sys.executable))
109+
else:
110+
print("%s %s is NOT manylinux2010 compatible" % (sys.argv[1], sys.executable))
111+
exit_code = 1
112+
113+
if sys.argv[1] in {"manylinux2014"} or sys.argv[1].startswith("manylinux_"):
114+
if is_manylinux2014_compatible():
115+
print("%s %s is manylinux2014 compatible" % (sys.argv[1], sys.executable))
116+
else:
117+
print("%s %s is NOT manylinux2014 compatible" % (sys.argv[1], sys.executable))
118+
exit_code = 1
119+
120+
sys.exit(exit_code)

0 commit comments

Comments
 (0)