Может ли Cargo загружать и строить зависимости без создания приложения?
Есть ли способ сказать Cargo для установки и сборки всех моих зависимостей, но не попытки создать мое приложение?
Я думал, что cargo install
будет делать это, но на самом деле все идет так же, как и при создании моего приложения. Я хочу добраться до состояния, в котором cargo build
найдет все зависимости, готовые к использованию, но не касаясь каталога /src
.
То, что я действительно пытаюсь сделать:
Я пытаюсь создать образ Docker для приложения Rust, где я бы хотел сделать следующие шаги:
Время сборки (docker build.
):
- импортировать изображение докера с установленным ржавчиной
- добавьте мои файлы Cargo.toml и Cargo.lock
- загружать и строить все зависимости
- добавить исходный каталог к изображению
- создать исходный код
Время выполнения (docker run...
):
- запустить приложение
Я пробовал следующий 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
до тех пор, пока не установит зависимости, поскольку это приведет к аннулированию кэшированного изображения при изменении моего собственного кода.
Ответы
Ответ 1
Насколько мне известно, нет никакой поддержки для создания только зависимостей в Cargo. Для него есть открытый вопрос. Я бы не удивился, если бы вы могли что-то передать Каргу, чтобы выполнить его, или, возможно, создать сторонний грузовой аддон. Я хотел эту функциональность для cargo doc
, когда мой собственный код слишком сломан, чтобы компилировать ;-)
Тем не менее, площадка Rust, которую я поддерживаю, достигает конечной цели. Там есть базовый контейнер Docker, который устанавливает Rustup и копирует в Cargo.toml
со всеми ящиками, доступными для игровой площадки. На этапах сборки создается пустой проект (с манекеном src/lib.rs
), затем вызывается cargo build
и cargo 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 image $HOME/.cargo
и все встроенные ящики хранятся в каталогах target/{debug,release}
.
Позже, реальные исходные файлы копируются в контейнер, а cargo build
cargo run
/cargo run
может быть выполнена снова, используя теперь скомпилированные ящики.
Если вы строите исполняемый проект, вы также хотите скопировать в Cargo.lock.
Ответ 2
Если вы добавите фиктивный основной файл или файл lib, вы можете использовать cargo build
чтобы просто сбрасывать зависимости. В настоящее время я использую это решение для моего проекта на базе Docker:
COPY Cargo.toml .
RUN mkdir src \
&& echo "// dummy file" > src/lib.rs \
&& cargo build
Я использую --volumes
, поэтому я закончил на этом этапе. Хост-хосты входят и сбрасывают фиктивный файл, а груз использует кэшированные зависимости, когда я иду для создания источника позже. Это решение будет работать так же хорошо, если вы хотите позже добавить COPY
(или ADD
) и использовать кэшированные зависимости.
Ответ 3
Основано на комментарии 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"]