Skip to content

Commit d24d25c

Browse files
committed
rust: Replace keep_fingerprints logic with unconditional cargo clean
Due to Earthly's layer cache code added with `COPY` (even with `--keep-ts`) can end up with timestamps (`mtime`) corresponding to the point of creation of the cache entry, not the current time. However on a following build the `target` mount cache may contain builds from other branches, with different code for those dependencies, which have a newer `mtime`. In this case `cargo` will think it can use the cached dependency instead of rebuilding (because the code appears older than the cached entry under `target`). Avoid this by using `cargo clean` to remove the build artifacts for any local crate. This should become unnecessary with rust-lang/cargo#14136 This replaces the old behaviour of removing the fingerprints directory. Using `cargo clean` uses a proper cargo API rather than relying on implementation details like where the fingerprints live and what the consequence removing them is. It may also keep the cached data smaller since it removes the build artifacts which will likely never be reused due to the lack of fingerprint. Note that the previous fingerprint cleaning was subject to a race where a different parallel build could reintroduce some fingerprints between `DO +REMOVE_SOURCE_FINGERPRINTS` and the `RUN ... cargo $args`. For that reason the calls to `cargo clean` here are made within the same `RUN` command so that the target cache remains locked. By switching to `cargo metadata` the requirement for `tomljson` is removed.
1 parent a9b9b6e commit d24d25c

File tree

2 files changed

+4
-44
lines changed

2 files changed

+4
-44
lines changed

rust/Earthfile

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ VERSION 0.8
22
# INIT sets some configuration in the environment (used by following functions), and installs required dependencies.
33
# Arguments:
44
# - cache_prefix: Overrides cache prefix for cache IDS. Its value is exported to the build environment under the entry: $EARTHLY_CACHE_PREFIX. By default ${EARTHLY_TARGET_PROJECT_NO_TAG}#${OS_RELEASE}#earthly-cargo-cache
5-
# - keep_fingerprints (false): Instructs the following +CARGO calls to not remove the Cargo fingerprints of the source packages. Use only when source packages have been COPYed with --keep-ts option.
65
# - sweep_days (4): +CARGO uses cargo-sweep to clean build artifacts that haven't been accessed for this number of days.
76
INIT:
87
FUNCTION
@@ -17,17 +16,14 @@ INIT:
1716
ENV PATH="$PATH:$CARGO_HOME/bin"
1817
END
1918
DO +INSTALL_CARGO_SWEEP
19+
COPY +get-jq/jq /tmp/jq
2020

2121
# $EARTHLY_CACHE_PREFIX
2222
ARG EARTHLY_TARGET_PROJECT_NO_TAG #https://docs.earthly.dev/docs/earthfile/builtin-args
2323
ARG OS_RELEASE=$(md5sum /etc/os-release | cut -d ' ' -f 1)
2424
ARG cache_prefix="${EARTHLY_TARGET_PROJECT_NO_TAG}#${OS_RELEASE}#earthly-cargo-cache"
2525
ENV EARTHLY_CACHE_PREFIX=$cache_prefix
2626

27-
# $EARTHLY_KEEP_FINGERPRINTS
28-
ARG keep_fingerprints=false
29-
ENV EARTHLY_KEEP_FINGERPRINTS=$keep_fingerprints
30-
3127
# $EARTHLY_SWEEP_DAYS
3228
ARG sweep_days=4
3329
ENV EARTHLY_SWEEP_DAYS=$sweep_days
@@ -56,9 +52,6 @@ CARGO:
5652
ARG --required args
5753
ARG output
5854
DO +SET_CACHE_MOUNTS_ENV
59-
IF [ "$EARTHLY_KEEP_FINGERPRINTS" = "false" ]
60-
DO +REMOVE_SOURCE_FINGERPRINTS
61-
END
6255
RUN --mount=$EARTHLY_RUST_CARGO_HOME_CACHE --mount=$EARTHLY_RUST_TARGET_CACHE \
6356
set -e; \
6457
echo "+CARGO: cargo $args"; \
@@ -67,7 +60,9 @@ CARGO:
6760
cargo sweep -r -t $EARTHLY_SWEEP_DAYS; \
6861
cargo sweep -r -i; \
6962
echo "+CARGO: copying output"; \
70-
$EARTHLY_FUNCTIONS_HOME/copy-output.sh "$output";
63+
$EARTHLY_FUNCTIONS_HOME/copy-output.sh "$output"; \
64+
echo "+CARGO: removing local crates from target cache"; \
65+
cargo metadata --format-version=1 --no-deps | /tmp/jq -r '.packages[].name' | xargs -I{} cargo clean -p {};
7166
RUN $EARTHLY_FUNCTIONS_HOME/rename-output.sh "$output"
7267

7368
# SET_CACHE_MOUNTS_ENV sets the following entries in the environment, to be used to mount the cargo caches.
@@ -138,15 +133,6 @@ get-cross:
138133
RUN wget -nv -O- "https://github.com/cross-rs/cross/releases/download/v${version}/cross-x86_64-unknown-linux-musl.tar.gz" | tar -xzf - -C .
139134
SAVE ARTIFACT cross
140135

141-
get-tomljson:
142-
FROM alpine:3.18.3
143-
ARG USERARCH
144-
ARG version=2.1.0
145-
RUN wget -O tomljson.tar.xz https://github.com/pelletier/go-toml/releases/download/v${version}/tomljson_${version}_linux_${USERARCH}.tar.xz && \
146-
tar -xf tomljson.tar.xz; \
147-
chmod +x tomljson
148-
SAVE ARTIFACT tomljson
149-
150136
get-jq:
151137
FROM alpine:3.18.3
152138
ARG USERARCH
@@ -192,26 +178,6 @@ INSTALL_EARTHLY_FUNCTIONS:
192178
chmod +x $EARTHLY_FUNCTIONS_HOME/rename-output.sh; \
193179
fi;
194180

195-
REMOVE_SOURCE_FINGERPRINTS:
196-
FUNCTION
197-
DO +CHECK_INITED
198-
COPY +get-tomljson/tomljson /tmp/tomljson
199-
COPY +get-jq/jq /tmp/jq
200-
RUN if [ ! -n "$EARTHLY_RUST_TARGET_CACHE" ]; then \
201-
echo "+SET_CACHE_MOUNTS_ENV has not been called yet in this build environment" ; \
202-
exit 1; \
203-
fi;
204-
RUN --mount=$EARTHLY_RUST_TARGET_CACHE \
205-
set -e;\
206-
source_libs=$(find . -name Cargo.toml -exec bash -c '/tmp/tomljson {} | /tmp/jq -r .package.name; printf "\n"' \;) ; \
207-
fingerprint_folders=$(find target -name .fingerprint) ; \
208-
for fingerprint_folder in $fingerprint_folders; do \
209-
cd $fingerprint_folder; \
210-
for source_lib in $source_libs; do \
211-
find . -maxdepth 1 -regex "\./$source_lib-[^-]+" -exec bash -c 'echo "deleting $(readlink -f {})"; rm -rf {}' \; ; \
212-
done \
213-
done;
214-
215181
CHECK_INITED:
216182
FUNCTION
217183
RUN if [ ! -n "$EARTHLY_CACHE_PREFIX" ]; then \

rust/README.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ DO rust+INIT ...
2929
Overrides cache prefix for cache IDS. Its value is exported to the build environment under the entry: `$EARTHLY_CACHE_PREFIX`.
3030
By default `${EARTHLY_TARGET_PROJECT_NO_TAG}#${OS_RELEASE}#earthly-cargo-cache`
3131

32-
#### `keep_fingerprints (false)`
33-
34-
By default `+CARGO` removes the [compiler fingerprints](https://doc.rust-lang.org/nightly/nightly-rustc/cargo/core/compiler/fingerprint/struct.Fingerprint.html) of those packages found in your source code (not their dependencies), to force their recompilation and work even when the Earthly `COPY` commands overwrote file mtimes (by default).
35-
36-
Set `keep_fingerprints=true` to keep the source packages fingerprints and avoid their recompilation, when source packages have been copied with `--keep-ts `option.
37-
3832
#### `sweep_days (4)`
3933
`+CARGO` calls use cargo-sweep to clean build artifacts that haven't been accessed for this number of days.
4034

0 commit comments

Comments
 (0)