web-dev-qa-db-ja.com

Cargoは、アプリケーションをビルドせずに依存関係をダウンロードしてビルドできますか?

Cargo にすべての依存関係をインストールしてビルドするように指示する方法はありますが、アプリケーションのビルドは試みませんか?

cargo installでそれができると思いましたが、実際にはアプリの構築にも役立ちます。 cargo buildディレクトリにアクセスせずに、/srcがすべての依存関係をすぐに使用できる状態にしたいと考えています。


私が本当に達成しようとしていること:

Rustアプリケーション用のDockerイメージを構築しようとしています。ここで、次の手順を実行します。

ビルド時間(docker build .):

  1. RustツールがインストールされているDockerイメージをインポートする
  2. cargo.tomlファイルとCargo.lockファイルを追加します
  3. すべての依存関係をダウンロードしてビルドする
  4. ソースディレクトリを画像に追加します
  5. ソースコードをビルドする

実行時(docker run ...):

  1. アプリケーションを実行する

次のDockerfileを試しましたが、示された手順でアプリケーションもビルドされます(もちろん、ソースディレクトリがまだないため失敗します)。

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

インストールの依存関係のステップを実際にアプリケーションをビルドすることから分離したい理由は、依存関係を変更しない場合、Dockerがすべての依存関係がすでにインストールおよびビルドされているキャッシュイメージを使用できるようにするためです。したがって、依存関係をインストールした後までADD /src /source/srcできません。これは、自分のコードを変更すると、キャッシュされたイメージが無効になるためです。

22
Tomas Aschan

私の知る限り、Cargoで依存関係だけを構築するためのネイティブサポートはありません。 未解決の問題 があります。ただし、Cargoに何かを送信してそれを達成したり、サードパーティのCargoアドオンを作成したりしても驚かないでしょう。自分のコードが壊れすぎてコンパイルできない場合は、cargo docにもこの機能が必要でした;-)

しかし、私が維持している 錆の遊び場 はあなたの最終目標を達成します。 Rustupをインストールして Cargo.toml にコピーする ベースDockerコンテナ があり、すべてのクレートが遊び場で利用できます。 ビルドステップで空のプロジェクト(ダミーのsrc/lib.rsを使用)を作成し、cargo buildcargo build --releaseを呼び出してクレートをコンパイルします

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

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

ダウンロードされたすべてのクレートはDockerイメージの$HOME/.cargoディレクトリに保存され、ビルドされたすべてのクレートはアプリケーションのtarget/{debug,release}ディレクトリに保存されます。

後で、実際のソースファイルがコンテナにコピーされ、コンパイルされたクレートを使用してcargo build/cargo runを再度実行できます。

実行可能プロジェクトをビルドしている場合は、Cargo.lockにもコピーする必要があります。

10
Shepmaster

ダミーのメインファイルまたはlibファイルを追加する場合は、cargo buildを使用して依存関係をプルダウンできます。私は現在、Dockerベースのプロジェクトにこのソリューションを使用しています。

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

--volumesを使用しているので、この時点で完了です。ホストボリュームが入ってダミーファイルを吹き飛ばし、後でソースをビルドするときに、cargoはキャッシュされた依存関係を使用します。このソリューションは、後でCOPY(またはADD)を追加し、キャッシュされた依存関係を使用する場合にも同様に機能します。

3
Zac Delventhal

GitHubコメント に基づく

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"]

私はこれをここに投稿したかったので、他の人がそれを今後見ることができます。私が使い始めたばかりのDocker用の実験的なツールがcargo-wharf( https://github.com/denzp/cargo-wharf/tree/master/cargo-wharf-frontend )と呼ばれています。ビルドされた貨物の依存関係をキャッシュするのは、DockerBuildKitフロントエンドです。ソースファイルの1つだけを変更した場合、docker buildを呼び出したときに再構築されるのはそれだけです。 Cargo.tomlファイルに注釈を付けてから、DockerをDockerfileではなくCargo.tomlに転送することで使用します。それをチェックしてください、それはまさに私が欲しかったものです。 (私はこのプロジェクトとは一切関係がありません。)

0
user96425