Search code examples
rust

how to clean specific crates in cargo cache / during dockerfile build optimization


Scenario

To optimize build runtimes I want to pre-compile dependencies.
When running the Dockerfile below, during the final build cargo still has Dummy main.

# Copy only the Cargo files to leverage caching
COPY Cargo.toml Cargo.lock ./
COPY Cargo.toml Cargo.lock ./

COPY ./compA/Cargo.toml ./compA/
COPY ./compB/Cargo.toml ./compB/

RUN  mkdir -p ./compA/src && echo "fn main() { println!(\"Dummy main\"); }" > ./compA/src/lib.rs
RUN  mkdir -p ./compB/src && echo "fn main() { println!(\"Dummy main\"); }" > ./compB/src/main.rs

RUN cargo fetch

# || true allows to succeed even if a dependency wasn't available (as it's being compiled in here as well)
RUN cargo build --release || true

# Copy the actual source code
COPY . .

# clean specifically the two dummy sections
cargo clean -p compA -p compB

# Now compile the actual src code
RUN cargo build --release

even though that the code is present:

#30 [builder 24/29] RUN cat compA/src/lib.rs
#30 0.319 // expected source code
#30 DONE

the main is still cached:

#35 [builder 29/29] RUN cargo build --release
#35 0.534 warning: function is never used: `main`
#35 0.482  --> compA/src/lib.rs:1:4
#35 0.482   |
#35 0.482 1 | fn main() { println!("Dummy main"); }
#35 0.482   |    ^^^^
#35 0.482   |

when I run a full cargo clean, then it is properly removed, along with all other dependencies which I want to prevent.

Summary

cargo clean #works but deletes too much
cargo clean -p compA #no effect
cargo clean -p [email protected] #error even though thats the SPEC syntax from cargo pkid

Any idea?


Solution

  • Update the timestamp of those files by running touch in the Dockerfile:

    # After copying files and cleaning specific parts of the build cache
    RUN touch ./compA/src/lib.rs
    RUN touch ./compB/src/main.rs
    
    # Then build
    RUN cargo build --release