bigywater.tech
Rust · 1

Rust 项目从 cargo new 到编译运行

每个 Rust 项目都从 cargo new 开始。这篇不讲命令表,而是真的跑一遍:cargo new 到底生成了哪些文件,第一次编译做了什么、再编译一次为什么几乎不花时间,target/ 里有什么,debug 与 release 的差别,以及 cargo check 为什么更快。

5 样
cargo new 生成:Cargo.toml、src/main.rs、.gitignore、.git(Cargo.lock 与 target 此时还没有)
0.02 s
什么都没改时再 cargo build 的耗时(第一次 0.23 s)
438,120 B
hello world 的 debug 可执行文件大小

cargo new 生成了什么

实测 · 本机执行输出
  $ cargo new hello
      Creating binary (application) `hello` package
  note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
  目录树:
    .git/ (git 仓库)
    .gitignore  (8 B)
    Cargo.toml  (76 B)
    src/
      main.rs  (45 B)
  Cargo.toml:
    [package]
    name = "hello"
    version = "0.1.0"
    edition = "2024"
    
    [dependencies]
  src/main.rs:
    fn main() {
        println!("Hello, world!");
    }
  .gitignore: /target

edition 决定语言版本的一组规则(这里的 2024 是 rustc 1.98 新建项目的默认值);Cargo.toml 是人写的清单,Cargo.lock 是 cargo 生成的依赖锁定(见Cargo.lock 的作用)。

第一次编译、再编译、运行

实测 · 本机执行输出
  $ cargo build   (第 1 次,0.23 s)
     Compiling hello v0.1.0 (<实验目录>/proj/hello)
      Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.21s
  $ cargo build   (什么都没改,0.02 s)
      Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
  $ cargo run
      Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
       Running `<实验目录>/target/debug/hello`
  Hello, world!
  Cargo.lock(此刻出现):
    # This file is automatically @generated by Cargo.
    # It is not intended for manual editing.
    version = 4
    
    [[package]]
    name = "hello"
    version = "0.1.0"

cargo 把「是否需要重编」交给指纹(target/debug/.fingerprint/)判断:源文件、依赖、编译参数都没变,就直接 Finished。

target/ 里的东西

实测 · 本机执行输出
  target/ 的结构(两层):
    debug/.cargo-artifact-lock  (0 B)
    debug/.cargo-build-lock  (0 B)
    debug/.cargo-lock  (0 B)
    debug/.fingerprint/
    debug/build/
    debug/deps/
    debug/examples/
    debug/hello  (438120 B)
    debug/hello.d  (279 B)
    debug/incremental/
  可执行文件 target/debug/hello:438120 字节(428 KiB)
  改一行字符串后 $ cargo build(0.14 s):
     Compiling hello v0.1.0 (<实验目录>/proj/hello)
      Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.11s

这个目录可以随时删除,下一次 build 会重新生成;所以 .gitignore 里只有 /target。

debug、release 与 check

实测 · 本机执行输出
  $ cargo build --release(0.12 s)
     Compiling hello v0.1.0 (<实验目录>/proj/hello)
      Finished `release` profile [optimized] target(s) in 0.10s
  release 可执行文件:433792 字节;debug:438120 字节
  改源码后 $ cargo check(0.05 s):
      Checking hello v0.1.0 (<实验目录>/proj/hello)
      Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s
  改源码后 $ cargo build(0.11 s)
  $ target/release/hello 直接运行(不经过 cargo): Hello, rust! v2

release 的优化效果要在有真实计算的程序里才明显(见Debug 与 Release 构建差异);这里的 hello world 编译时间都在 0.1 s 量级,差别主要来自「要不要生成可执行文件」。

分步演示

cargo 的一次循环
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。每次实验前清空了共享的 target 目录,项目在临时目录里;时间是单次测量(一个很小的项目,0.1 s 量级的差别主要是进程启动与文件系统开销)
    • 没有验证:大项目的编译时间、增量编译的细节、rustup 与 rustc 的关系(见第 2 篇)、cargo new --lib 与 workspace、其它 edition 的差别
    京ICP备2026067502号-1京公网安备11010502063487号