diff --git a/Cargo.lock b/Cargo.lock index 22c90e17..1866a691 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -847,6 +847,7 @@ dependencies = [ name = "conduwuit" version = "0.5.0-rc.6" dependencies = [ + "bindgen 0.71.1", "clap", "conduwuit_admin", "conduwuit_api", diff --git a/docker/Dockerfile b/docker/Dockerfile index bd6e72d1..55150902 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -78,7 +78,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ WORKDIR /app COPY ./rust-toolchain.toml . RUN rustc --version \ - && rustup target add $(xx-cargo --print-target-triple) + && xx-cargo --setup-target-triple # Build binary # We disable incremental compilation to save disk space, as it only produces a minimal speedup for this case. @@ -87,8 +87,10 @@ RUN echo "CARGO_INCREMENTAL=0" >> /etc/environment # Configure pkg-config RUN <> /etc/environment - echo "PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /etc/environment + if command -v "$(xx-info)-pkg-config" >/dev/null 2>/dev/null; then + echo "PKG_CONFIG_LIBDIR=/usr/lib/$(xx-info)/pkgconfig" >> /etc/environment + echo "PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /etc/environment + fi echo "PKG_CONFIG_ALLOW_CROSS=true" >> /etc/environment EOF @@ -109,16 +111,17 @@ RUN <> /etc/environment - echo "CXXFLAGS='${CXXFLAGS} -march=${TARGET_CPU}'" >> /etc/environment - echo "RUSTFLAGS='${RUSTFLAGS} -C target-cpu=${TARGET_CPU}'" >> /etc/environment - fi + set -o allexport + set -o xtrace + . /etc/environment + if [ -n "${TARGET_CPU}" ]; then + echo "CFLAGS='${CFLAGS} -march=${TARGET_CPU}'" >> /etc/environment + echo "CXXFLAGS='${CXXFLAGS} -march=${TARGET_CPU}'" >> /etc/environment + echo "RUSTFLAGS='${RUSTFLAGS} -C target-cpu=${TARGET_CPU}'" >> /etc/environment + fi EOF # Prepare output directories @@ -136,12 +139,12 @@ ARG TARGETPLATFORM RUN xx-cargo --print-target-triple # Conduwuit version info -ARG GIT_COMMIT_HASH= -ARG GIT_COMMIT_HASH_SHORT= -ARG GIT_REMOTE_URL= -ARG GIT_REMOTE_COMMIT_URL= -ARG CONDUWUIT_VERSION_EXTRA= -ARG CONTINUWUITY_VERSION_EXTRA= +ARG GIT_COMMIT_HASH +ARG GIT_COMMIT_HASH_SHORT +ARG GIT_REMOTE_URL +ARG GIT_REMOTE_COMMIT_URL +ARG CONDUWUIT_VERSION_EXTRA +ARG CONTINUWUITY_VERSION_EXTRA ENV GIT_COMMIT_HASH=$GIT_COMMIT_HASH ENV GIT_COMMIT_HASH_SHORT=$GIT_COMMIT_HASH_SHORT ENV GIT_REMOTE_URL=$GIT_REMOTE_URL @@ -169,7 +172,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \ jq -r ".packages[] | select(.name == \"$PACKAGE\") | .targets[] | select( .kind | map(. == \"bin\") | any ) | .name")) for BINARY in "${BINARIES[@]}"; do echo $BINARY - xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY + xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY cp $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY /out/sbin/$BINARY done EOF diff --git a/docker/musl.Dockerfile b/docker/musl.Dockerfile new file mode 100644 index 00000000..d5317d15 --- /dev/null +++ b/docker/musl.Dockerfile @@ -0,0 +1,201 @@ +# Why does this exist? +# Debian doesn't provide prebuilt musl packages +# rocksdb requires a prebuilt liburing, and linking fails if a gnu one is provided + +ARG RUST_VERSION=1 +ARG ALPINE_VERSION=3.22 + +FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx +FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS base +FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS toolchain + +# Install repo tools and dependencies +RUN --mount=type=cache,target=/etc/apk/cache apk add \ + build-base pkgconfig make jq bash \ + curl git file \ + llvm-dev clang clang-dev lld + + +# Developer tool versions +# renovate: datasource=github-releases depName=cargo-bins/cargo-binstall +ENV BINSTALL_VERSION=1.13.0 +# renovate: datasource=github-releases depName=psastras/sbom-rs +ENV CARGO_SBOM_VERSION=0.9.1 +# renovate: datasource=crate depName=lddtree +ENV LDDTREE_VERSION=0.3.7 + +# Install unpackaged tools +RUN <> /etc/environment + +# Configure pkg-config +RUN </dev/null 2>/dev/null; then + echo "PKG_CONFIG_LIBDIR=/usr/lib/$(xx-info)/pkgconfig" >> /etc/environment + echo "PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /etc/environment + fi + echo "PKG_CONFIG_ALLOW_CROSS=true" >> /etc/environment +EOF + +# Configure cc to use clang version +RUN <> /etc/environment + echo "CXX=clang++" >> /etc/environment +EOF + +# Cross-language LTO +RUN <> /etc/environment + echo "CXXFLAGS=-flto" >> /etc/environment + # Linker is set to target-compatible clang by xx + echo "RUSTFLAGS='-Clinker-plugin-lto -Clink-arg=-fuse-ld=lld'" >> /etc/environment +EOF + +# Apply CPU-specific optimizations if TARGET_CPU is provided +ARG TARGET_CPU + +RUN <> /etc/environment + echo "CXXFLAGS='${CXXFLAGS} -march=${TARGET_CPU}'" >> /etc/environment + echo "RUSTFLAGS='${RUSTFLAGS} -C target-cpu=${TARGET_CPU}'" >> /etc/environment + fi +EOF + +# Prepare output directories +RUN mkdir /out + +FROM toolchain AS builder + + +# Get source +COPY . . + +ARG TARGETPLATFORM + +# Verify environment configuration +RUN xx-cargo --print-target-triple + +# Conduwuit version info +ARG GIT_COMMIT_HASH +ARG GIT_COMMIT_HASH_SHORT +ARG GIT_REMOTE_URL +ARG GIT_REMOTE_COMMIT_URL +ARG CONDUWUIT_VERSION_EXTRA +ARG CONTINUWUITY_VERSION_EXTRA +ENV GIT_COMMIT_HASH=$GIT_COMMIT_HASH +ENV GIT_COMMIT_HASH_SHORT=$GIT_COMMIT_HASH_SHORT +ENV GIT_REMOTE_URL=$GIT_REMOTE_URL +ENV GIT_REMOTE_COMMIT_URL=$GIT_REMOTE_COMMIT_URL +ENV CONDUWUIT_VERSION_EXTRA=$CONDUWUIT_VERSION_EXTRA +ENV CONTINUWUITY_VERSION_EXTRA=$CONTINUWUITY_VERSION_EXTRA + +ARG RUST_PROFILE=release + +# Build the binary +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + --mount=type=cache,target=/app/target,id=cargo-target-${TARGET_CPU}-${TARGETPLATFORM}-musl-${RUST_PROFILE} \ + bash <<'EOF' + set -o allexport + set -o xtrace + . /etc/environment + TARGET_DIR=($(cargo metadata --no-deps --format-version 1 | \ + jq -r ".target_directory")) + mkdir /out/sbin + PACKAGE=conduwuit + xx-cargo build --locked --profile ${RUST_PROFILE} \ + -p $PACKAGE --features libclang_static; + BINARIES=($(cargo metadata --no-deps --format-version 1 | \ + jq -r ".packages[] | select(.name == \"$PACKAGE\") | .targets[] | select( .kind | map(. == \"bin\") | any ) | .name")) + for BINARY in "${BINARIES[@]}"; do + echo $BINARY + xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY + cp $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY /out/sbin/$BINARY + done +EOF + +# Generate Software Bill of Materials (SBOM) +RUN --mount=type=cache,target=/usr/local/cargo/registry \ + --mount=type=cache,target=/usr/local/cargo/git/db \ + bash <<'EOF' + set -o xtrace + mkdir /out/sbom + typeset -A PACKAGES + for BINARY in /out/sbin/*; do + BINARY_BASE=$(basename ${BINARY}) + package=$(cargo metadata --no-deps --format-version 1 | jq -r ".packages[] | select(.targets[] | select( .kind | map(. == \"bin\") | any ) | .name == \"$BINARY_BASE\") | .name") + if [ -z "$package" ]; then + continue + fi + PACKAGES[$package]=1 + done + for PACKAGE in $(echo ${!PACKAGES[@]}); do + echo $PACKAGE + cargo sbom --cargo-package $PACKAGE > /out/sbom/$PACKAGE.spdx.json + done +EOF + +# Extract dynamically linked dependencies +RUN <