|
| 1 | +#!/bin/bash |
| 2 | +# Top-level build script called from Dockerfile |
| 3 | + |
| 4 | +# Stop at any error, show all commands |
| 5 | +set -ex |
| 6 | + |
| 7 | +# Python versions to be installed in /opt/$VERSION_NO |
| 8 | +# NOTE Only need python 2.7.11 for nupic.core/nupic.bindings at this time, so |
| 9 | +# remove others to expedite build and reduce docker image size. The original |
| 10 | +# manylinux docker image project builds many python versions. |
| 11 | +# NOTE We added back 3.5.1, since auditwheel requires python 3.3+ |
| 12 | +CPYTHON_VERSIONS="2.7.11 3.5.1" |
| 13 | + |
| 14 | +# openssl version to build, with expected sha256 hash of .tar.gz |
| 15 | +# archive |
| 16 | +OPENSSL_ROOT=openssl-1.0.2l |
| 17 | +OPENSSL_HASH=ce07195b659e75f4e1db43552860070061f156a98bb37b672b101ba6e3ddf30c |
| 18 | +EPEL_RPM_HASH=e5ed9ecf22d0c4279e92075a64c757ad2b38049bcf5c16c4f2b75d5f6860dc0d |
| 19 | +DEVTOOLS_HASH=a8ebeb4bed624700f727179e6ef771dafe47651131a00a78b342251415646acc |
| 20 | +PATCHELF_HASH=d9afdff4baeacfbc64861454f368b7f2c15c44d245293f7587bbf726bfe722fb |
| 21 | +CURL_ROOT=curl-7.49.1 |
| 22 | +CURL_HASH=eb63cec4bef692eab9db459033f409533e6d10e20942f4b060b32819e81885f1 |
| 23 | +AUTOCONF_ROOT=autoconf-2.69 |
| 24 | +AUTOCONF_HASH=954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969 |
| 25 | + |
| 26 | +# Dependencies for compiling Python that we want to remove from |
| 27 | +# the final image after compiling Python |
| 28 | +PYTHON_COMPILE_DEPS="zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel" |
| 29 | + |
| 30 | +# Libraries that are allowed as part of the manylinux1 profile |
| 31 | +MANYLINUX1_DEPS="glibc-devel libstdc++-devel glib2-devel libX11-devel libXext-devel libXrender-devel mesa-libGL-devel libICE-devel libSM-devel ncurses-devel" |
| 32 | + |
| 33 | +# Get build utilities |
| 34 | +MY_DIR=$(dirname "${BASH_SOURCE[0]}") |
| 35 | +source $MY_DIR/build_utils.sh |
| 36 | + |
| 37 | +# EPEL support |
| 38 | +yum -y install wget curl |
| 39 | +curl -sLO https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm |
| 40 | +check_sha256sum epel-release-6-8.noarch.rpm $EPEL_RPM_HASH |
| 41 | + |
| 42 | +# Dev toolset (for LLVM and other projects requiring C++11 support) |
| 43 | +curl -sLO http://people.centos.org/tru/devtools-2/devtools-2.repo |
| 44 | +check_sha256sum devtools-2.repo $DEVTOOLS_HASH |
| 45 | +mv devtools-2.repo /etc/yum.repos.d/devtools-2.repo |
| 46 | +rpm -Uvh --replacepkgs epel-release-6*.rpm |
| 47 | +rm -f epel-release-6*.rpm |
| 48 | + |
| 49 | +# Development tools and libraries |
| 50 | +yum -y install bzip2 make git patch unzip bison yasm diffutils \ |
| 51 | + automake which file \ |
| 52 | + kernel-devel-`uname -r` \ |
| 53 | + devtoolset-2-binutils devtoolset-2-gcc \ |
| 54 | + devtoolset-2-gcc-c++ devtoolset-2-gcc-gfortran \ |
| 55 | + ${PYTHON_COMPILE_DEPS} |
| 56 | + |
| 57 | +# Install more recent version of cmake |
| 58 | +# curl -O https://cmake.org/files/v3.8/cmake-3.8.1-Linux-x86_64.sh |
| 59 | +# /bin/sh cmake-3.8.1-Linux-x86_64.sh --prefix=/usr/local --skip-license |
| 60 | +# rm cmake-3.8.1-Linux-x86_64.sh |
| 61 | + |
| 62 | +wget -q https://cmake.org/files/v3.5/cmake-3.5.2.tar.gz && tar xzf cmake-3.5.2.tar.gz && \ |
| 63 | +cd cmake-3.5.2 && ./bootstrap && \ |
| 64 | +make -j4 && make install && cd .. && rm cmake-3.5.2.tar.gz |
| 65 | + |
| 66 | + |
| 67 | +# Install newest autoconf |
| 68 | +build_autoconf $AUTOCONF_ROOT $AUTOCONF_HASH |
| 69 | +autoconf --version |
| 70 | + |
| 71 | +# Compile the latest Python releases. |
| 72 | +# (In order to have a proper SSL module, Python is compiled |
| 73 | +# against a recent openssl [see env vars above], which is linked |
| 74 | +# statically. We delete openssl afterwards.) |
| 75 | +build_openssl $OPENSSL_ROOT $OPENSSL_HASH |
| 76 | +mkdir -p /opt/python |
| 77 | +build_cpythons $CPYTHON_VERSIONS |
| 78 | + |
| 79 | +PY35_BIN=/opt/python/cp35-cp35m/bin |
| 80 | +# NOTE Since our custom manylinux image builds pythons with shared |
| 81 | +# libpython, we need to add libpython's dir to LD_LIBRARY_PATH before running |
| 82 | +# python. |
| 83 | +ORIGINAL_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" |
| 84 | +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname ${PY35_BIN})/lib" |
| 85 | + |
| 86 | +# Our openssl doesn't know how to find the system CA trust store |
| 87 | +# (https://github.com/pypa/manylinux/issues/53) |
| 88 | +# And it's not clear how up-to-date that is anyway |
| 89 | +# So let's just use the same one pip and everyone uses |
| 90 | +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname ${PY35_BIN})/lib" $PY35_BIN/pip install certifi |
| 91 | +ln -s $($PY35_BIN/python -c 'import certifi; print(certifi.where())') \ |
| 92 | + /opt/_internal/certs.pem |
| 93 | +# If you modify this line you also have to modify the versions in the |
| 94 | +# Dockerfiles: |
| 95 | +export SSL_CERT_FILE=/opt/_internal/certs.pem |
| 96 | + |
| 97 | +# Install newest curl |
| 98 | +build_curl $CURL_ROOT $CURL_HASH |
| 99 | +rm -rf /usr/local/include/curl /usr/local/lib/libcurl* /usr/local/lib/pkgconfig/libcurl.pc |
| 100 | +hash -r |
| 101 | +curl --version |
| 102 | +curl-config --features |
| 103 | + |
| 104 | +# Now we can delete our built SSL |
| 105 | +rm -rf /usr/local/ssl |
| 106 | + |
| 107 | +# Install patchelf (latest with unreleased bug fixes) |
| 108 | +curl -sLO https://nipy.bic.berkeley.edu/manylinux/patchelf-0.9njs2.tar.gz |
| 109 | +check_sha256sum patchelf-0.9njs2.tar.gz $PATCHELF_HASH |
| 110 | +tar -xzf patchelf-0.9njs2.tar.gz |
| 111 | +(cd patchelf-0.9njs2 && ./configure && make && make install) |
| 112 | +rm -rf patchelf-0.9njs2.tar.gz patchelf-0.9njs2 |
| 113 | + |
| 114 | +# Install latest pypi release of auditwheel |
| 115 | +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname ${PY35_BIN})/lib" $PY35_BIN/pip install auditwheel |
| 116 | +ln -s $PY35_BIN/auditwheel /usr/local/bin/auditwheel |
| 117 | + |
| 118 | +# Clean up development headers and other unnecessary stuff for |
| 119 | +# final image |
| 120 | +yum -y erase wireless-tools gtk2 libX11 hicolor-icon-theme \ |
| 121 | + avahi freetype bitstream-vera-fonts \ |
| 122 | + ${PYTHON_COMPILE_DEPS} > /dev/null 2>&1 |
| 123 | +yum -y install ${MANYLINUX1_DEPS} |
| 124 | +yum -y clean all > /dev/null 2>&1 |
| 125 | +yum list installed |
| 126 | +# we don't need libpython*.a, and they're many megabytes |
| 127 | +find /opt/_internal -name '*.a' -print0 | xargs -0 rm -f |
| 128 | +# Strip what we can -- and ignore errors, because this just attempts to strip |
| 129 | +# *everything*, including non-ELF files: |
| 130 | +find /opt/_internal -type f -print0 \ |
| 131 | + | xargs -0 -n1 strip --strip-unneeded 2>/dev/null || true |
| 132 | +# We do not need the Python test suites, or indeed the precompiled .pyc and |
| 133 | +# .pyo files. Partially cribbed from: |
| 134 | +# https://github.com/docker-library/python/blob/master/3.4/slim/Dockerfile |
| 135 | +find /opt/_internal \ |
| 136 | + \( -type d -a -name test -o -name tests \) \ |
| 137 | + -o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) \ |
| 138 | + -print0 | xargs -0 rm -f |
| 139 | + |
| 140 | +for PYTHON in /opt/python/*/bin/python; do |
| 141 | + # Add matching directory of libpython shared library to library lookup path |
| 142 | + LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname $(dirname ${PYTHON}))/lib" |
| 143 | + |
| 144 | + # Smoke test to make sure that our Pythons work, and do indeed detect as |
| 145 | + # being manylinux compatible: |
| 146 | + LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname $(dirname ${PYTHON}))/lib" $PYTHON $MY_DIR/manylinux1-check.py |
| 147 | + # Make sure that SSL cert checking works |
| 148 | + LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}:$(dirname $(dirname ${PYTHON}))/lib" $PYTHON $MY_DIR/ssl-check.py |
| 149 | +done |
| 150 | + |
| 151 | +# Restore LD_LIBRARY_PATH |
| 152 | +LD_LIBRARY_PATH="${ORIGINAL_LD_LIBRARY_PATH}" |
0 commit comments