From c99bbe05156f997bd1f2fef8dea3186ddaae60cf Mon Sep 17 00:00:00 2001 From: Charles Leifer Date: Thu, 5 Sep 2019 13:46:32 -0500 Subject: [PATCH] Add build scripts for creating manylinux wheels. --- build-scripts/README | 16 +++++++++ build-scripts/_build_wheels.sh | 61 ++++++++++++++++++++++++++++++++++ build-scripts/build.sh | 25 ++++++++++++++ build-scripts/cleanup.sh | 8 +++++ 4 files changed, 110 insertions(+) create mode 100644 build-scripts/README create mode 100755 build-scripts/_build_wheels.sh create mode 100755 build-scripts/build.sh create mode 100755 build-scripts/cleanup.sh diff --git a/build-scripts/README b/build-scripts/README new file mode 100644 index 0000000..fc67048 --- /dev/null +++ b/build-scripts/README @@ -0,0 +1,16 @@ +### Building wheels + +This directory contains a utility script (`build.sh`) which can be used to +create completely self-contained manylinux wheels for Python 3.6 and 3.7. The +build script fetches the latest release of Sqlcipher and generates the source +amalgamation and header file, which are then compiled into `sqlcipher3`. The +resulting Python package can be deployed to any linux environment and will +utilize the latest Sqlcipher source code with extensions compiled in. + +The package name for the wheels is `sqlcipher3-binary` to differentiate it from +the standard `sqlcipher3` source distribution. The source distribution will +link against the system sqlcipher by default, though you can provide your own +`sqlite3.c` and `sqlite3.h` and use `setup.py build_static` to create a +self-contained package as well. + +Build artifacts are placed in the `wheelhouse/` directory. diff --git a/build-scripts/_build_wheels.sh b/build-scripts/_build_wheels.sh new file mode 100755 index 0000000..84d7552 --- /dev/null +++ b/build-scripts/_build_wheels.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# manylinux uses ancient Centos 5, which ships openssl 0.9.8. We need to build +# our own in order to then build sqlcipher. The SSL headers will be installed +# to /usr/local/. +# +# The code for installing Perl and OpenSSL is derived from the psycopg2-binary +# build scripts. +yum install -y zlib-devel + +OPENSSL_VERSION="1.1.1b" +OPENSSL_TAG="OpenSSL_${OPENSSL_VERSION//./_}" + +cd /io + +if [ ! -d "openssl-${OPENSSL_TAG}/" ]; then + # Building openssl 1.1 requires perl 5.10 or newer. + curl -L https://install.perlbrew.pl | bash + source ~/perl5/perlbrew/etc/bashrc + perlbrew install --notest perl-5.16.0 + perlbrew switch perl-5.16.0 + + curl -sL https://github.com/openssl/openssl/archive/${OPENSSL_TAG}.tar.gz \ + | tar xzf - + + cd "openssl-${OPENSSL_TAG}" + + # Expose the lib version number in the .so file name. + sed -i "s/SHLIB_VERSION_NUMBER\s\+\".*\"/SHLIB_VERSION_NUMBER \"${OPENSSL_VERSION}\"/" \ + ./include/openssl/opensslv.h + sed -i "s|if (\$shlib_version_number =~ /(^\[0-9\]\*)\\\.(\[0-9\\\.\]\*)/)|if (\$shlib_version_number =~ /(^[0-9]*)\.([0-9\.]*[a-z]?)/)|" \ + ./Configure + + ./config --prefix=/usr/local/ --openssldir=/usr/local/ zlib -fPIC shared + make depend && make && make install +fi + +# Volume (cwd of build script) is mounted at /io. +# A checkout of sqlcipher3 is cloned beforehand by the build.sh script. +cd /io/sqlcipher3 + +sed -i "s|name='sqlcipher3-binary'|name=PACKAGE_NAME|g" setup.py + +export CFLAGS="-I/usr/local/include -L/usr/local/lib" + +PY36="/opt/python/cp36-cp36m/bin" +"${PY36}/python" setup.py build_static + +PY37="/opt/python/cp37-cp37m/bin" +"${PY37}/python" setup.py build_static + +# Replace the package name defined in setup.py so we can push this to PyPI +# without stomping on the source dist. +sed -i "s|name=PACKAGE_NAME,|name='sqlcipher3-binary',|g" setup.py + +"${PY36}/pip" wheel /io/sqlcipher3 -w /io/wheelhouse +"${PY37}/pip" wheel /io/sqlcipher3 -w /io/wheelhouse + +for whl in /io/wheelhouse/*.whl; do + auditwheel repair "$whl" -w /io/wheelhouse/ +done diff --git a/build-scripts/build.sh b/build-scripts/build.sh new file mode 100755 index 0000000..29092b4 --- /dev/null +++ b/build-scripts/build.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e -x + +# Fetch the source code for SQLCipher. +if [[ ! -d "sqlcipher" ]]; then + git clone --depth=1 git@github.com:sqlcipher/sqlcipher + cd sqlcipher/ + ./configure --disable-tcl --enable-tempstore=yes LDFLAGS="-lcrypto -lm" + make sqlite3.c + cd ../ +fi + +# Grab the sqlcipher3 source code. +if [[ ! -d "./sqlcipher3" ]]; then + git clone git@github.com:coleifer/sqlcipher3 +fi + +# Copy the sqlcipher source amalgamation into the pysqlite3 directory so we can +# create a self-contained extension module. +cp "sqlcipher/sqlite3.c" sqlcipher3/ +cp "sqlcipher/sqlite3.h" sqlcipher3/ + +# Create the wheels and strip symbols to produce manylinux wheels. +docker run -it -v $(pwd):/io quay.io/pypa/manylinux1_x86_64 /io/_build_wheels.sh diff --git a/build-scripts/cleanup.sh b/build-scripts/cleanup.sh new file mode 100755 index 0000000..1352d4f --- /dev/null +++ b/build-scripts/cleanup.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +cleanup="openssl-OpenSSL_1_1_1b sqlcipher sqlcipher3 wheelhouse" +for p in $cleanup; do + if [[ -d "$p" ]]; then + sudo rm -rf "$p" + fi +done