application-services/libs/build-sqlcipher-desktop.sh

235 строки
7.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euvx
if [[ "${#}" -lt 1 ]] || [[ "${#}" -gt 2 ]]
then
echo "Usage:"
echo "./build-sqlcipher-desktop.sh <ABSOLUTE_SRC_DIR> [CROSS_COMPILE_TARGET]"
exit 1
fi
SQLCIPHER_SRC_DIR=${1}
# Whether to cross compile from Linux to a different target. Really
# only intended for automation.
CROSS_COMPILE_TARGET=${2-}
if [[ -n "${CROSS_COMPILE_TARGET}" ]] && [[ "$(uname -s)" != "Linux" ]]; then
echo "Can only cross compile from 'Linux'; 'uname -s' is $(uname -s)"
exit 1
fi
if [[ "${CROSS_COMPILE_TARGET}" =~ "win32-x86-64" ]]; then
DIST_DIR=$(abspath "desktop/win32-x86-64/sqlcipher")
NSS_DIR=$(abspath "desktop/win32-x86-64/nss")
TARGET_OS="windows"
elif [[ "${CROSS_COMPILE_TARGET}" =~ "darwin" ]]; then
DIST_DIR=$(abspath "desktop/darwin/sqlcipher")
NSS_DIR=$(abspath "desktop/darwin/nss")
TARGET_OS="macos"
elif [[ -n "${CROSS_COMPILE_TARGET}" ]]; then
echo "Cannot build SQLCipher for unrecognized target OS ${CROSS_COMPILE_TARGET}"
exit 1
elif [[ "$(uname -s)" == "Darwin" ]]; then
DIST_DIR=$(abspath "desktop/darwin/sqlcipher")
NSS_DIR=$(abspath "desktop/darwin/nss")
TARGET_OS="macos"
elif [[ "$(uname -s)" == "Linux" ]]; then
# This is a JNA weirdness: "x86-64" rather than "x86_64".
DIST_DIR=$(abspath "desktop/linux-x86-64/sqlcipher")
NSS_DIR=$(abspath "desktop/linux-x86-64/nss")
TARGET_OS="linux"
else
echo "Cannot build SQLcipher on unrecognized host OS $(uname -s)"
exit 1
fi
if [[ -d "${DIST_DIR}" ]]; then
echo "${DIST_DIR} folder already exists. Skipping build."
exit 0
fi
echo "# Building sqlcipher"
# Keep in sync with SQLCIPHER_CFLAGS in `build-sqlcipher-desktop.sh` for now (it probably makes
# sense to try to avoid this duplication in the future).
# TODO: We could probably prune some of these, and it would be nice to allow debug builds (which
# should set `SQLITE_DEBUG` and `SQLITE_ENABLE_API_ARMOR` and not `NDEBUG`).
SQLCIPHER_CFLAGS=" \
-DSQLITE_HAS_CODEC \
-DSQLITE_SOUNDEX \
-DHAVE_USLEEP=1 \
-DSQLITE_MAX_VARIABLE_NUMBER=99999 \
-DSQLITE_THREADSAFE=1 \
-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \
-DNDEBUG=1 \
-DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 \
-DSQLITE_ENABLE_LOAD_EXTENSION \
-DSQLITE_ENABLE_COLUMN_METADATA \
-DSQLITE_ENABLE_UNLOCK_NOTIFY \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_STAT3 \
-DSQLITE_ENABLE_STAT4 \
-DSQLITE_ENABLE_JSON1 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLCIPHER_CRYPTO_NSS \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_SECURE_DELETE=1 \
-DSQLITE_DEFAULT_PAGE_SIZE=32768 \
-DSQLITE_MAX_DEFAULT_PAGE_SIZE=32768 \
-I${NSS_DIR}/include \
"
LIBS="\
-lcertdb \
-lcerthi \
-lcryptohi \
-lfreebl_static \
-lhw-acc-crypto-avx \
-lhw-acc-crypto-avx2 \
-lnspr4 \
-lnss_static \
-lnssb \
-lnssdev \
-lnsspki \
-lnssutil \
-lpk11wrap_static \
-lplc4 \
-lplds4 \
-lsoftokn_static \
-lgcm-aes-x86_c_lib \
"
if [[ "${TARGET_OS}" == "windows" ]]; then
LIBS="${LIBS} -lintel-gcm-wrap_c_lib"
elif [[ "${TARGET_OS}" == "linux" ]]; then
LIBS="${LIBS} -lintel-gcm-wrap_c_lib -lintel-gcm-s_lib"
fi
BUILD_DIR=$(mktemp -d)
pushd "${BUILD_DIR}"
# Why `--with-pic --enable-shared`? We're doing unusual things. By
# default, libtool builds a static library (.a) with a non-PIC .o, and
# a shared library (.so, say) with a PIC .o. We want to compile PIC
# .o files for use in subsequent compilations and wrap them in a .a.
# We achieve that by forcing PIC (even for the .a) and disabling the
# shared library (.so) entirely.
if [[ "${CROSS_COMPILE_TARGET}" =~ "darwin" ]]; then
export CC=/tmp/clang/bin/clang
export AR=/tmp/cctools/bin/x86_64-darwin11-ar
export RANLIB=/tmp/cctools/bin/x86_64-darwin11-ranlib
export STRIP=/tmp/cctools/bin/x86_64-darwin11-strip
export LIBTOOL=/tmp/cctools/bin/x86_64-darwin11-libtool
export NM=/tmp/cctools/bin/x86_64-darwin11-nm
export LD=/tmp/cctools/bin/x86_64-darwin11-ld
export CFLAGS='-B /tmp/cctools/bin -target x86_64-darwin11 -mlinker-version=137 -isysroot /tmp/MacOSX10.11.sdk -I/tmp/MacOSX10.11.sdk/usr/include -iframework /tmp/MacOSX10.11.sdk/System/Library/Frameworks'
export LDFLAGS='-B /tmp/cctools/bin -Wl,-syslibroot,/tmp/MacOSX10.11.sdk -Wl,-dead_strip'
# This is crucial. Without this, libtool drops the `-target ...`
# flags from the clang compiler linker driver invocation, resulting
# in clang choosing a random system `ld` rather than the macOS
# linker from the cctools port.
export LTLINK_EXTRAS='-XCClinker -target -XCClinker x86_64-darwin11 -XCClinker -B -XCClinker /tmp/cctools/bin'
# See https://searchfox.org/mozilla-central/rev/8848b9741fc4ee4e9bc3ae83ea0fc048da39979f/build/macosx/cross-mozconfig.common#12-13.
export LD_LIBRARY_PATH=/tmp/clang/lib
"${SQLCIPHER_SRC_DIR}/configure" \
--with-pic \
--disable-shared \
--host=x86_64-apple-darwin \
--with-crypto-lib=none \
--disable-tcl \
--enable-tempstore=yes \
CFLAGS="${CFLAGS} ${SQLCIPHER_CFLAGS}" \
LDFLAGS="${LDFLAGS} -L${NSS_DIR}/lib" \
LIBS="${LIBS}"
elif [[ "${CROSS_COMPILE_TARGET}" =~ "win32-x86-64" ]]; then
pushd "${SQLCIPHER_SRC_DIR}"
# From https://github.com/qTox/qTox/blob/9525505bff8719c84b6193174ea5e7ec097c54b8/windows/cross-compile/build.sh#L390-L446.
# shellcheck disable=SC2016
sed -i s/'if test "$TARGET_EXEEXT" = ".exe"'/'if test ".exe" = ".exe"'/g configure
# Can't quite figure out what to tell ./configure so that it gets the picture
# here (it doesn't seem to handle host/build/target args correctly)... Oh well,
# this is a bit of a sledgehammer but does the job.
sed -i s/'BEXE = @BUILD_EXEEXT@'/'BEXE = ""'/g Makefile.in
> Makefile.in-patch cat << "EOF"
--- Makefile.in 2017-12-21 19:31:28.000000000 +0000
+++ Makefile.in 2018-11-06 23:58:45.576548000 +0000
@@ -1092,9 +1092,9 @@
$(TOP)/ext/fts5/fts5_unicode2.c \
$(TOP)/ext/fts5/fts5_varint.c \
$(TOP)/ext/fts5/fts5_vocab.c \
-fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon
+fts5parse.c: $(TOP)/ext/fts5/fts5parse.y lemon$(BEXE)
cp $(TOP)/ext/fts5/fts5parse.y .
rm -f fts5parse.h
./lemon$(BEXE) $(OPTS) fts5parse.y
EOF
patch --forward --ignore-whitespace < Makefile.in-patch
popd
"${SQLCIPHER_SRC_DIR}/configure" \
--with-pic \
--disable-shared \
--build=x86_64 \
--host=x86_64-w64-mingw32 \
--target=x86_64-w64-mingw32 \
--enable-tempstore=yes \
--with-crypto-lib=none \
--disable-tcl \
CFLAGS="${SQLCIPHER_CFLAGS}" \
LDFLAGS="-L${NSS_DIR}/lib" \
LIBS="${LIBS}"
elif [[ "$(uname -s)" == "Darwin" ]]; then
"${SQLCIPHER_SRC_DIR}/configure" \
--with-pic \
--disable-shared \
--enable-tempstore=yes \
--with-crypto-lib=none \
--disable-tcl \
CFLAGS="${SQLCIPHER_CFLAGS}" \
LDFLAGS="-L${NSS_DIR}/lib" \
LIBS="${LIBS}"
elif [[ "$(uname -s)" == "Linux" ]]; then
"${SQLCIPHER_SRC_DIR}/configure" \
--with-pic \
--disable-shared \
--enable-tempstore=yes \
--with-crypto-lib=none \
--disable-tcl \
CFLAGS="${SQLCIPHER_CFLAGS}" \
LDFLAGS="-L${NSS_DIR}/lib" \
LIBS="${LIBS}"
fi
make sqlite3.h
make sqlite3ext.h
make libsqlcipher.la
mkdir -p "${DIST_DIR}/include/sqlcipher"
mkdir -p "${DIST_DIR}/lib"
cp -p "${BUILD_DIR}/sqlite3.h" "${DIST_DIR}/include/sqlcipher"
cp -p "${BUILD_DIR}/sqlite3ext.h" "${DIST_DIR}/include/sqlcipher"
cp -p "${BUILD_DIR}/.libs/libsqlcipher.a" "${DIST_DIR}/lib"
chmod +w "${DIST_DIR}/lib/libsqlcipher.a"
if [[ "${CROSS_COMPILE_TARGET}" =~ "win32-x86-64" ]]; then
mv "${DIST_DIR}/lib/libsqlcipher.a" "${DIST_DIR}/lib/sqlcipher.lib"
fi
popd