Add --linux-compat build option for Ubuntu 20.04 binaries

Build release binaries inside an Ubuntu 20.04 Docker container
to produce executables with lower GLIBC requirements, compatible
with older Linux distributions.

- Add Dockerfile.compat (Ubuntu 20.04 base, full depends rebuild)
- Add .dockerignore to exclude host build artifacts from context
- Add --linux-compat flag to build.sh with Docker build/extract/package
- Strip binaries inside container to avoid root ownership issues
This commit is contained in:
2026-03-10 19:39:55 -05:00
parent 449a00434e
commit 6d56ad8541
3 changed files with 114 additions and 1 deletions

27
.dockerignore Normal file
View File

@@ -0,0 +1,27 @@
.git
release
depends/built
depends/work
depends/x86_64-unknown-linux-gnu
depends/x86_64-w64-mingw32
src/RandomX/build
src/*.o
src/*.a
src/*.la
src/*.lo
src/.libs
src/.deps
src/univalue/.libs
src/univalue/.deps
src/cc/*.o
src/cc/*.a
src/dragonxd
src/dragonx-cli
src/dragonx-tx
src/dragonxd.exe
src/dragonx-cli.exe
src/dragonx-tx.exe
sapling-output.params
sapling-spend.params
config.status
config.log

31
Dockerfile.compat Normal file
View File

@@ -0,0 +1,31 @@
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
build-essential pkg-config libc6-dev m4 g++-multilib autoconf libtool \
ncurses-dev unzip python3 zlib1g-dev wget bsdmainutils automake cmake \
libcurl4-openssl-dev curl git binutils \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY . /build/
# Clean host-built depends and src artifacts to force full rebuild inside container
RUN rm -rf /build/depends/built /build/depends/work \
/build/depends/x86_64-unknown-linux-gnu \
/build/depends/x86_64-w64-mingw32 \
/build/src/RandomX/build \
&& find /build/src -name '*.o' -o -name '*.a' -o -name '*.la' -o -name '*.lo' \
-o -name '*.lai' | xargs rm -f \
&& rm -rf /build/src/univalue/.libs /build/src/univalue/.deps \
&& rm -rf /build/src/.libs /build/src/.deps \
&& rm -rf /build/src/cc/*.o /build/src/cc/*.a \
&& rm -f /build/config.status /build/config.log
RUN cd /build && ./util/build.sh --disable-tests -j$(nproc)
# Strip binaries inside the container so extracted files are already small
RUN strip /build/src/dragonxd /build/src/dragonx-cli /build/src/dragonx-tx
CMD ["/bin/bash"]

View File

@@ -14,6 +14,7 @@ RELEASE_DIR="$SCRIPT_DIR/release"
BUILD_LINUX_RELEASE=0
BUILD_WIN_RELEASE=0
BUILD_MAC_RELEASE=0
BUILD_LINUX_COMPAT=0
REMAINING_ARGS=()
for arg in "$@"; do
@@ -21,6 +22,9 @@ for arg in "$@"; do
--linux-release)
BUILD_LINUX_RELEASE=1
;;
--linux-compat)
BUILD_LINUX_COMPAT=1
;;
--win-release)
BUILD_WIN_RELEASE=1
;;
@@ -110,8 +114,59 @@ package_release() {
}
# Handle release builds
if [ $BUILD_LINUX_RELEASE -eq 1 ] || [ $BUILD_WIN_RELEASE -eq 1 ] || [ $BUILD_MAC_RELEASE -eq 1 ]; then
if [ $BUILD_LINUX_COMPAT -eq 1 ] || [ $BUILD_LINUX_RELEASE -eq 1 ] || [ $BUILD_WIN_RELEASE -eq 1 ] || [ $BUILD_MAC_RELEASE -eq 1 ]; then
mkdir -p "$RELEASE_DIR"
if [ $BUILD_LINUX_COMPAT -eq 1 ]; then
echo "=== Building Linux compat release (Ubuntu 20.04 via Docker) ==="
if ! command -v docker &>/dev/null; then
echo "Error: docker is required for --linux-compat builds"
exit 1
fi
# Use sudo for docker if the user isn't in the docker group
DOCKER_CMD="docker"
if ! docker info &>/dev/null 2>&1; then
echo "Note: Using sudo for docker (add yourself to the docker group to avoid this)"
DOCKER_CMD="sudo docker"
fi
DOCKER_IMAGE="dragonx-compat-builder"
COMPAT_PLATFORM="linux-amd64-ubuntu2004"
COMPAT_RELEASE_DIR="$RELEASE_DIR/dragonx-$VERSION-$COMPAT_PLATFORM"
echo "Building Docker image (Ubuntu 20.04 base)..."
$DOCKER_CMD build -f Dockerfile.compat -t "$DOCKER_IMAGE" .
echo "Extracting binaries from Docker image..."
CONTAINER_ID=$($DOCKER_CMD create "$DOCKER_IMAGE")
mkdir -p "$COMPAT_RELEASE_DIR"
for bin in dragonxd dragonx-cli dragonx-tx; do
$DOCKER_CMD cp "$CONTAINER_ID:/build/src/$bin" "$COMPAT_RELEASE_DIR/$bin"
done
$DOCKER_CMD rm "$CONTAINER_ID" >/dev/null
# Fix ownership (docker cp creates root-owned files)
# Binaries are already stripped inside the Docker container
if [ "$(stat -c '%U' "$COMPAT_RELEASE_DIR/dragonxd")" = "root" ]; then
sudo chown "$(id -u):$(id -g)" "$COMPAT_RELEASE_DIR"/dragonx*
fi
# Copy common files
cp "$SCRIPT_DIR/util/bootstrap-dragonx.sh" "$COMPAT_RELEASE_DIR/"
cp "$SCRIPT_DIR/contrib/asmap/asmap.dat" "$COMPAT_RELEASE_DIR/" 2>/dev/null || true
cp "$SCRIPT_DIR/sapling-output.params" "$COMPAT_RELEASE_DIR/" 2>/dev/null || true
cp "$SCRIPT_DIR/sapling-spend.params" "$COMPAT_RELEASE_DIR/" 2>/dev/null || true
echo "Compat release packaged: $COMPAT_RELEASE_DIR"
ls -la "$COMPAT_RELEASE_DIR"
# Show glibc version requirement
echo ""
echo "Binary compatibility info:"
objdump -T "$COMPAT_RELEASE_DIR/dragonxd" | grep -oP 'GLIBC_\d+\.\d+' | sort -uV | tail -1 && echo "(max GLIBC version required)"
fi
if [ $BUILD_LINUX_RELEASE -eq 1 ]; then
echo "=== Building Linux release ==="