You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Cargo复用已编译本地Rust库并避免依赖全量重建?

问题描述

我在同一个单体仓库(monorepo)中维护一个Rust主项目和一个Rust库项目,主项目的Cargo.toml通过本地路径引用该库:

aws_tools = { path = "../../shared/rust/my_tools/" }

编译库项目会生成libmy_tools.rlib文件,但主项目编译时并不会复用该文件,而是重新编译库的所有源码,导致无法利用已编译库加速Docker容器构建。
此外,每当更新aws_tools的任意源码文件时,pw_uploader的所有依赖都会重新构建,而非仅aws_tools本身。请问如何解决这两个问题?

我的Dockerfile
FROM --platform=linux/arm64 rust:slim as build

# Install required dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    build-essential \
    pkg-config \
    libssl-dev


# Copy files for the library projects
WORKDIR /usr/src/my_application/shared/rust/aws_tools
COPY ./shared/rust/aws_tools/Cargo.toml ./shared/rust/aws_tools/Cargo.lock ./
COPY ./shared/rust/aws_tools/src/ ./src/


# Create a new empty shell project
WORKDIR /usr/src/my_application/docker 
RUN cargo init --bin pw-uploader
WORKDIR /usr/src/my_application/docker/pw-uploader

# Copy the Cargo.toml files for the main project 
COPY ./docker/pw-uploader/Cargo.toml  ./docker/pw-uploader/Cargo.lock ./

# Build the dependencies for the main project
RUN cargo build --release 

# Build the main project
COPY ./docker/pw-uploader/src/  ./src/
RUN touch ./src/main.rs && cargo build --release


FROM --platform=linux/arm64 debian:bullseye

RUN apt-get update 
RUN apt-get upgrade
RUN apt-get install -y --no-install-recommends libc6-dev 
RUN apt-get install -y --no-install-recommends libssl-dev
RUN apt-get install -y --no-install-recommends ca-certificates
RUN apt-get clean

RUN update-ca-certificates

WORKDIR /usr/src/app
# Copy the built project and its dependencies from the main project build image
COPY --from=build /usr/src/my_application/docker/pw-uploader/target/release/pw_uploader .


# Start the application
CMD ["./pw_uploader"]
解决方案

一、解决主项目复用已编译库的问题

核心是让Cargo共享编译产物目录,自动识别并复用已编译的库文件。

1. 设置共享编译目录

在Docker的build阶段,通过CARGO_TARGET_DIR环境变量指定统一的编译产物目录,让库和主项目的编译结果都存放在这里,Cargo会自动复用已有产物:

ENV CARGO_TARGET_DIR=/usr/src/target

2. 提前编译库项目

在构建主项目之前完成库的编译,产物存入共享目录,主项目构建时直接取用:

# 构建库项目
WORKDIR /usr/src/my_application/shared/rust/aws_tools
COPY ./shared/rust/aws_tools/Cargo.toml ./shared/rust/aws_tools/Cargo.lock ./
COPY ./shared/rust/aws_tools/src/ ./src/
RUN cargo build --release

二、解决更新库时全量重建依赖的问题

问题根源是Docker构建缓存失效,通过拆分构建步骤精准控制缓存触发条件。

1. 拆分库的构建步骤

先复制库的Cargo.toml和Cargo.lock缓存依赖下载,再复制真实源码编译,确保只有源码变更时才重建库:

WORKDIR /usr/src/my_application/shared/rust/aws_tools
# 先缓存依赖
COPY ./shared/rust/aws_tools/Cargo.toml ./shared/rust/aws_tools/Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/lib.rs && cargo build --release
# 再复制真实源码并重新构建
COPY ./shared/rust/aws_tools/src/ ./src/
RUN cargo build --release

2. 拆分主项目的构建步骤

同样先缓存主项目依赖,再复制源码构建,使用--only-deps参数只构建依赖(包括已编译的库):

WORKDIR /usr/src/my_application/docker/pw-uploader
# 缓存主项目依赖
COPY ./docker/pw-uploader/Cargo.toml ./docker/pw-uploader/Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release --only-deps
# 复制真实源码构建主项目
COPY ./docker/pw-uploader/src/ ./src/
RUN touch ./src/main.rs && cargo build --release

完整优化后的Dockerfile

FROM --platform=linux/arm64 rust:slim as build

# 设置共享编译目录
ENV CARGO_TARGET_DIR=/usr/src/target

# 安装系统依赖并清理缓存
RUN apt-get update && \
    apt-get install -y --no-install-recommends build-essential pkg-config libssl-dev && \
    rm -rf /var/lib/apt/lists/*

# 构建库项目:先缓存依赖,再编译真实源码
WORKDIR /usr/src/my_application/shared/rust/aws_tools
COPY ./shared/rust/aws_tools/Cargo.toml ./shared/rust/aws_tools/Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/lib.rs && cargo build --release
COPY ./shared/rust/aws_tools/src/ ./src/
RUN cargo build --release

# 构建主项目:先缓存依赖,再编译真实源码
WORKDIR /usr/src/my_application/docker/pw-uploader
COPY ./docker/pw-uploader/Cargo.toml ./docker/pw-uploader/Cargo.lock ./
RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release --only-deps
COPY ./docker/pw-uploader/src/ ./src/
RUN touch ./src/main.rs && cargo build --release

# 生成最终镜像
FROM --platform=linux/arm64 debian:bullseye

RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends libc6-dev libssl-dev ca-certificates && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    update-ca-certificates

WORKDIR /usr/src/app
COPY --from=build /usr/src/target/release/pw_uploader .

CMD ["./pw_uploader"]

优化效果

  • 主项目构建时直接复用已编译的库文件,无需重新编译库源码
  • 更新库源码时,仅重新构建库本身,主项目的其他依赖不会触发重建
  • 充分利用Docker缓存,大幅缩短构建时间

内容的提问来源于stack exchange,提问作者Oleksii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:08:09