From ddc900a656de488909315acf0b0095cf14217617 Mon Sep 17 00:00:00 2001 From: Thiago Kenji Okada Date: Sun, 9 May 2021 18:30:27 -0300 Subject: [PATCH] Build BABASHKA_STATIC with musl C library (#828) * Build BABASHKA_STATIC with musl C library Based on https://github.com/babashka/pod-babashka-aws/pull/37. This is the recommended way to build static binaries with GraalVM by the documentation and multiple issues on GitHub. See: - https://www.graalvm.org/reference-manual/native-image/StaticImages/ - oracle/graal#571 (comment) The reason that building a statically binary with glibc is complicated is explained in the glib documentation: https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked_programs_need_some_shared_libraries_which_is_not_acceptable_for_me.__What_can_I_do.3F * Bring back zlib1g-dev Seems it is necessary for the non-static build. --- .circleci/config.yml | 2 +- Dockerfile | 7 +++++-- script/compile | 24 +++++++++++++++++++++++- script/setup-musl | 24 ++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) create mode 100755 script/setup-musl diff --git a/.circleci/config.yml b/.circleci/config.yml index 885555a4..2b587bd1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -105,7 +105,7 @@ jobs: name: Install native dev tools command: | sudo apt-get update - sudo apt-get -y install gcc g++ zlib1g-dev + sudo apt-get -y install g++ zlib1g-dev - run: name: Download GraalVM command: | diff --git a/Dockerfile b/Dockerfile index 004fdba4..db7ba15c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,13 @@ FROM clojure:lein-2.9.1 AS BASE +ENV DEBIAN_FRONTEND=noninteractive RUN apt update -RUN apt install --no-install-recommends -yy curl unzip build-essential zlib1g-dev +RUN apt install --no-install-recommends -yy curl unzip build-essential zlib1g-dev sudo WORKDIR "/opt" RUN curl -sLO https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.0.0/graalvm-ce-java11-linux-amd64-21.0.0.tar.gz RUN tar -xzf graalvm-ce-java11-linux-amd64-21.0.0.tar.gz -ARG BABASHKA_XMX="-J-Xmx3g" +ARG BABASHKA_XMX="-J-Xmx4500m" ENV GRAALVM_HOME="/opt/graalvm-ce-java11-21.0.0" ENV JAVA_HOME="/opt/graalvm-ce-java11-21.0.0/bin" @@ -31,6 +32,7 @@ ARG BABASHKA_FEATURE_HSQLDB= ARG BABASHKA_FEATURE_ORACLEDB= ARG BABASHKA_FEATURE_DATASCRIPT= ARG BABASHKA_FEATURE_LANTERNA= +ARG BABASHKA_STATIC= ENV BABASHKA_LEAN=$BABASHKA_LEAN ENV BABASHKA_FEATURE_CORE_ASYNC=$BABASHKA_FEATURE_CORE_ASYNC ENV BABASHKA_FEATURE_CSV=$BABASHKA_FEATURE_CSV @@ -47,6 +49,7 @@ ENV BABASHKA_FEATURE_HSQLDB=$BABASHKA_FEATURE_HSQLDB ENV BABASHKA_FEATURE_ORACLEDB=$BABASHKA_FEATURE_ORACLEDB ENV BABASHKA_FEATURE_DATASCRIPT=$BABASHKA_FEATURE_DATASCRIPT ENV BABASHKA_FEATURE_LANTERNA=$BABASHKA_FEATURE_LANTERNA +ENV BABASHKA_STATIC=$BABASHKA_STATIC COPY . . RUN ./script/uberjar diff --git a/script/compile b/script/compile index 7bce6b1d..74b04621 100755 --- a/script/compile +++ b/script/compile @@ -76,7 +76,29 @@ args=( "-jar" "$BABASHKA_JAR" BABASHKA_STATIC=${BABASHKA_STATIC:-} if [ "$BABASHKA_STATIC" = "true" ]; then - args+=("--static") + args+=("--static" "--libc=musl") + + # needs to be in a separate script as we need sudo and >> redirects in it wont work. + sudo bash script/setup-musl + + ZLIB_VERSION="1.2.11" + + curl -O -sL "https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz" + tar xf "zlib-${ZLIB_VERSION}.tar.gz" + cd "zlib-${ZLIB_VERSION}" + CC=musl-gcc ./configure --static --prefix=/usr/lib/x86_64-linux-musl/ + make CC=musl-gcc + sudo make install + export CC=gcc + cd .. + + # depending on GCC version, we will have different directories here. + # for example, for GCC 6.3.0 we will have: + # - /usr/lib/gcc/x86_64-linux-gnu/6 + # - /usr/lib/gcc/x86_64-linux-gnu/6.3.0 + for dest_dir in /usr/lib/gcc/x86_64-linux-gnu/*; do + sudo cp -f /usr/lib/x86_64-linux-musl/lib/libz.a "$dest_dir" + done fi BABASHKA_FEATURE_HSQLDB=${BABASHKA_FEATURE_HSQLDB:-} diff --git a/script/setup-musl b/script/setup-musl new file mode 100755 index 00000000..1727b2b1 --- /dev/null +++ b/script/setup-musl @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# This script sets up the latest available musl-tools using apt pinning from debian unstable. +# The one available in stable and testing are quite outdated and this ensures we get the latest improvements +# This explictly installs musl from unstable and keeps the others at a higher priority + +cat >> /etc/apt/sources.list <> /etc/apt/preferences <