Skip to content

Commit

Permalink
ci: try using arm images to build
Browse files Browse the repository at this point in the history
  • Loading branch information
PastaPastaPasta committed Feb 6, 2025
1 parent 21fb709 commit 4755d30
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 121 deletions.
23 changes: 12 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env:
jobs:
build-image:
name: Build Image
runs-on: ubuntu-22.04
runs-on: ubuntu-22.04-arm
outputs:
image-tag: ${{ steps.prepare.outputs.image-tag }}
repo-name: ${{ steps.prepare.outputs.repo-name }}
Expand Down Expand Up @@ -58,15 +58,15 @@ jobs:
build-depends:
name: Build Dependencies
needs: build-image
runs-on: ubuntu-22.04
runs-on: ubuntu-22.04-arm
strategy:
fail-fast: false
matrix:
include:
- build_target: arm-linux
host: arm-linux-gnueabihf
- build_target: linux64
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu

container:
image: ghcr.io/${{ needs.build-image.outputs.repo-name }}/dashcore-ci-runner:${{ needs.build-image.outputs.image-tag }}
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
build:
name: Build
needs: [build-image, build-depends]
runs-on: ubuntu-22.04
runs-on: ubuntu-22.04-arm
strategy:
fail-fast: false
matrix:
Expand All @@ -112,25 +112,25 @@ jobs:
host: arm-linux-gnueabihf
depends_on: arm-linux
- build_target: linux64
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
- build_target: linux64_cxx20
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
- build_target: linux64_fuzz
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
- build_target: linux64_nowallet
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
- build_target: linux64_sqlite
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
- build_target: linux64_tsan
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
- build_target: linux64_ubsan
host: x86_64-pc-linux-gnu
host: aarch64-linux-gnu
depends_on: linux64
container:
image: ghcr.io/${{ needs.build-image.outputs.repo-name }}/dashcore-ci-runner:${{ needs.build-image.outputs.image-tag }}
Expand Down Expand Up @@ -178,6 +178,7 @@ jobs:
mkdir /output
BASE_OUTDIR="/output"
BUILD_TARGET="${{ matrix.build_target }}"
HOST="${{ matrix.host }}"
source ./ci/dash/matrix.sh
./ci/dash/build_src.sh
./ci/dash/test_unittests.sh
Expand Down
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_native_tsan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ export DEP_OPTS="CC=clang-18 CXX='clang++-18 -stdlib=libc++'"
export TEST_RUNNER_EXTRA="--extended --exclude feature_pruning,feature_dbcrash,wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163)
export TEST_RUNNER_EXTRA="${TEST_RUNNER_EXTRA} --timeout-factor=4" # Increase timeout because sanitizers slow down
export GOAL="install"
export BITCOIN_CONFIG="--enable-zmq --with-gui=no --with-sanitizers=thread CC=clang-18 CXX=clang++-18 CXXFLAGS='-g' --with-boost-process"
export BITCOIN_CONFIG="--enable-zmq --with-gui=no --without-bdb --with-sanitizers=thread CC=clang-18 CXX=clang++-18 CXXFLAGS='-g' --with-boost-process"
export CPPFLAGS="-DARENA_DEBUG -DDEBUG_LOCKORDER -DDEBUG_LOCKCONTENTION"
export PYZMQ=true
263 changes: 154 additions & 109 deletions contrib/containers/ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,114 +7,171 @@ ENV DEBIAN_FRONTEND="noninteractive" TZ="Europe/London"
# (zlib1g-dev is needed for the Qt host binary builds, but should not be used by target binaries)
ENV APT_ARGS="-y --no-install-recommends --no-upgrade"

# Install packages for i386 on amd64 hosts, then install common packages
# -----------------------------------------------------------------------------
# Install base packages
# -----------------------------------------------------------------------------
RUN set -ex; \
apt-get update && \
if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
dpkg --add-architecture i386 && \
apt-get update && \
apt-get install $APT_ARGS \
g++-multilib \
wine32; \
apt-get install $APT_ARGS \
apt-transport-https \
ca-certificates \
gnupg \
software-properties-common \
wget \
curl \
xz-utils \
&& rm -rf /var/lib/apt/lists/*

# -----------------------------------------------------------------------------
# Detect host architecture and add a foreign architecture if needed.
#
# On an amd64 host, add armhf (with its dedicated sources) so that we can install
# the ARM cross‑compiler. On ARM hosts we assume that the x86_64 cross‑compiler is
# provided natively.
# -----------------------------------------------------------------------------
RUN set -ex; \
ARCH="$(dpkg --print-architecture)"; \
echo "Host architecture is: ${ARCH}"; \
if [ "${ARCH}" = "amd64" ]; then \
echo "Running on amd64; adding armhf as a foreign architecture"; \
dpkg --add-architecture armhf; \
echo "deb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports jammy main restricted universe multiverse" \
> /etc/apt/sources.list.d/armhf.list; \
fi; \
apt-get update

#
# -----------------------------------------------------------------------------
# Install common development packages (including Python via PyEnv)
# -----------------------------------------------------------------------------
ARG PYTHON_VERSION=3.9.18
RUN set -ex; \
apt-get install $APT_ARGS \
autotools-dev \
automake \
autoconf \
bison \
build-essential \
bsdmainutils \
curl \
ccache \
cmake \
g++ \
gettext \
git \
gnupg \
libtool \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-randr0 \
libxcb-render-util0 \
libxcb-shape0 \
libxcb-sync1 \
libxcb-xfixes0 \
libxcb-xinerama0 \
libxcb-xkb1 \
libxkbcommon-x11-0 \
lsb-release \
software-properties-common \
unzip \
wget \
m4 \
pkg-config \
zlib1g-dev \
build-essential \
autotools-dev \
automake \
autoconf \
bison \
bsdmainutils \
ccache \
cmake \
gawk \
gettext \
git \
libtool \
lsb-release \
m4 \
pkg-config \
unzip \
valgrind \
zlib1g-dev \
\
# Python build dependencies
libbz2-dev \
libffi-dev \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
make \
tk-dev \
&& rm -rf /var/lib/apt/lists/*

# Install Clang+LLVM and set it as default
# We don't need all packages but the default set doesn't include some
# packages we want so we will need to install some of them manually.
# Install PyEnv and the requested Python version
ENV PYENV_ROOT="/usr/local/pyenv"
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"
RUN set -ex; \
curl https://pyenv.run | bash; \
pyenv update; \
pyenv install "${PYTHON_VERSION}"; \
pyenv global "${PYTHON_VERSION}"; \
pyenv rehash; \
pip3 install --no-cache-dir \
codespell==1.17.1 \
flake8==3.8.3 \
jinja2 \
lief==0.13.2 \
multiprocess \
mypy==0.910 \
pyzmq==22.3.0 \
vulture==2.3

#
# -----------------------------------------------------------------------------
# Install LLVM/Clang (example: version 18) and set it as default
# -----------------------------------------------------------------------------
ARG LLVM_VERSION=18
RUN set -ex; \
echo "Installing LLVM and Clang ${LLVM_VERSION}..."; \
curl -sL https://apt.llvm.org/llvm.sh | bash -s -- "${LLVM_VERSION}"; \
echo "Installing additional packages..."; \
apt-get update && apt-get install $APT_ARGS \
"clang-format-${LLVM_VERSION}" \
"clang-tidy-${LLVM_VERSION}" \
"libc++-${LLVM_VERSION}-dev" \
"libc++abi-${LLVM_VERSION}-dev" \
"libclang-rt-${LLVM_VERSION}-dev" \
"lld-${LLVM_VERSION}"; \
rm -rf /var/lib/apt/lists/*; \
echo "Setting defaults..."; \
lldbUpdAltArgs="update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${LLVM_VERSION} 100"; \
"clang-format-${LLVM_VERSION}" \
"clang-tidy-${LLVM_VERSION}" \
"libc++-${LLVM_VERSION}-dev" \
"libc++abi-${LLVM_VERSION}-dev" \
"libclang-rt-${LLVM_VERSION}-dev" \
"lld-${LLVM_VERSION}" \
&& rm -rf /var/lib/apt/lists/*; \
# Set up update-alternatives for LLVM tools
ALT_CMD="update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${LLVM_VERSION} 100"; \
for binName in clang clang++ clang-format clang-tidy clangd dsymutil lld lldb lldb-server llvm-ar llvm-cov llvm-nm llvm-objdump llvm-ranlib llvm-strip; do \
lldbUpdAltArgs="${lldbUpdAltArgs} --slave /usr/bin/${binName} ${binName} /usr/bin/${binName}-${LLVM_VERSION}"; \
ALT_CMD="$ALT_CMD --slave /usr/bin/${binName} ${binName} /usr/bin/${binName}-${LLVM_VERSION}"; \
done; \
for binName in ld64.lld ld.lld lld-link wasm-ld; do \
lldbUpdAltArgs="${lldbUpdAltArgs} --slave /usr/bin/${binName} ${binName} /usr/bin/lld-${LLVM_VERSION}"; \
ALT_CMD="$ALT_CMD --slave /usr/bin/${binName} ${binName} /usr/bin/lld-${LLVM_VERSION}"; \
done; \
sh -c "${lldbUpdAltArgs}";
# LD_LIBRARY_PATH is empty by default, this is the first entry
ENV LD_LIBRARY_PATH="/usr/lib/llvm-${LLVM_VERSION}/lib"
sh -c "$ALT_CMD"

# Python setup
# PYTHON_VERSION should match the value in .python-version
ARG PYTHON_VERSION=3.9.18
RUN apt-get update && apt-get install $APT_ARGS \
ca-certificates \
libbz2-dev \
libffi-dev \
liblzma-dev \
libncurses5-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
make \
tk-dev \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
# Add LLVM libraries to LD_LIBRARY_PATH
ENV LD_LIBRARY_PATH="/usr/lib/llvm-${LLVM_VERSION}/lib"

ENV PYENV_ROOT="/usr/local/pyenv"
ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${PATH}"
RUN curl https://pyenv.run | bash \
&& pyenv update \
&& pyenv install $PYTHON_VERSION \
&& pyenv global $PYTHON_VERSION \
&& pyenv rehash
RUN pip3 install \
codespell==1.17.1 \
flake8==3.8.3 \
jinja2 \
lief==0.13.2 \
multiprocess \
mypy==0.910 \
pyzmq==22.3.0 \
vulture==2.3
#
# -----------------------------------------------------------------------------
# Install cross compilers depending on host architecture.
#
# - On amd64: install the ARM cross-compiler packages and create symlinks so that
# "arm-linux-gnueabihf-gcc" and "arm-linux-gnueabihf-g++" are available.
# - On ARM: install the x86_64 cross-compiler packages and create symlinks so that
# "x86_64-pc-linux-gnu-gcc" and "x86_64-pc-linux-gnu-g++" are available.
# -----------------------------------------------------------------------------
RUN set -ex; \
ARCH="$(dpkg --print-architecture)"; \
echo "Installing cross-compiler for ARM on amd64"; \
apt-get update && apt-get install $APT_ARGS \
gcc-arm-linux-gnueabihf \
g++-arm-linux-gnueabihf; \
\
# Create symlinks for the ARM cross-compiler.
# (Ubuntu Jammy typically installs versioned binaries—adjust the version if needed.)
ln -sf /usr/bin/arm-linux-gnueabihf-gcc-11 /usr/bin/arm-linux-gnueabihf-gcc; \
ln -sf /usr/bin/arm-linux-gnueabihf-g++-11 /usr/bin/arm-linux-gnueabihf-g++; \
if [ "${ARCH}" = "arm64" ]; then \
echo "Installing cross-compiler for x86_64 on arm64"; \
apt-get update && apt-get install $APT_ARGS \
gcc-x86-64-linux-gnu \
g++-x86-64-linux-gnu; \
binutils-x86-64-linux-gnu; \
\
# Create symlinks so that a build expecting x86_64-pc-linux-gnu-gcc/g++ will find the compiler.
ln -sf /usr/bin/x86_64-linux-gnu-gcc /usr/bin/x86_64-pc-linux-gnu-gcc; \
ln -sf /usr/bin/x86_64-linux-gnu-g++ /usr/bin/x86_64-pc-linux-gnu-g++; \
fi && \
rm -rf /var/lib/apt/lists/*

#
# -----------------------------------------------------------------------------
# Additional Tools (ShellCheck, dash_hash, Cppcheck, etc.)
# -----------------------------------------------------------------------------
ARG SHELLCHECK_VERSION=v0.9.0
RUN set -ex; \
# Example: download ShellCheck (note: the x86_64 binary won't run natively on ARM)
curl -fL \
"https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" \
-o /tmp/shellcheck.tar.xz || true; \
rm -f /tmp/shellcheck.tar.xz

# dash_hash
ARG DASH_HASH_VERSION=1.4.0
RUN set -ex; \
cd /tmp; \
Expand All @@ -132,13 +189,9 @@ RUN set -ex; \
rm -rf /tmp/cppcheck.tar.gz
ENV PATH="/opt/cppcheck/build/bin:${PATH}"

ARG SHELLCHECK_VERSION=v0.7.1
RUN set -ex; \
curl -fL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" -o /tmp/shellcheck.tar.xz; \
mkdir -p /opt/shellcheck && tar -xf /tmp/shellcheck.tar.xz -C /opt/shellcheck --strip-components=1 && rm /tmp/shellcheck.tar.xz
ENV PATH="/opt/shellcheck:${PATH}"

# Add user with specified (or default) user/group ids and setup configuration files
# -----------------------------------------------------------------------------
# Add a non-root user
# -----------------------------------------------------------------------------
ARG USER_ID=1000
ARG GROUP_ID=1000
RUN set -ex; \
Expand Down Expand Up @@ -178,16 +231,8 @@ RUN \
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; \
exit 0

RUN \
mkdir -p /src/dash && \
mkdir -p /cache/ccache && \
mkdir /cache/depends && \
mkdir /cache/sdk-sources && \
chown ${USER_ID}:${GROUP_ID} /src && \
chown ${USER_ID}:${GROUP_ID} -R /src && \
chown ${USER_ID}:${GROUP_ID} /cache && \
chown ${USER_ID}:${GROUP_ID} -R /cache

# Prepare a work directory for building
RUN mkdir -p /src/dash && chown dash:dash /src/dash
WORKDIR /src/dash

USER dash
USER dash

0 comments on commit 4755d30

Please sign in to comment.