Jeongik Cha | 7e7f19d | 2024-10-31 20:50:24 +0900 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # |
| 3 | # Example: |
| 4 | # env BUILD_TARGET=mips ./scripts/cross-build.sh |
| 5 | # |
| 6 | set -eo pipefail |
| 7 | |
| 8 | CROSS_ROOT="${CROSS_ROOT:-/tmp/cross}" |
| 9 | STAGE_ROOT="${STAGE_ROOT:-/tmp/stage}" |
| 10 | BUILD_ROOT="${BUILD_ROOT:-/tmp/build}" |
| 11 | BUILD_TARGET="${BUILD_TARGET:-x86_64}" |
| 12 | |
| 13 | ZLIB_VERSION="${ZLIB_VERSION:-1.3.1}" |
| 14 | JSON_C_VERSION="${JSON_C_VERSION:-0.17}" |
| 15 | MBEDTLS_VERSION="${MBEDTLS_VERSION:-2.28.5}" |
| 16 | LIBUV_VERSION="${LIBUV_VERSION:-1.44.2}" |
| 17 | LIBWEBSOCKETS_VERSION="${LIBWEBSOCKETS_VERSION:-4.3.3}" |
| 18 | |
| 19 | build_zlib() { |
| 20 | echo "=== Building zlib-${ZLIB_VERSION} (${TARGET})..." |
| 21 | curl -fSsLo- "https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" |
| 22 | pushd "${BUILD_DIR}"/zlib-"${ZLIB_VERSION}" |
| 23 | env CHOST="${TARGET}" ./configure --static --archs="-fPIC" --prefix="${STAGE_DIR}" |
| 24 | make -j"$(nproc)" install |
| 25 | popd |
| 26 | } |
| 27 | |
| 28 | build_json-c() { |
| 29 | echo "=== Building json-c-${JSON_C_VERSION} (${TARGET})..." |
| 30 | curl -fSsLo- "https://s3.amazonaws.com/json-c_releases/releases/json-c-${JSON_C_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" |
| 31 | pushd "${BUILD_DIR}/json-c-${JSON_C_VERSION}" |
| 32 | rm -rf build && mkdir -p build && cd build |
| 33 | cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \ |
| 34 | -DCMAKE_BUILD_TYPE=RELEASE \ |
| 35 | -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \ |
| 36 | -DBUILD_SHARED_LIBS=OFF \ |
| 37 | -DBUILD_TESTING=OFF \ |
| 38 | -DDISABLE_THREAD_LOCAL_STORAGE=ON \ |
| 39 | .. |
| 40 | make -j"$(nproc)" install |
| 41 | popd |
| 42 | } |
| 43 | |
| 44 | build_mbedtls() { |
| 45 | echo "=== Building mbedtls-${MBEDTLS_VERSION} (${TARGET})..." |
| 46 | curl -fSsLo- "https://github.com/ARMmbed/mbedtls/archive/v${MBEDTLS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" |
| 47 | pushd "${BUILD_DIR}/mbedtls-${MBEDTLS_VERSION}" |
| 48 | rm -rf build && mkdir -p build && cd build |
| 49 | cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \ |
| 50 | -DCMAKE_BUILD_TYPE=RELEASE \ |
| 51 | -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \ |
| 52 | -DENABLE_TESTING=OFF \ |
| 53 | .. |
| 54 | make -j"$(nproc)" install |
| 55 | popd |
| 56 | } |
| 57 | |
| 58 | build_libuv() { |
| 59 | echo "=== Building libuv-${LIBUV_VERSION} (${TARGET})..." |
| 60 | curl -fSsLo- "https://dist.libuv.org/dist/v${LIBUV_VERSION}/libuv-v${LIBUV_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" |
| 61 | pushd "${BUILD_DIR}/libuv-v${LIBUV_VERSION}" |
| 62 | ./autogen.sh |
| 63 | env CFLAGS=-fPIC ./configure --disable-shared --enable-static --prefix="${STAGE_DIR}" --host="${TARGET}" |
| 64 | make -j"$(nproc)" install |
| 65 | popd |
| 66 | } |
| 67 | |
| 68 | install_cmake_cross_file() { |
| 69 | cat << EOF > "${BUILD_DIR}/cross-${TARGET}.cmake" |
| 70 | SET(CMAKE_SYSTEM_NAME $1) |
| 71 | |
| 72 | set(CMAKE_C_COMPILER "${TARGET}-gcc") |
| 73 | set(CMAKE_CXX_COMPILER "${TARGET}-g++") |
| 74 | |
| 75 | set(CMAKE_FIND_ROOT_PATH "${STAGE_DIR}") |
| 76 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) |
| 77 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) |
| 78 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) |
| 79 | |
| 80 | set(OPENSSL_USE_STATIC_LIBS TRUE) |
| 81 | EOF |
| 82 | } |
| 83 | |
| 84 | build_libwebsockets() { |
| 85 | echo "=== Building libwebsockets-${LIBWEBSOCKETS_VERSION} (${TARGET})..." |
| 86 | curl -fSsLo- "https://github.com/warmcat/libwebsockets/archive/v${LIBWEBSOCKETS_VERSION}.tar.gz" | tar xz -C "${BUILD_DIR}" |
| 87 | cp "$(dirname $0)/client_cert.patch" ${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION} |
| 88 | pushd "${BUILD_DIR}/libwebsockets-${LIBWEBSOCKETS_VERSION}" |
| 89 | patch -p1 < client_cert.patch |
| 90 | sed -i 's/ websockets_shared//g' cmake/libwebsockets-config.cmake.in |
| 91 | sed -i 's/ OR PC_OPENSSL_FOUND//g' lib/tls/CMakeLists.txt |
| 92 | sed -i '/PC_OPENSSL/d' lib/tls/CMakeLists.txt |
| 93 | rm -rf build && mkdir -p build && cd build |
| 94 | cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \ |
| 95 | -DCMAKE_BUILD_TYPE=RELEASE \ |
| 96 | -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \ |
| 97 | -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \ |
| 98 | -DCMAKE_EXE_LINKER_FLAGS="-static" \ |
| 99 | -DLWS_WITHOUT_TESTAPPS=ON \ |
| 100 | -DLWS_WITH_MBEDTLS=ON \ |
| 101 | -DLWS_WITH_LIBUV=ON \ |
| 102 | -DLWS_STATIC_PIC=ON \ |
| 103 | -DLWS_WITH_SHARED=OFF \ |
| 104 | -DLWS_UNIX_SOCK=ON \ |
| 105 | -DLWS_IPV6=ON \ |
| 106 | -DLWS_ROLE_RAW_FILE=OFF \ |
| 107 | -DLWS_WITH_HTTP2=ON \ |
| 108 | -DLWS_WITH_HTTP_BASIC_AUTH=OFF \ |
| 109 | -DLWS_WITH_UDP=OFF \ |
| 110 | -DLWS_WITHOUT_CLIENT=ON \ |
| 111 | -DLWS_WITHOUT_EXTENSIONS=OFF \ |
| 112 | -DLWS_WITH_LEJP=OFF \ |
| 113 | -DLWS_WITH_LEJP_CONF=OFF \ |
| 114 | -DLWS_WITH_LWSAC=OFF \ |
| 115 | -DLWS_WITH_SEQUENCER=OFF \ |
| 116 | .. |
| 117 | make -j"$(nproc)" install |
| 118 | popd |
| 119 | } |
| 120 | |
| 121 | build_ttyd() { |
| 122 | echo "=== Building ttyd (${TARGET})..." |
| 123 | rm -rf build && mkdir -p build && cd build |
| 124 | cmake -DCMAKE_TOOLCHAIN_FILE="${BUILD_DIR}/cross-${TARGET}.cmake" \ |
| 125 | -DCMAKE_INSTALL_PREFIX="${STAGE_DIR}" \ |
| 126 | -DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \ |
| 127 | -DCMAKE_C_FLAGS="-Os -ffunction-sections -fdata-sections -fno-unwind-tables -fno-asynchronous-unwind-tables -flto" \ |
| 128 | -DCMAKE_EXE_LINKER_FLAGS="-static -no-pie -Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" \ |
| 129 | -DCMAKE_BUILD_TYPE=RELEASE \ |
| 130 | .. |
| 131 | make install |
| 132 | } |
| 133 | |
| 134 | build() { |
| 135 | TARGET="$1" |
| 136 | ALIAS="$2" |
| 137 | STAGE_DIR="${STAGE_ROOT}/${TARGET}" |
| 138 | BUILD_DIR="${BUILD_ROOT}/${TARGET}" |
| 139 | MUSL_CC_URL="https://github.com/tsl0922/musl-toolchains/releases/download/2021-11-23" |
| 140 | COMPONENTS="1" |
| 141 | SYSTEM="Linux" |
| 142 | |
| 143 | if [ "$ALIAS" = "win32" ]; then |
| 144 | COMPONENTS=2 |
| 145 | SYSTEM="Windows" |
| 146 | fi |
| 147 | |
| 148 | echo "=== Installing toolchain ${ALIAS} (${TARGET})..." |
| 149 | |
| 150 | mkdir -p "${CROSS_ROOT}" && export PATH="${PATH}:${CROSS_ROOT}/bin" |
| 151 | curl -fSsLo- "${MUSL_CC_URL}/${TARGET}-cross.tgz" | tar xz -C "${CROSS_ROOT}" --strip-components=${COMPONENTS} |
| 152 | |
| 153 | echo "=== Building target ${ALIAS} (${TARGET})..." |
| 154 | |
| 155 | rm -rf "${STAGE_DIR}" "${BUILD_DIR}" |
| 156 | mkdir -p "${STAGE_DIR}" "${BUILD_DIR}" |
| 157 | export PKG_CONFIG_PATH="${STAGE_DIR}/lib/pkgconfig" |
| 158 | |
| 159 | install_cmake_cross_file ${SYSTEM} |
| 160 | |
| 161 | build_zlib |
| 162 | build_json-c |
| 163 | build_libuv |
| 164 | build_mbedtls |
| 165 | build_libwebsockets |
| 166 | build_ttyd |
| 167 | } |
| 168 | |
| 169 | case ${BUILD_TARGET} in |
| 170 | amd64) BUILD_TARGET="x86_64" ;; |
| 171 | arm64) BUILD_TARGET="aarch64" ;; |
| 172 | armv7) BUILD_TARGET="armv7l" ;; |
| 173 | esac |
| 174 | |
| 175 | case ${BUILD_TARGET} in |
| 176 | i686|x86_64|aarch64|mips|mipsel|mips64|mips64el|s390x) |
| 177 | build "${BUILD_TARGET}-linux-musl" "${BUILD_TARGET}" |
| 178 | ;; |
| 179 | arm) |
| 180 | build "${BUILD_TARGET}-linux-musleabi" "${BUILD_TARGET}" |
| 181 | ;; |
| 182 | armhf) |
| 183 | build arm-linux-musleabihf "${BUILD_TARGET}" |
| 184 | ;; |
| 185 | armv7l) |
| 186 | build armv7l-linux-musleabihf "${BUILD_TARGET}" |
| 187 | ;; |
| 188 | win32) |
| 189 | build x86_64-w64-mingw32 "${BUILD_TARGET}" |
| 190 | ;; |
| 191 | *) |
| 192 | echo "unknown cross target: ${BUILD_TARGET}" && exit 1 |
| 193 | esac |