Skip to content

Commit

Permalink
static: new script to build via Alpine chroot
Browse files Browse the repository at this point in the history
also switch back to older alpine 3.17 because of broken git in aarch64
alpine builds.
  • Loading branch information
breuner committed Jun 2, 2024
1 parent 508a7ca commit 3835ee2
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
### General Changes
* Timestamps in csv files now include milliseconds for higher precision.
* Updated S3 to latest AWS SDK CPP v1.11.319.
* Added new script in `build_helpers/chroot` to build static executable via Alpine chroot.

### Contributors
Thanks to Casey Peel, Michael Shustin, Erez Horev and Github user russki for code contributions. Thanks to Andy Black and Github user mhanafi1970 for helpful comments and suggestions.
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ endif
# Dynamic or static linking
ifeq ($(BUILD_STATIC), 1)
LDFLAGS += -static
# NOTE: Alpine v3.20+ requires additional "-l cares -l zstd"
LDFLAGS_S3_STATIC += -l curl -l ssl -l crypto -l tls -l z -l nghttp2 -l brotlidec -l brotlicommon \
-l idn2 -l unistring -l cares -l psl -l zstd -l dl
-l idn2 -l unistring -l psl -l dl
else # dynamic linking
LDFLAGS_S3_DYNAMIC += -l curl -l ssl -l crypto -l z -l dl
endif
Expand Down Expand Up @@ -312,12 +313,14 @@ endif

clean-externals:
ifdef BUILD_VERBOSE
rm -f $(EXTERNAL_PATH)/alpine-chroot-install
rm -rf $(EXTERNAL_PATH)/Simple-Web-Server
rm -rf $(EXTERNAL_PATH)/uWebSockets
rm -rf $(EXTERNAL_PATH)/aws-sdk-cpp $(EXTERNAL_PATH)/aws-sdk-cpp_install
rm -rf $(EXTERNAL_PATH)/mimalloc
else
@echo "[DELETE] EXTERNALS"
@rm -f $(EXTERNAL_PATH)/alpine-chroot-install
@rm -rf $(EXTERNAL_PATH)/Simple-Web-Server
@rm -rf $(EXTERNAL_PATH)/uWebSockets
@rm -rf $(EXTERNAL_PATH)/aws-sdk-cpp $(EXTERNAL_PATH)/aws-sdk-cpp_install
Expand Down
143 changes: 143 additions & 0 deletions build_helpers/chroot/build_static_local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/bin/bash
#
# Build static arm64 executable in Alpine chroot.
# Call this script from the repository root dir.
#
# For cross-compile on Ubuntu x86_64:
# * Install binfmt support and qemu to enable running non-native executables:
# $ sudo apt-get install qemu binfmt-support qemu-user-static
# * Register multiarch support:
# $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
# * Try running an arm64 executable:
# $ docker run --rm -t arm64v8/ubuntu uname -m

# NOTE on Alpine v3.17:
# * Alpine v3.18-3.20 fail on ARM64 with git clone error "bad address".
# * Alpine v3.20+ requires "apk add c-ares-static zstd-static";
# see Makefile alpine 3.20 hint for linker flags

CHROOT_PATH=${CHROOT_PATH:="/var/tmp/elbencho_chroot_$(whoami)"}
CHROOT_VERSION="v3.17" # see note on alpine 3.17 above
ELBENCHO_VERSION=$(make version)
BUILD_ARCH=${BUILD_ARCH:="$(uname -m)"} # e.g. aarch64, x86_64
ALPINE_SCRIPT_PATH=${ALPINE_SCRIPT_PATH:="external/alpine-chroot-install"}

ALTHTTPSVC_SUPPORT="${OVERRIDE_ALTHTTPSVC_SUPPORT:-0}"
S3_SUPPORT="${OVERRIDE_S3_SUPPORT:-1}"
USE_MIMALLOC="${OVERRIDE_USE_MIMALLOC:-1}"

# Cross-compile is mem intensive, so limit to one proc per GB RAM
RAM_GB=$(grep MemTotal /proc/meminfo | awk '{printf "%."d"f\n", $2 / 1024 / 1024}')
RAM_GB=$((RAM_GB > 1 ? RAM_GB : 1))
NUM_JOBS=${NUM_JOBS:="$(( $(nproc) > RAM_GB ? RAM_GB : $(nproc) ))"}


################## START OF FUNCTION DEFINITIONS #################

# call chroot destroy script if it exists and exit with error.
cleanup_chroot_and_exit()
{
if [ -f "$CHROOT_PATH/destroy" ]; then
echo
echo "*** Cleaning up chroot..."
sudo "$CHROOT_PATH/destroy" --remove
fi

exit 1
}

################## END OF FUNCTION DEFINITIONS ###################


echo "Building static executable..."

echo
echo "BUILD_ARCH: $BUILD_ARCH; CHROOT_VERSION: $CHROOT_VERSION; NUM_JOBS: $NUM_JOBS"
echo "(RAM_GB: $RAM_GB; nproc: $(nproc))"

if [ -f "$CHROOT_PATH/destroy" ]; then
echo
echo "*** Cleaning up old chroot..."
sudo "$CHROOT_PATH/destroy" --remove
fi

echo
echo "*** Cleaning build dir..."

# NOTE: clean-all has to come before chroot install script download, because clean-all will
# delete the script, thus we run this outside of the chroot.
make clean-all

if [ $? -ne 0 ]; then
echo "ERROR: Cleaning build dir failed."
cleanup_chroot_and_exit
exit 1
fi

echo
echo "*** Preparing chroot setup..."

wget https://raw.githubusercontent.com/alpinelinux/alpine-chroot-install/v0.14.0/alpine-chroot-install \
-O "$ALPINE_SCRIPT_PATH"
echo "ccbf65f85cdc351851f8ad025bb3e65bae4d5b06 $ALPINE_SCRIPT_PATH" | sha1sum -c
chmod +x "$ALPINE_SCRIPT_PATH"

# note: "-i $(pwd)" bind-mounts the current dir into the chroot under the same path
sudo "$ALPINE_SCRIPT_PATH" -b "$CHROOT_VERSION" -a "$BUILD_ARCH" \
-d "$(realpath "$CHROOT_PATH")" -i $(pwd) -p \
"bash boost-dev build-base gcc g++ git libaio-dev make numactl-dev \
cmake curl-dev curl-static openssl-libs-static ncurses-static \
boost-static ncurses zlib-static libretls-static nghttp2-static \
brotli-static ncurses-dev sudo tar libidn2-static libunistring-static \
libpsl-static"

if [ $? -ne 0 ]; then
echo "ERROR: Preparation of chroot failed."
cleanup_chroot_and_exit
exit 1
fi

echo
echo "*** Setting git parallelism...."

sudo "$CHROOT_PATH/enter-chroot" -u $(whoami) \
git config --global submodule.fetchJobs "$NUM_JOBS"
sudo "$CHROOT_PATH/enter-chroot" -u $(whoami) \
git config --global fetch.parallel "$NUM_JOBS"

echo
echo "*** Building in chroot..."

sudo "$CHROOT_PATH/enter-chroot" -u $(whoami) make -C "$(pwd)" -j $NUM_JOBS \
BACKTRACE_SUPPORT=0 ALTHTTPSVC_SUPPORT=$ALTHTTPSVC_SUPPORT \
S3_SUPPORT=$S3_SUPPORT USE_MIMALLOC=$USE_MIMALLOC BUILD_STATIC=1

if [ $? -ne 0 ]; then
echo "ERROR: Build failed."
cleanup_chroot_and_exit
exit 1
fi

bin/elbencho --version && \
file bin/elbencho | grep static && \
cp -v bin/elbencho bin/elbencho-${ELBENCHO_VERSION}-static-"$BUILD_ARCH" && \
tar -czf ./packaging/elbencho-${ELBENCHO_VERSION}-static-"$BUILD_ARCH".tar.gz -C bin ./elbencho

if [ $? -ne 0 ]; then
echo "ERROR: Executable packaging failed."
cleanup_chroot_and_exit
exit 1
fi

echo
echo "All Done. Your tar file is here:" && \
find ./packaging -maxdepth 1 -name "*-static-*.tar.gz" && \


if [ -f "$CHROOT_PATH/destroy" ]; then
echo
echo "*** Cleaning up chroot..."
sudo "$CHROOT_PATH/destroy" --remove
fi

exit 0
17 changes: 11 additions & 6 deletions build_helpers/docker/build_arm64_static_local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@
# * Try running an arm64 executable:
# $ docker run --rm -t arm64v8/ubuntu uname -m

# NOTE on Alpine v3.17:
# * Alpine v3.18-3.20 fail on ARM64 with git clone error "bad address".
# * Alpine v3.20+ requires "apk add c-ares-static zstd-static";
# see Makefile alpine 3.20 hint for linker flags

CONTAINER_NAME="elbencho-static"
IMAGE_NAME="alpine:3"
IMAGE_NAME="alpine:3.17" # see note on alpine 3.17 above
ELBENCHO_VERSION=$(make version)

ALTHTTPSVC_SUPPORT="${OVERRIDE_ALTHTTPSVC_SUPPORT:-0}"
Expand All @@ -24,20 +29,20 @@ USE_MIMALLOC="${OVERRIDE_USE_MIMALLOC:-1}"
# Cross-compile is mem intensive, so limit to one proc per GB RAM
RAM_GB=$(grep MemTotal /proc/meminfo | awk '{printf "%."d"f\n", $2 / 1024 / 1024}')
RAM_GB=$((RAM_GB > 1 ? RAM_GB : 1))
NUM_JOBS=$(( $(nproc) > RAM_GB ? RAM_GB : $(nproc) ))
NUM_JOBS=${NUM_JOBS:="$(( $(nproc) > RAM_GB ? RAM_GB : $(nproc) ))"}

echo "Calculated NUM_JOBS: $NUM_JOBS (RAM_GB: $RAM_GB, nproc: $(nproc))"
echo "NUM_JOBS: $NUM_JOBS (RAM_GB: $RAM_GB, nproc: $(nproc))"

docker rm $CONTAINER_NAME

#docker pull $IMAGE_NAME && \
docker run --platform linux/arm64 --name $CONTAINER_NAME --privileged -it -v $PWD:$PWD -w $PWD $IMAGE_NAME \
docker run --platform linux/arm64 --name $CONTAINER_NAME --privileged -i -v $PWD:$PWD -w $PWD $IMAGE_NAME \
sh -c "\
apk add bash boost-dev build-base gcc g++ git libaio-dev make numactl-dev \
c-ares-static cmake curl-dev curl-static openssl-libs-static ncurses-static \
cmake curl-dev curl-static openssl-libs-static ncurses-static \
boost-static ncurses zlib-static libretls-static nghttp2-static \
brotli-static ncurses-dev sudo tar libidn2-static libunistring-static \
libpsl-static zstd-static && \
libpsl-static && \
apk update && apk upgrade && \
adduser -u $UID -D builduser && \
sudo -u builduser git config --global submodule.fetchJobs $NUM_JOBS && \
Expand Down
12 changes: 8 additions & 4 deletions build_helpers/docker/build_static_local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
# Note: For podman's docker interface (e.g. RHEL8) remove "sudo -u builduser",
# because it already runs under the calling UID.

# NOTE on Alpine v3.17:
# * Alpine v3.18-3.20 fail on ARM64 with git clone error "bad address".
# * Alpine v3.20+ requires "apk add c-ares-static zstd-static";
# see Makefile alpine 3.20 hint for linker flags.
CONTAINER_NAME="elbencho-static"
IMAGE_NAME="alpine:3"
IMAGE_NAME="alpine:3.17" # see note on alpine 3.17 above
ELBENCHO_VERSION=$(make version)

ALTHTTPSVC_SUPPORT="${OVERRIDE_ALTHTTPSVC_SUPPORT:-1}"
Expand All @@ -20,13 +24,13 @@ rm -f packaging/elbencho-\${ELBENCHO_VERSION}-static-$(uname -m).tar.gz
docker rm $CONTAINER_NAME

docker pull $IMAGE_NAME && \
docker run --name $CONTAINER_NAME --privileged -it -v $PWD:$PWD -w $PWD $IMAGE_NAME \
docker run --name $CONTAINER_NAME --privileged -i -v $PWD:$PWD -w $PWD $IMAGE_NAME \
sh -c "\
apk add bash boost-dev build-base gcc g++ git libaio-dev make numactl-dev \
c-ares-static cmake curl-dev curl-static openssl-libs-static ncurses-static \
cmake curl-dev curl-static openssl-libs-static ncurses-static \
boost-static ncurses zlib-static libretls-static nghttp2-static \
brotli-static ncurses-dev sudo tar libidn2-static libunistring-static \
libpsl-static zstd-static && \
libpsl-static && \
apk update && apk upgrade && \
adduser -u $UID -D builduser && \
sudo -u builduser git config --global submodule.fetchJobs 0 && \
Expand Down
1 change: 1 addition & 0 deletions external/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
alpine-chroot-install
Simple-Web-Server/
aws-sdk-cpp/
aws-sdk-cpp_install/
Expand Down

0 comments on commit 3835ee2

Please sign in to comment.