Is there a way to tell Cargo to install and build all my dependencies, but not attempt to build my application?
I thought cargo install
would do that, but it actually goes all the way to building my app too. I want to get to a state where cargo build
would find all dependencies ready to use, but without touching the /src
directory.
What I'm really trying to accomplish:
I'm trying to build a Docker image for a Rust application, where I'd like to do the following steps:
Build time (docker build .
):
- import a docker image with rust tooling installed
- add my Cargo.toml and Cargo.lock files
- download and build all dependencies
- add my source directory to the image
- build my source code
Run time (docker run ...
):
- run the application
I've tried the following Dockerfile
, but the indicated step builds my application as well (which of course fails since the source directory isn't there yet):
FROM jimmycuadra/rust
ADD Cargo.toml /source
ADD Cargo.lock /source
RUN cargo install # <-- failure here
ADD src /source/src
RUN cargo build
ENTRYPOINT cargo run
The reason I want to separate the install dependencies step from actually building my application, is that if I don't change the dependencies, I want Docker to be able use a cached image with all dependencies already installed and built. Thus, I can't ADD /src /source/src
until after installing the dependecies, as that would invalidate the cached image when I change my own code.
Best Answer
There is no native support for building just the dependencies in Cargo, as far as I know. There is an open issue for it. I wouldn't be surprised if you could submit something to Cargo to accomplish it though, or perhaps create a third-party Cargo addon. I've wanted this functionality for
cargo doc
as well, when my own code is too broken to compile ;-)However, the Rust playground that I maintain does accomplish your end goal. There's a base Docker container that installs Rustup and copies in a
Cargo.toml
with all of the crates available for the playground. The build steps create a blank project (with a dummysrc/lib.rs
), then callscargo build
andcargo build --release
to compile the crates:All of the downloaded crates are stored in the Docker image's
$HOME/.cargo
directory and all of the built crates are stored in the applicationstarget/{debug,release}
directories.Later on, the real source files are copied into the container and
cargo build
/cargo run
can be executed again, using the now-compiled crates.If you were building an executable project, you'd want to copy in the Cargo.lock as well.