Can Cargo download and build dependencies without also building the application?

若如初见. 提交于 2019-11-28 02:36:27

问题


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 .):

  1. import a docker image with rust tooling installed
  2. add my Cargo.toml and Cargo.lock files
  3. download and build all dependencies
  4. add my source directory to the image
  5. build my source code

Run time (docker run ...):

  1. 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.


回答1:


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 dummy src/lib.rs), then calls cargo build and cargo build --release to compile the crates:

RUN cd / && \
    cargo new playground
WORKDIR /playground

ADD Cargo.toml /playground/Cargo.toml
RUN cargo build
RUN cargo build --release
RUN rm src/*.rs

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 applications target/{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.




回答2:


If you add a dummy main or lib file, you can use cargo build to just pull down the dependencies. I'm currently using this solution for my Docker based project:

COPY Cargo.toml .
RUN mkdir src \
    && echo "// dummy file" > src/lib.rs \
    && cargo build

I'm using --volumes, so I'm done at this point. The host volumes come in and blow away the dummy file, and cargo uses the cached dependencies when I go to build the source later. This solution will work just as well if you want to add a COPY (or ADD) later and use the cached dependencies though.




回答3:


Based on a GitHub comment

FROM rust:1.37

WORKDIR /usr/src

# Create blank project
RUN USER=root cargo new PROJ

# We want dependencies cached, so copy those first.
COPY Cargo.toml /usr/src/PROJ/
COPY Cargo.lock /usr/src/PROJ/

WORKDIR /usr/src/PROJ

# This is a dummy build to get the dependencies cached.
RUN cargo build --release

# Now copy in the rest of the sources
COPY MyPROJECT/src /usr/src/PROJ/src/

# This is the actual build.
RUN cargo build --release \
    && mv target/release/appname /bin \
    && rm -rf /usr/src/PROJ

WORKDIR /

EXPOSE 8888

CMD ["/bin/appname"]


来源:https://stackoverflow.com/questions/42130132/can-cargo-download-and-build-dependencies-without-also-building-the-application

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!