├── .gitignore ├── .travis.yml ├── LICENSE ├── README.rst └── docker ├── Dockerfile-x86_64 ├── build_scripts ├── build_utils.sh ├── manylinux-check.py ├── python-tag-abi-tag.py ├── requirements-pre-7.3.0.txt ├── requirements.txt └── ssl-check.py ├── build_scripts_pypy ├── install_pypy.sh └── prefetch_pypy.sh └── deploy.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # prefetched sources 2 | docker/sources 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # pyenv 79 | .python-version 80 | 81 | # celery beat schedule file 82 | celerybeat-schedule 83 | 84 | # SageMath parsed files 85 | *.sage.py 86 | 87 | # Environments 88 | .env 89 | .venv 90 | env/ 91 | venv/ 92 | ENV/ 93 | env.bak/ 94 | venv.bak/ 95 | 96 | # Spyder project settings 97 | .spyderproject 98 | .spyproject 99 | 100 | # Rope project settings 101 | .ropeproject 102 | 103 | # mkdocs documentation 104 | /site 105 | 106 | # mypy 107 | .mypy_cache/ 108 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | dist: trusty 3 | services: 4 | - docker 5 | 6 | cache: 7 | directories: 8 | - $HOME/docker 9 | 10 | env: 11 | global: 12 | # DOCKERPASS 13 | - secure: "Vlh5o7wH3AVM234pGD2QaFkXm267cIXPnowAsn+j5HB7B0P1r88EuSTr83ZsaS/5K4r/7w11VIt0qmg2d9lhCL00+QKnawimu0MrXcevesjFYetyrfxv0G+ofEn/R1KhEhqarCBk20ng1cEcPCx7p7Dg2R9oHAGHnooapLWdEb5xCE7djgOoulsOC4SNX4s5Pt9biEFwNS9TRzTjfpxR0kAcd6EYrdxIRJ6d2pwzdHWU6LYiEybLpkwRZysgcSSJeFiziIoYUglUPDXg+xAZA/vBSZQqmnjCa7VgcBU3znewgF7Nkz7vCaoHCZF60C7Ri2nkzRLkUgz0UjrxAKfDznqwFtMzy1dJ2xYqM+Pj1xXWUkf3hiT0AZfEMqx+9Tv4LEXwJuP519i0ZVcd4JrD7YkSntO9LQN9Xi5Z09dZlfAsKxEfP0o8gy4dnXTzIQczaMK/HHp1VEtErVEoIHydmio1Jwhf5/NQawsoP4MFP84Lb4G6SKPWkdQC+CYLg4nyo58dMUC5943z2vUzI/Fe37HLmFLkTUUsOcYpFkS5be//d2kqM2av+8gXOkVNpgX4H1rBsNGdc3Z/vv3neogzO3y1eDr/aDcKwlXkGgMcw9q+MIJ01h9rGN45d/723xC07F0lFKoPDtPenUCoWAzXXxuJjZdqWvxB7jrEQlzIUyg=" 14 | 15 | 16 | jobs: 17 | include: 18 | - stage: "Build pypy/manylinux images" 19 | 20 | script: 21 | - TRAVIS_COMMIT=$TRAVIS_COMMIT ./build.sh 22 | 23 | deploy: 24 | provider: script 25 | script: docker/deploy.sh 26 | on: 27 | branch: master 28 | repo: pypy/manylinux 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Antonio Cuni 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | manylinux for PyPy - archived 2 | ============================= 3 | 4 | .. note:: 5 | **This repo is archived. Please use the official manylinux_ images instead** 6 | 7 | Older info 8 | ---------- 9 | 10 | .. image:: https://travis-ci.org/pypy/manylinux.svg?branch=master 11 | :target: https://travis-ci.org/pypy/manylinux 12 | 13 | `Docker image`_ for building PyPy manylinux_ wheels. 14 | 15 | This image extends the official manylinux image by installing PyPy. For now, 16 | the only supported platform is ``x86_64``. 17 | 18 | .. _`Docker image`: https://hub.docker.com/r/pypywheels/manylinux2010-pypy_x86_64 19 | .. _manylinux: https://github.com/pypa/manylinux 20 | 21 | At the moment of writing, this image provide the following versions of 22 | PyPy: 23 | 24 | - PyPy2.7 7.3.4 25 | 26 | - PyPy3.7 7.3.4 27 | 28 | - PyPy3.6 7.3.3 29 | 30 | - PyPy2.7 7.2.0 31 | 32 | - PyPy3.6 7.2.0 33 | 34 | Live example 35 | ------------- 36 | 37 | `pypy-manylinux-demo`_ is an example project which demonstrate how to build 38 | CPython and PyPy wheels using Travis CI and this image. It is a fork of the 39 | official `python-manylinux-demo`, and shows that building wheels for PyPy is 40 | as easy as changing the image name! 41 | 42 | .. _`pypy-manylinux-demo`: https://github.com/pypy/pypy-manylinux-demo 43 | .. _`python-manylinux-demo`: https://github.com/pypa/python-manylinux-demo 44 | 45 | How to run PyPy 46 | ---------------- 47 | 48 | The various PyPy versions are installed inside ``/opt/pypy/``, and they are 49 | also symlinked to ``/opt/python``. Moreover, each installation of PyPy 50 | contains also a ``python`` symlink. 51 | 52 | All the following commands are equivalent and run the PyPy 2.7, version 53 | 7.3.4. You can use whatever fits best in your build system: 54 | 55 | - ``/opt/pypy/pypy2.7-7.3.4/bin/pypy`` 56 | 57 | - ``/opt/pypy/pypy2.7-7.3.4/bin/python`` 58 | 59 | - ``/opt/python/pp27-pypy_73/bin/pypy`` 60 | 61 | - ``/opt/python/pp27-pypy_73/bin/python`` 62 | 63 | Similarly, these are the commands to run PyPy 3.7, version 7.3.4: 64 | 65 | - ``/opt/pypy/pypy3.7-7.3.4/bin/pypy`` 66 | 67 | - ``/opt/pypy/pypy3.7-7.3.4/bin/python`` 68 | 69 | - ``/opt/python/pp37-pypy37_pp73/bin/pypy`` 70 | 71 | - ``/opt/python/pp37-pypy37_pp73/bin/python`` 72 | 73 | The paths for PyPy 7.3.3 Python 3.6 are completely analogous to the ones for 3.7. 74 | 75 | 76 | PEP 425 Compatibility tags 77 | --------------------------- 78 | 79 | ``pp27-pypy_73`` and ``pp36-pypy36_pp73`` are the `PEP 425`_ compliant 80 | compatibility tag. In particular: 81 | 82 | - ``pp`` stands for PyPy (as opposed to ``cp`` which is CPython) 83 | 84 | - ``27`` and ``37`` mean "Python 2.7|3.7" 85 | 86 | - ``pypy_73`` and ``pypy37_pp73`` (or before PyPy 7.3.0, ``pypy_41`` and 87 | ``pypy3_71``) are the binary ABI tags for the relevant version of PyPy. 88 | You can probably ignore them. 89 | 90 | Before pip 20 and wheel 0.34, tags looked like ``pp273-pypy_73`` or 91 | ``pp373-pypy36_pp73``, where ``273`` and ``373`` mean "Python [2|3]", 92 | "PyPy 7.3.x". Pre-7.3.0 versions of PyPy do not support pip>=20, and thus 93 | still rely on these old PyPy PEP 425 tags. 94 | 95 | .. _`PEP 425`: https://www.python.org/dev/peps/pep-0425/ 96 | -------------------------------------------------------------------------------- /docker/Dockerfile-x86_64: -------------------------------------------------------------------------------- 1 | FROM quay.io/pypa/manylinux2010_x86_64 2 | LABEL maintainer="Antonio Cuni" 3 | 4 | COPY build_scripts /build_scripts 5 | COPY build_scripts_pypy /build_scripts_pypy 6 | RUN : \ 7 | && build_scripts_pypy/prefetch_pypy.sh \ 8 | && build_scripts_pypy/install_pypy.sh \ 9 | && rm -rf /sources /build_scripts* 10 | 11 | CMD ["/bin/bash"] 12 | -------------------------------------------------------------------------------- /docker/build_scripts/build_utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Helper utilities for build 3 | 4 | 5 | function check_var { 6 | if [ -z "$1" ]; then 7 | echo "required variable not defined" 8 | exit 1 9 | fi 10 | } 11 | 12 | 13 | function lex_pyver { 14 | # Echoes Python version string padded with zeros 15 | # Thus: 16 | # 3.2.1 -> 003002001 17 | # 3 -> 003000000 18 | echo $1 | awk -F "." '{printf "%03d%03d%03d", $1, $2, $3}' 19 | } 20 | 21 | 22 | function pyver_dist_dir { 23 | # Echoes the dist directory name of given pyver, removing alpha/beta prerelease 24 | # Thus: 25 | # 3.2.1 -> 3.2.1 26 | # 3.7.0b4 -> 3.7.0 27 | echo $1 | awk -F "." '{printf "%d.%d.%d", $1, $2, $3}' 28 | } 29 | 30 | 31 | function do_cpython_build { 32 | local py_ver=$1 33 | check_var $py_ver 34 | local ucs_setting=$2 35 | check_var $ucs_setting 36 | tar -xzf Python-$py_ver.tgz 37 | pushd Python-$py_ver 38 | if [ "$ucs_setting" = "none" ]; then 39 | unicode_flags="" 40 | dir_suffix="" 41 | else 42 | local unicode_flags="--enable-unicode=$ucs_setting" 43 | local dir_suffix="-$ucs_setting" 44 | fi 45 | local prefix="/opt/_internal/cpython-${py_ver}${dir_suffix}" 46 | mkdir -p ${prefix}/lib 47 | ./configure --prefix=${prefix} --disable-shared $unicode_flags > /dev/null 48 | make -j2 > /dev/null 49 | make install > /dev/null 50 | popd 51 | rm -rf Python-$py_ver 52 | # Some python's install as bin/python3. Make them available as 53 | # bin/python. 54 | if [ -e ${prefix}/bin/python3 ]; then 55 | ln -s python3 ${prefix}/bin/python 56 | fi 57 | ${prefix}/bin/python get-pip.py 58 | if [ -e ${prefix}/bin/pip3 ] && [ ! -e ${prefix}/bin/pip ]; then 59 | ln -s pip3 ${prefix}/bin/pip 60 | fi 61 | # Since we fall back on a canned copy of get-pip.py, we might not have 62 | # the latest pip and friends. Upgrade them to make sure. 63 | ${prefix}/bin/pip install -U --require-hashes -r ${MY_DIR}/requirements.txt 64 | local abi_tag=$(${prefix}/bin/python ${MY_DIR}/python-tag-abi-tag.py) 65 | ln -s ${prefix} /opt/python/${abi_tag} 66 | } 67 | 68 | 69 | function build_cpython { 70 | local py_ver=$1 71 | check_var $py_ver 72 | check_var $PYTHON_DOWNLOAD_URL 73 | local py_dist_dir=$(pyver_dist_dir $py_ver) 74 | curl -fsSLO $PYTHON_DOWNLOAD_URL/$py_dist_dir/Python-$py_ver.tgz 75 | curl -fsSLO $PYTHON_DOWNLOAD_URL/$py_dist_dir/Python-$py_ver.tgz.asc 76 | gpg --verify Python-$py_ver.tgz.asc 77 | if [ $(lex_pyver $py_ver) -lt $(lex_pyver 3.3) ]; then 78 | do_cpython_build $py_ver ucs2 79 | do_cpython_build $py_ver ucs4 80 | else 81 | do_cpython_build $py_ver none 82 | fi 83 | rm -f Python-$py_ver.tgz 84 | rm -f Python-$py_ver.tgz.asc 85 | } 86 | 87 | 88 | function build_cpythons { 89 | check_var $GET_PIP_URL 90 | curl -fsSLO $GET_PIP_URL 91 | # Import public keys used to verify downloaded Python source tarballs. 92 | # https://www.python.org/static/files/pubkeys.txt 93 | gpg --import ${MY_DIR}/cpython-pubkeys.txt 94 | for py_ver in $@; do 95 | build_cpython $py_ver 96 | done 97 | # Remove GPG hidden directory. 98 | rm -rf /root/.gnupg/ 99 | rm -f get-pip.py 100 | } 101 | 102 | 103 | function do_openssl_build { 104 | ./config no-ssl2 no-shared -fPIC --prefix=/usr/local/ssl > /dev/null 105 | make > /dev/null 106 | make install_sw > /dev/null 107 | } 108 | 109 | 110 | function check_required_source { 111 | local file=$1 112 | check_var ${file} 113 | if [ ! -f $file ]; then 114 | echo "Required source archive must be prefetched to docker/sources/ with prefetch.sh: $file" 115 | return 1 116 | fi 117 | } 118 | 119 | 120 | function fetch_source { 121 | # This is called both inside and outside the build context (e.g. in Travis) to prefetch 122 | # source tarballs, where curl exists (and works) 123 | local file=$1 124 | check_var ${file} 125 | local url=$2 126 | check_var ${url} 127 | if [ -f ${file} ]; then 128 | echo "${file} exists, skipping fetch" 129 | else 130 | curl -fsSL -o ${file} ${url}/${file} 131 | fi 132 | } 133 | 134 | 135 | function check_sha256sum { 136 | local fname=$1 137 | check_var ${fname} 138 | local sha256=$2 139 | check_var ${sha256} 140 | 141 | echo "${sha256} ${fname}" > ${fname}.sha256 142 | sha256sum -c ${fname}.sha256 143 | rm -f ${fname}.sha256 144 | } 145 | 146 | 147 | function build_openssl { 148 | local openssl_fname=$1 149 | check_var ${openssl_fname} 150 | local openssl_sha256=$2 151 | check_var ${openssl_sha256} 152 | # Can't use curl here because we don't have it yet, OpenSSL must be prefetched 153 | check_required_source ${openssl_fname}.tar.gz 154 | check_sha256sum ${openssl_fname}.tar.gz ${openssl_sha256} 155 | tar -xzf ${openssl_fname}.tar.gz 156 | (cd ${openssl_fname} && do_openssl_build) 157 | rm -rf ${openssl_fname} ${openssl_fname}.tar.gz 158 | } 159 | 160 | 161 | function build_git { 162 | local git_fname=$1 163 | check_var ${git_fname} 164 | local git_sha256=$2 165 | check_var ${git_sha256} 166 | check_var ${GIT_DOWNLOAD_URL} 167 | fetch_source v${git_fname}.tar.gz ${GIT_DOWNLOAD_URL} 168 | check_sha256sum v${git_fname}.tar.gz ${git_sha256} 169 | tar -xzf v${git_fname}.tar.gz 170 | (cd git-${git_fname} && make install prefix=/usr/local NO_GETTEXT=1 NO_TCLTK=1 LDFLAGS="-L/usr/local/ssl/lib -ldl" CFLAGS="-I/usr/local/ssl/include" > /dev/null) 171 | rm -rf git-${git_fname} v${git_fname}.tar.gz 172 | } 173 | 174 | 175 | function do_curl_build { 176 | # We do this shared to avoid obnoxious linker issues where git couldn't 177 | # link properly. If anyone wants to make this build statically go for it. 178 | LIBS=-ldl CFLAGS=-Wl,--exclude-libs,ALL ./configure --with-ssl --disable-static > /dev/null 179 | make > /dev/null 180 | make install > /dev/null 181 | } 182 | 183 | 184 | function build_curl { 185 | local curl_fname=$1 186 | check_var ${curl_fname} 187 | local curl_sha256=$2 188 | check_var ${curl_sha256} 189 | check_var ${CURL_DOWNLOAD_URL} 190 | # Can't use curl here because we don't have it yet...we are building it. It must be prefetched 191 | check_required_source ${curl_fname}.tar.gz 192 | check_sha256sum ${curl_fname}.tar.gz ${curl_sha256} 193 | tar -zxf ${curl_fname}.tar.gz 194 | (cd curl-*/ && do_curl_build) 195 | rm -rf curl-* 196 | } 197 | 198 | 199 | function do_standard_install { 200 | ./configure > /dev/null 201 | make > /dev/null 202 | make install > /dev/null 203 | } 204 | 205 | 206 | function build_autoconf { 207 | local autoconf_fname=$1 208 | check_var ${autoconf_fname} 209 | local autoconf_sha256=$2 210 | check_var ${autoconf_sha256} 211 | check_var ${AUTOCONF_DOWNLOAD_URL} 212 | fetch_source ${autoconf_fname}.tar.gz ${AUTOCONF_DOWNLOAD_URL} 213 | check_sha256sum ${autoconf_fname}.tar.gz ${autoconf_sha256} 214 | tar -zxf ${autoconf_fname}.tar.gz 215 | (cd ${autoconf_fname} && do_standard_install) 216 | rm -rf ${autoconf_fname} ${autoconf_fname}.tar.gz 217 | } 218 | 219 | 220 | function build_automake { 221 | local automake_fname=$1 222 | check_var ${automake_fname} 223 | local automake_sha256=$2 224 | check_var ${automake_sha256} 225 | check_var ${AUTOMAKE_DOWNLOAD_URL} 226 | fetch_source ${automake_fname}.tar.gz ${AUTOMAKE_DOWNLOAD_URL} 227 | check_sha256sum ${automake_fname}.tar.gz ${automake_sha256} 228 | tar -zxf ${automake_fname}.tar.gz 229 | (cd ${automake_fname} && do_standard_install) 230 | rm -rf ${automake_fname} ${automake_fname}.tar.gz 231 | } 232 | 233 | 234 | function build_libtool { 235 | local libtool_fname=$1 236 | check_var ${libtool_fname} 237 | local libtool_sha256=$2 238 | check_var ${libtool_sha256} 239 | check_var ${LIBTOOL_DOWNLOAD_URL} 240 | fetch_source ${libtool_fname}.tar.gz ${LIBTOOL_DOWNLOAD_URL} 241 | check_sha256sum ${libtool_fname}.tar.gz ${libtool_sha256} 242 | tar -zxf ${libtool_fname}.tar.gz 243 | (cd ${libtool_fname} && do_standard_install) 244 | rm -rf ${libtool_fname} ${libtool_fname}.tar.gz 245 | } 246 | -------------------------------------------------------------------------------- /docker/build_scripts/manylinux-check.py: -------------------------------------------------------------------------------- 1 | # Logic copied from PEP 513 2 | 3 | def is_manylinux2010_compatible(): 4 | # Only Linux, and only x86-64 / i686 5 | from distutils.util import get_platform 6 | if get_platform() not in ["linux-x86_64", "linux-i686"]: 7 | return False 8 | 9 | # Check for presence of _manylinux module 10 | try: 11 | import _manylinux 12 | return bool(_manylinux.manylinux1_compatible) 13 | except (ImportError, AttributeError): 14 | # Fall through to heuristic check below 15 | pass 16 | 17 | # Check glibc version. CentOS 6 uses glibc 2.12. 18 | return have_compatible_glibc(2, 12) 19 | 20 | def have_compatible_glibc(major, minimum_minor): 21 | import ctypes 22 | 23 | process_namespace = ctypes.CDLL(None) 24 | try: 25 | gnu_get_libc_version = process_namespace.gnu_get_libc_version 26 | except AttributeError: 27 | # Symbol doesn't exist -> therefore, we are not linked to 28 | # glibc. 29 | return False 30 | 31 | # Call gnu_get_libc_version, which returns a string like "2.5". 32 | gnu_get_libc_version.restype = ctypes.c_char_p 33 | version_str = gnu_get_libc_version() 34 | # py2 / py3 compatibility: 35 | if not isinstance(version_str, str): 36 | version_str = version_str.decode("ascii") 37 | 38 | # Parse string and check against requested version. 39 | version = [int(piece) for piece in version_str.split(".")] 40 | assert len(version) == 2 41 | if major != version[0]: 42 | return False 43 | if minimum_minor > version[1]: 44 | return False 45 | return True 46 | 47 | import sys 48 | if is_manylinux2010_compatible(): 49 | print("%s is manylinux2010 compatible" % (sys.executable,)) 50 | sys.exit(0) 51 | else: 52 | print("%s is NOT manylinux2010 compatible" % (sys.executable,)) 53 | sys.exit(1) 54 | -------------------------------------------------------------------------------- /docker/build_scripts/python-tag-abi-tag.py: -------------------------------------------------------------------------------- 1 | # Utility script to print the python tag + the abi tag for a Python 2 | # See PEP 425 for exactly what these are, but an example would be: 3 | # cp27-cp27mu 4 | 5 | from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag 6 | 7 | print("{0}{1}-{2}".format(get_abbr_impl(), get_impl_ver(), get_abi_tag())) -------------------------------------------------------------------------------- /docker/build_scripts/requirements-pre-7.3.0.txt: -------------------------------------------------------------------------------- 1 | pip==19.1.1 \ 2 | --hash=sha256:44d3d7d3d30a1eb65c7e5ff1173cdf8f7467850605ac7cc3707b6064bddd0958 \ 3 | --hash=sha256:993134f0475471b91452ca029d4390dc8f298ac63a712814f101cd1b6db46676 4 | wheel==0.31.1 \ 5 | --hash=sha256:80044e51ec5bbf6c894ba0bc48d26a8c20a9ba629f4ca19ea26ecfcf87685f5f \ 6 | --hash=sha256:0a2e54558a0628f2145d2fc822137e322412115173e8a2ddbe1c9024338ae83c 7 | setuptools==41.0.1 \ 8 | --hash=sha256:a222d126f5471598053c9a77f4b5d4f26eaa1f150ad6e01dcf1a42e185d05613 \ 9 | --hash=sha256:c7769ce668c7a333d84e17fe8b524b1c45e7ee9f7908ad0a73e1eda7e6a5aebf 10 | -------------------------------------------------------------------------------- /docker/build_scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | # pip requirements for all cpythons 2 | # NOTE: pip has GPG signatures; could download and verify independently. 3 | pip==20.0.2 \ 4 | --hash=sha256:4ae14a42d8adba3205ebeb38aa68cfc0b6c346e1ae2e699a0b3bad4da19cef5c \ 5 | --hash=sha256:7db0c8ea4c7ea51c8049640e8e6e7fde949de672bfa4949920675563a5a6967f 6 | wheel==0.34.2 \ 7 | --hash=sha256:8788e9155fe14f54164c1b9eb0a319d98ef02c160725587ad60f14ddc57b6f96 \ 8 | --hash=sha256:df277cb51e61359aba502208d680f90c0493adec6f0e848af94948778aed386e 9 | setuptools==44.0.0; python_version == '2.7' \ 10 | --hash=sha256:180081a244d0888b0065e18206950d603f6550721bd6f8c0a10221ed467dd78e \ 11 | --hash=sha256:e5baf7723e5bb8382fc146e33032b241efc63314211a3a120aaa55d62d2bb008 12 | setuptools==45.2.0; python_version >= '3.5' \ 13 | --hash=sha256:316484eebff54cc18f322dea09ed031b7e3eb00811b19dcedb09bc09bba7d93d \ 14 | --hash=sha256:89c6e6011ec2f6d57d43a3f9296c4ef022c2cbf49bab26b407fe67992ae3397f 15 | -------------------------------------------------------------------------------- /docker/build_scripts/ssl-check.py: -------------------------------------------------------------------------------- 1 | # cf. https://github.com/pypa/manylinux/issues/53 2 | 3 | GOOD_SSL = "https://google.com" 4 | BAD_SSL = "https://self-signed.badssl.com" 5 | 6 | import sys 7 | 8 | print("Testing SSL certificate checking for Python:", sys.version) 9 | 10 | if (sys.version_info[:2] < (3, 4)): 11 | print("This version never checks SSL certs; skipping tests") 12 | sys.exit(0) 13 | 14 | if sys.version_info[0] >= 3: 15 | from urllib.request import urlopen 16 | EXC = OSError 17 | else: 18 | from urllib import urlopen 19 | EXC = IOError 20 | 21 | print("Connecting to %s should work" % (GOOD_SSL,)) 22 | urlopen(GOOD_SSL) 23 | print("...it did, yay.") 24 | 25 | print("Connecting to %s should fail" % (BAD_SSL,)) 26 | try: 27 | urlopen(BAD_SSL) 28 | # If we get here then we failed: 29 | print("...it DIDN'T!!!!!11!!1one!") 30 | sys.exit(1) 31 | except EXC: 32 | print("...it did, yay.") 33 | -------------------------------------------------------------------------------- /docker/build_scripts_pypy/install_pypy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | function get_shortdir { 6 | local exe=$1 7 | $exe -c 'import sys; print("pypy%d.%d-%d.%d.%d" % (sys.version_info[:2]+sys.pypy_version_info[:3]))' 8 | } 9 | 10 | function get_requirements_txt { 11 | local exe=$1 12 | $exe -c 'import sys; print("requirements-pre-7.3.0.txt" if sys.pypy_version_info < (7,3,0) else "requirements.txt")' 13 | } 14 | 15 | # this is more or less equivalent to do_cpython_build, although we download a 16 | # prebuilt pypy instead of building it from scratch 17 | function install_one_pypy { 18 | local tarball=$1 19 | local basename=$(basename $tarball) 20 | local outdir=/opt/pypy/${basename/.tar.bz2//} 21 | 22 | mkdir -p /opt/pypy 23 | cd /opt/pypy 24 | tar xf $tarball 25 | 26 | # the new PyPy 3 distributions don't have pypy symlinks to pypy3 27 | if [ ! -f "$outdir/bin/pypy" ]; then 28 | ln -s pypy3 $outdir/bin/pypy 29 | fi 30 | 31 | # rename the directory to something shorter like pypy2.7-7.1.1 32 | shortdir=$(get_shortdir $outdir/bin/pypy) 33 | mv "$outdir" "$shortdir" 34 | local pypy=$shortdir/bin/pypy 35 | 36 | # add a generic "python" symlink 37 | if [ ! -f "$shortdir/bin/python" ]; then 38 | ln -s pypy $shortdir/bin/python 39 | fi 40 | 41 | # remove debug symbols 42 | rm $shortdir/bin/*.debug 43 | 44 | # install and upgrade pip 45 | $pypy -m ensurepip --default-pip 46 | $pypy -m pip install -U --require-hashes -r /build_scripts/requirements.txt 47 | 48 | local abi_tag=$($pypy /build_scripts/python-tag-abi-tag.py) 49 | ln -s /opt/pypy/$shortdir /opt/python/${abi_tag} 50 | } 51 | 52 | for TARBALL in /sources/pypy*.tar.bz2 53 | do 54 | install_one_pypy "$TARBALL" 55 | rm "$TARBALL" 56 | done 57 | 58 | 59 | # the following is copied&adapted from 60 | # pypa/manylinux/docker/build_scripts/build.sh 61 | 62 | for PYTHON in /opt/pypy/*/bin/python; do 63 | # Smoke test to make sure that our Pythons work, and do indeed detect as 64 | # being manylinux compatible: 65 | $PYTHON /build_scripts/manylinux-check.py 66 | # Make sure that SSL cert checking works 67 | $PYTHON /build_scripts/ssl-check.py 68 | done 69 | 70 | # We do not need the Python test suites, or indeed the precompiled .pyc and 71 | # .pyo files. Partially cribbed from: 72 | # https://github.com/docker-library/python/blob/master/3.4/slim/Dockerfile 73 | find /opt/pypy -depth \ 74 | \( -type d -a -name test -o -name tests \) \ 75 | -o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) | xargs rm -rf 76 | -------------------------------------------------------------------------------- /docker/build_scripts_pypy/prefetch_pypy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | SOURCES=/sources 6 | SQUEAKY_GITHUB_URL=https://github.com/squeaky-pl/portable-pypy/releases/download # old releases 7 | URL=https://downloads.python.org/pypy # new releases 8 | 9 | 10 | MY_DIR=$(dirname "${BASH_SOURCE[0]}") 11 | . $MY_DIR/../build_scripts/build_utils.sh 12 | 13 | mkdir -p "$SOURCES" 14 | cd "$SOURCES" 15 | 16 | # pypy 7.2.0 17 | fetch_source pypy-7.2.0-linux_x86_64-portable.tar.bz2 "$SQUEAKY_GITHUB_URL/pypy-7.2.0" 18 | fetch_source pypy3.6-7.2.0-linux_x86_64-portable.tar.bz2 "$SQUEAKY_GITHUB_URL/pypy3.6-7.2.0" 19 | 20 | # pypy 7.3.3 (3.6 only) 21 | fetch_source pypy3.6-v7.3.3-linux64.tar.bz2 "$URL" 22 | 23 | # pypy 7.3.4 24 | fetch_source pypy2.7-v7.3.4-linux64.tar.bz2 "$URL" 25 | fetch_source pypy3.7-v7.3.4-linux64.tar.bz2 "$URL" 26 | -------------------------------------------------------------------------------- /docker/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | tag=pypywheels/manylinux2010-pypy_x86_64 3 | build_id=$(git show -s --format=%cd-%h --date=short $TRAVIS_COMMIT) 4 | 5 | docker login -u pypywheels -p $DOCKERPASS 6 | docker tag ${tag}:latest ${tag}:${build_id} 7 | docker push ${tag}:${build_id} 8 | docker push ${tag}:latest 9 | --------------------------------------------------------------------------------