From e672b6f09218b61248a265a9a7ce3c0d3158ff48 Mon Sep 17 00:00:00 2001 From: Maxim Biro Date: Thu, 16 Feb 2017 05:18:17 -0500 Subject: [PATCH] Add Dockerfile for Windows cross-compilation --- other/docker/windows/Dockerfile | 32 ++++ other/docker/windows/build_dependencies.sh | 89 +++++++++++ other/docker/windows/build_toxcore.sh | 164 +++++++++++++++++++++ other/docker/windows/get_packages.sh | 55 +++++++ 4 files changed, 340 insertions(+) create mode 100644 other/docker/windows/Dockerfile create mode 100644 other/docker/windows/build_dependencies.sh create mode 100644 other/docker/windows/build_toxcore.sh create mode 100644 other/docker/windows/get_packages.sh diff --git a/other/docker/windows/Dockerfile b/other/docker/windows/Dockerfile new file mode 100644 index 00000000..176c3937 --- /dev/null +++ b/other/docker/windows/Dockerfile @@ -0,0 +1,32 @@ +FROM debian:stretch-slim + +# Build-time enviroment variables +ARG VERSION_SODIUM=1.0.16 +ARG VERSION_OPUS=v1.2.1 +ARG VERSION_VPX=v1.6.1 +ARG VERSION_CHECK=0.12.0 + +ARG SUPPORT_TEST=false +ARG SUPPORT_ARCH_i686=true +ARG SUPPORT_ARCH_x86_64=true + +# Make those available when running the container +ENV SUPPORT_TEST=${SUPPORT_TEST} +ENV SUPPORT_ARCH_i686=${SUPPORT_ARCH_i686} +ENV SUPPORT_ARCH_x86_64=${SUPPORT_ARCH_x86_64} + +ADD get_packages.sh . +RUN sh ./get_packages.sh + +ADD build_dependencies.sh . +RUN sh ./build_dependencies.sh + +ADD build_toxcore.sh . + +ENV ENABLE_TEST=false +ENV ALLOW_TEST_FAILURE=false +ENV ENABLE_ARCH_i686=true +ENV ENABLE_ARCH_x86_64=true +ENV EXTRA_CMAKE_FLAGS="-DWARNINGS=OFF -DBOOTSTRAP_DAEMON=OFF -DTEST_TIMEOUT_SECONDS=300" + +CMD sh ./build_toxcore.sh diff --git a/other/docker/windows/build_dependencies.sh b/other/docker/windows/build_dependencies.sh new file mode 100644 index 00000000..f3d4b603 --- /dev/null +++ b/other/docker/windows/build_dependencies.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env sh + +set -e -x + +#=== Cross-Compile Dependencies === + +build() +{ + ARCH=${1} + + echo "Building for ${ARCH} architecture" + + # set some things + WINDOWS_TOOLCHAIN=${ARCH}-w64-mingw32 + + # prefix that we will copy to the user + PREFIX_DIR="/root/prefix/${ARCH}" + # prefix for things that shouldn't be copied to the user + EXTRA_PREFIX_DIR="/root/extra-prefix/${ARCH}" + mkdir -p "${PREFIX_DIR}" "${EXTRA_PREFIX_DIR}" + + export MAKEFLAGS=j$(nproc) + export CFLAGS=-O3 + + cd /tmp + + echo + echo "=== Building Sodium ${VERSION_SODIUM} ${ARCH} ===" + git clone --depth=1 --branch="${VERSION_SODIUM}" https://github.com/jedisct1/libsodium + cd libsodium + ./autogen.sh + ./configure --host="${WINDOWS_TOOLCHAIN}" --prefix="${PREFIX_DIR}" --disable-shared --enable-static + make + make install + cd .. + + echo + echo "=== Building Opus ${VERSION_OPUS} ${ARCH} ===" + git clone --depth=1 --branch="${VERSION_OPUS}" https://github.com/xiph/opus + cd opus + ./autogen.sh + ./configure --host="${WINDOWS_TOOLCHAIN}" --prefix="${PREFIX_DIR}" --disable-extra-programs --disable-doc --disable-shared --enable-static + make + make install + cd .. + + echo + echo "=== Building VPX ${VERSION_VPX} ${ARCH} ===" + LIB_VPX_TARGET="" + if [ "${ARCH}" = "i686" ]; then + LIB_VPX_TARGET=x86-win32-gcc + else + LIB_VPX_TARGET=x86_64-win64-gcc + fi + git clone --depth=1 --branch="${VERSION_VPX}" https://github.com/webmproject/libvpx + cd libvpx + CROSS="${WINDOWS_TOOLCHAIN}"- ./configure --target="${LIB_VPX_TARGET}" --prefix="${PREFIX_DIR}" --disable-examples --disable-unit-tests --disable-shared --enable-static + make + make install + cd .. + + if [ "${SUPPORT_TEST}" = "true" ]; then + echo + echo "=== Building Check ${VERSION_CHECK} ${ARCH} ===" + git clone --depth=1 --branch="${VERSION_CHECK}" https://github.com/libcheck/check + cd check + autoreconf --install + ./configure --host="${WINDOWS_TOOLCHAIN}" --prefix="${EXTRA_PREFIX_DIR}" + make + make install + cd .. + fi + + rm -rf /tmp/* +} + +if [ "${SUPPORT_ARCH_i686}" = "true" ]; then + build i686 +fi + +if [ "${SUPPORT_ARCH_x86_64}" = "true" ]; then + build x86_64 +fi + +tree /root + +echo +echo "Built dependencies successfully!" +echo diff --git a/other/docker/windows/build_toxcore.sh b/other/docker/windows/build_toxcore.sh new file mode 100644 index 00000000..0f4c2731 --- /dev/null +++ b/other/docker/windows/build_toxcore.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env sh + +set -e -x + +#=== Cross-Compile Toxcore === + +build() +{ + ARCH=${1} + + echo "Building for ${ARCH} architecture" + + # set some things + + WINDOWS_TOOLCHAIN=${ARCH}-w64-mingw32 + + # toxcore dependencies that we will copy to the user for static build of toxcore (e.g. vpx, opus, sodium) + DEP_PREFIX_DIR="/root/prefix/${ARCH}" + + # toxcore dependencies that user doesn't need in build result (e.g. libcheck used for testing toxcore) + EXTRA_DEP_PREFIX_DIR="/root/extra-prefix/${ARCH}" + mkdir -p "${EXTRA_DEP_PREFIX_DIR}" + + # where to put the result of this particular build + RESULT_PREFIX_DIR="/prefix/${ARCH}" + mkdir -p "${RESULT_PREFIX_DIR}" + + # where to install static/shared toxcores before deciding whether they should be copied over to the user + STATIC_TOXCORE_PREFIX_DIR="/tmp/static_prefix" + SHARED_TOXCORE_PREFIX_DIR="/tmp/shared_prefix" + mkdir -p "${STATIC_TOXCORE_PREFIX_DIR}" "${SHARED_TOXCORE_PREFIX_DIR}" + + export MAKEFLAGS=j$(nproc) + export CFLAGS=-O3 + + echo + echo "=== Building toxcore ${ARCH} ===" + export PKG_CONFIG_PATH="${DEP_PREFIX_DIR}/lib/pkgconfig:${EXTRA_DEP_PREFIX_DIR}/lib/pkgconfig" + + cp /toxcore /tmp/toxcore -R + cd /tmp/toxcore/build + echo " + SET(CMAKE_SYSTEM_NAME Windows) + + SET(CMAKE_C_COMPILER ${WINDOWS_TOOLCHAIN}-gcc) + SET(CMAKE_CXX_COMPILER ${WINDOWS_TOOLCHAIN}-g++) + SET(CMAKE_RC_COMPILER ${WINDOWS_TOOLCHAIN}-windres) + + SET(CMAKE_FIND_ROOT_PATH /usr/${WINDOWS_TOOLCHAIN} ${DEP_PREFIX_DIR} ${EXTRA_DEP_PREFIX_DIR}) + " > windows_toolchain.cmake + + if [ "${ENABLE_TEST}" = "true" ]; then + echo "SET(CROSSCOMPILING_EMULATOR /usr/bin/wine)" >> windows_toolchain.cmake + fi + + cmake -DCMAKE_TOOLCHAIN_FILE=windows_toolchain.cmake \ + -DCMAKE_INSTALL_PREFIX="${STATIC_TOXCORE_PREFIX_DIR}" \ + -DENABLE_SHARED=OFF \ + -DENABLE_STATIC=ON \ + ${EXTRA_CMAKE_FLAGS} \ + .. + cmake --build . --target install + + if [ "${ENABLE_TEST}" = "true" ]; then + rm -rf /root/.wine + + # setup wine + if [ "${ARCH}" = "i686" ]; then + export WINEARCH=win32 + else + export WINEARCH=win64 + fi + + winecfg + export CTEST_OUTPUT_ON_FAILURE=1 + # add libgcc_s_sjlj-1.dll libwinpthread-1.dll libcheck-0.dll into PATH env var of wine + export WINEPATH=`cd /usr/lib/gcc/${WINDOWS_TOOLCHAIN}/*posix/ ; winepath -w $(pwd)`\;`winepath -w /usr/${WINDOWS_TOOLCHAIN}/lib/`\;`winepath -w ${EXTRA_DEP_PREFIX_DIR}/bin` + + if [ "${ALLOW_TEST_FAILURE}" = "true" ]; then + set +e + fi + cmake --build . --target test + if [ "${ALLOW_TEST_FAILURE}" = "true" ]; then + set -e + fi + fi + + # move static dependencies + cp "${STATIC_TOXCORE_PREFIX_DIR}"/* "${RESULT_PREFIX_DIR}" -R + cp "${DEP_PREFIX_DIR}"/* "${RESULT_PREFIX_DIR}" -R + + # make libtox.dll + cd "${SHARED_TOXCORE_PREFIX_DIR}" + for archive in ${STATIC_TOXCORE_PREFIX_DIR}/lib/libtox*.a + do + ${WINDOWS_TOOLCHAIN}-ar xv ${archive} + done + ${WINDOWS_TOOLCHAIN}-gcc -Wl,--export-all-symbols \ + -Wl,--out-implib=libtox.dll.a \ + -shared \ + -o libtox.dll \ + *.obj \ + ${STATIC_TOXCORE_PREFIX_DIR}/lib/*.a \ + ${DEP_PREFIX_DIR}/lib/*.a \ + /usr/${WINDOWS_TOOLCHAIN}/lib/libwinpthread.a \ + -liphlpapi \ + -lws2_32 \ + -static-libgcc + cp libtox.dll.a ${RESULT_PREFIX_DIR}/lib + mkdir -p ${RESULT_PREFIX_DIR}/bin + cp libtox.dll ${RESULT_PREFIX_DIR}/bin + + rm -rf /tmp/* + + # remove everything from include directory except tox headers + mv ${RESULT_PREFIX_DIR}/include/tox ${RESULT_PREFIX_DIR}/tox + rm -rf ${RESULT_PREFIX_DIR}/include/* + mv ${RESULT_PREFIX_DIR}/tox ${RESULT_PREFIX_DIR}/include/tox + + sed -i "s|^prefix=.*|prefix=${RESULT_PREFIX_DIR}|g" ${RESULT_PREFIX_DIR}/lib/pkgconfig/*.pc + sed -i "s|^libdir=.*|libdir=${RESULT_PREFIX_DIR}/lib|g" ${RESULT_PREFIX_DIR}/lib/*.la +} + +#=== Test Supported vs. Enabled === + +if [ "${ENABLE_ARCH_i686}" != "true" ] && [ "${ENABLE_ARCH_x86_64}" != "true" ]; then + echo "Error: No architecture specified. Set either ENABLE_ARCH_i686 or ENABLE_ARCH_x86_64 or both." + exit 1 +fi + +if [ "${ENABLE_ARCH_i686}" = "true" ] && [ "${SUPPORT_ARCH_i686}" != "true" ]; then + echo "Error: Can't build for i686 architecture because the image was created without SUPPORT_ARCH_i686 set" + exit 1 +fi + +if [ "${ENABLE_ARCH_x86_64}" = "true" ] && [ "${SUPPORT_ARCH_x86_64}" != "true" ]; then + echo "Error: Can't build for x86_64 architecture because the image was created without SUPPORT_ARCH_x86_64 set" + exit 1 +fi + +if [ "${ENABLE_TEST}" = "true" ] && [ "${SUPPORT_TEST}" != "true" ]; then + echo "Error: Can't build with tests because the image was created without SUPPORT_TEST set" + exit 1 +fi + +#=== Build === + +if [ "${ENABLE_ARCH_i686}" = "true" ]; then + build i686 +fi + +if [ "${ENABLE_ARCH_x86_64}" = "true" ]; then + build x86_64 +fi + + +tree -h /prefix + +echo +echo "Built toxcore successfully!" +echo + +# since we are building as root +chmod 777 /prefix -R diff --git a/other/docker/windows/get_packages.sh b/other/docker/windows/get_packages.sh new file mode 100644 index 00000000..e3fb51f5 --- /dev/null +++ b/other/docker/windows/get_packages.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env sh + +set -e -x + +#=== Install Packages === + +apt-get update + +# Arch-independent packages required for building toxcore's dependencies and toxcore itself +apt-get install -y \ + autoconf \ + automake \ + ca-certificates \ + cmake \ + git \ + libtool \ + libc-dev \ + make \ + pkg-config \ + tree \ + yasm + +# Arch-dependent packages required for building toxcore's dependencies and toxcore itself +if [ "${SUPPORT_ARCH_i686}" = "true" ]; then + apt-get install -y \ + g++-mingw-w64-i686 \ + gcc-mingw-w64-i686 +fi + +if [ "${SUPPORT_ARCH_x86_64}" = "true" ]; then + apt-get install -y \ + g++-mingw-w64-x86-64 \ + gcc-mingw-w64-x86-64 +fi + +# Pacakges needed for running toxcore tests +if [ "${SUPPORT_TEST}" = "true" ]; then + apt-get install -y \ + curl \ + texinfo + + dpkg --add-architecture i386 + apt-get update + apt-get install -y \ + wine \ + wine32 \ + wine64 +fi + +# Clean up to reduce image size +apt-get clean +rm -rf \ + /var/lib/apt/lists/* \ + /tmp/* \ + /var/tmp/*