rust 我可以阻止cargo在每个新项目中重建库吗?

2admgd59  于 11个月前  发布在  Go
关注(0)|答案(3)|浏览(164)

假设我执行了cargo new one --bincargo new two --bin,然后将相同的依赖项添加到每个项目的Cargo.toml中,并构建它们。
现在有两个完全相同的库集合:
/one/目标/调试/deps/ *.rlib
/两个/目标/调试/deps/ *.rlib
它们都是相同的文件,浪费了存储空间,但真正的问题是,我必须为每个项目重新编译这些库。这需要很长的时间。cargo install也有同样的问题。
我是否可以指定一个位置来存储编译后的库以避免重新编译?

jk9hmnmh

jk9hmnmh1#

多个Cargo项目可能会使用相同的目标目录来共享这些库。

.货物/配置

在项目中放置一个“.cargo”文件夹,并在其中创建一个包含以下内容的“config”文件:

[build]
target-dir = "/path/to/your/shared/target/dir"

字符串
在Unix上,这可能类似于:

mkdir ~/shared_rust_target
mkdir .cargo
echo "[build]" > .cargo/config
echo "target-dir = \"$HOME/shared_rust_target\"" >> .cargo/config

货物_目标_方向

设置CARGO_TARGET_DIRenvironment variable
在Unix上,这可能类似于:

export CARGO_TARGET_DIR="$HOME/shared_rust_target"


请参阅this PR以取得其他target-dir文件。
特别是,在Cargo 1.9之前,不应该在同一个目标目录中同时构建多个项目。(Here's more关于Cargo 1.9如何支持并发构建)。
Cargo docs中也提到了target-dir
应工作,按this issue
P.S.现在还可以通过workspaces实现板条箱的重复使用。
P.S. https://docs.rs/cargo-hakari/latest/cargo_hakari/有助于保持项目之间的一些依赖关系兼容。

i34xakig

i34xakig2#

即使有办法做到这一点,你可能也不想这么做。仅仅因为你碰巧使用了相同的库并不意味着它们被编译成了相同的库。例如,Cargo支持特性的概念,编译时间配置改变了crate的编译方式。
同样,你可能需要支持多个版本的Rust,比如nightly和stable。或者你可能需要为不同的架构交叉编译。每一个版本都会产生不同的代码。
Cargo * 将 * 缓存单个项目的构建产品,所以我发现开销并不明显,我编译了很多在Stack Overflow上提问的人的项目!:-)

42fyovps

42fyovps3#

我设法从几个答案中拼凑出代码,但主要是this one。这个Dockerfile不仅应该缓存Cargo依赖下载,还应该缓存它们的编译和crates.io索引。我能找到的所有其他答案都只缓存下载或索引,而不是两者兼而有之。

FROM arm64v8/rust as builder

# Capture dependencies
COPY Cargo.toml Cargo.lock /app/

# We create a dummy main.rs to build deps
WORKDIR /app
RUN mkdir src && echo "fn main() {}" > src/main.rs
# RUN rustup install nightly && rustup default nightly

# This step compiles only our dependencies and saves them in a layer. This is the most impactful time savings
# Note the use of --mount=type=cache. On subsequent runs, we'll have the crates already downloaded
RUN --mount=type=cache,target=/usr/local/cargo/registry cargo build --release && rm src/main.rs

# Copy our sources
COPY ./src /app/src

# A bit of magic here!
# * We're mounting that cache again to use during the build, otherwise it's not present and we'll have to download those again - bad!
# * Rust here is a bit fiddly, so we'll touch the files (even though we copied over them) to force a new build
RUN --mount=type=cache,target=/usr/local/cargo/registry \
    set -e && \
    # update timestamps to force a new build &&
    touch /app/src/main.rs && \
    cargo build --release

# Again, our final image is the same - a slim base and just our app
FROM debian:buster-slim as app
COPY --from=builder /app/target/release/app/app
CMD ["/app"]

字符串
请注意FROM arm64v8,如果您的目标是x86,请将builderapp FROM替换为各自的x86版本。

相关问题