Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use sccache to improve build time #81

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 80 additions & 37 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,37 +1,3 @@
# always build this using the latest stable release
FROM rust:1.71.0 as build


ARG JQ_VERSION=1.6
ARG JQ_URL=https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64

# install cargo-local-registry dependencies
RUN apt-get update && apt-get install -y gcc openssl cmake

RUN mkdir -p /rust-test-runner/src
ENV wd /rust-test-runner
WORKDIR ${wd}
COPY Cargo.* ./
# for caching, we want to download and build all the dependencies before copying
# any of the real source files. We therefore build an empty dummy library,
# then remove it.
RUN echo '// dummy file' > src/lib.rs
RUN cargo build
# now get rid of the stub and copy the real source files
RUN rm src/lib.rs
COPY src/* src/
# build the executable
RUN cargo build --release
# download jq
RUN curl -L -o /usr/local/bin/jq "${JQ_URL}" \
&& chmod +x /usr/local/bin/jq
# install cargo-local-registry
RUN cargo install cargo-local-registry
# download popular crates to local registry
WORKDIR /local-registry
COPY local-registry/* ./
RUN cargo generate-lockfile && cargo local-registry --sync Cargo.lock .

# As of Dec 2019, we need to use the nightly toolchain to get JSON test output
# tracking issue: https://github.com/rust-lang/rust/issues/49359

Expand All @@ -45,7 +11,7 @@ RUN cargo generate-lockfile && cargo local-registry --sync Cargo.lock .

################ start-copy-pasta ################

FROM debian:bookworm-slim
FROM debian:bookworm-slim as rust-nightly

ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo \
Expand Down Expand Up @@ -87,19 +53,96 @@ RUN set -eux; \

################ end-copy-pasta ################

# The build stage must use the same compiler version as the test runner itself,
# otherwise sccache will not work. Compilation artifacts from different versions
# of the Rust compiler are incompatible.
FROM rust-nightly as build

ARG JQ_VERSION=1.6
ARG JQ_URL=https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64

ARG SC_VERSION=v0.5.4
ARG SC_URL=https://github.com/mozilla/sccache/releases/download/${SC_VERSION}/sccache-${SC_VERSION}-x86_64-unknown-linux-musl.tar.gz

ENV SCCACHE_DIR=/opt/compilation-cache
ENV RUSTC_WRAPPER=/usr/local/bin/sccache

# install basic things missing in debian-slim
RUN apt-get update && apt-get install -y curl

# download sccache
RUN curl -L -o sccache.tgz "${SC_URL}" \
&& tar xvzf sccache.tgz --strip-components=1 \
&& cp sccache ${RUSTC_WRAPPER} \
&& chmod +x ${RUSTC_WRAPPER}
RUN mkdir -p ${SCCACHE_DIR}

# install cargo-local-registry dependencies
RUN apt-get update && apt-get install -y \
gcc openssl cmake \
# needed due to use of debian-slim. regular debian has these already.
libssl-dev pkg-config

RUN mkdir -p /rust-test-runner/src
ENV wd /rust-test-runner
WORKDIR ${wd}
COPY Cargo.* ./

# for caching, we want to download and build all the dependencies before copying
# any of the real source files. We therefore build an empty dummy library,
# then remove it.
RUN echo '// dummy file' > src/lib.rs
RUN cargo build
# now get rid of the stub and copy the real source files
RUN rm src/lib.rs
COPY src/* src/
# build the executable
RUN cargo build --release
# download jq
RUN curl -L -o /usr/local/bin/jq "${JQ_URL}" \
&& chmod +x /usr/local/bin/jq
# install cargo-local-registry
RUN cargo install cargo-local-registry
# download popular crates to local registry
WORKDIR /local-registry
COPY local-registry/* ./
RUN cargo generate-lockfile && cargo local-registry --sync Cargo.lock .
# only keep the local registry
RUN rm Cargo.* dummy.rs

# The environment should be as identical as possible between populating and
# using the compilation cache, so we put this environment in a separate build
# stage that can be shared.
FROM rust-nightly as test-env

ENV SCCACHE_DIR=/opt/compilation-cache
ENV RUSTC_WRAPPER=/usr/local/bin/sccache
COPY --from=build ${RUSTC_WRAPPER} ${RUSTC_WRAPPER}
RUN mkdir -p ${SCCACHE_DIR}

ENV wd /opt/test-runner
RUN mkdir -p ${wd}/bin
WORKDIR ${wd}
COPY --from=build /rust-test-runner/target/release/transform-output bin
COPY --from=build /usr/local/bin/jq /usr/local/bin
# configure local-registry
# configure local registry
COPY --from=build /local-registry local-registry/
RUN echo '[source.crates-io]\n\
registry = "https://github.com/rust-lang/crates.io-index"\n\
replace-with = "local-registry"\n\
\n\
[source.local-registry]\n\
local-registry = "/opt/test-runner/local-registry/"\n' >> $CARGO_HOME/config.toml
# set entrypoint

# populate compilation cache in the same environment as the tests will run
FROM test-env AS cache
RUN apt-get update && apt-get install -y m4
WORKDIR /local-registry
COPY local-registry/* ./
RUN cargo build

# final stage
FROM test-env
COPY --from=cache ${SCCACHE_DIR} ${SCCACHE_DIR}
COPY bin/run.sh bin
ENTRYPOINT ["bin/run.sh"]
File renamed without changes.