Rust: 新手看的 内置 cfg 速查表

读完这篇,你应该能:

  • 知道 什么叫 cfg,它和 feature 有何区别;
  • 会用 rustc --print cfg 找到自己目标平台的 "开关";
  • 大概记住 什么时候 才需要写 #[cfg(...)]------其余时候就让编译器自动干活。

cfg 是什么?为什么要管它?

cfg = configuration,

Rust 的 条件编译 机制。

编译期根据真假裁剪代码 / 依赖,而 不会 增加运行时代码路径。

语法入口:

  • #[cfg(name)] / #[cfg(name = "value")]
  • cfg!(name)(编译时求值,返回 bool)
  • Cargo 专用:[target.'cfg(...)'.dependencies]

怎么查看自己有哪些内置 cfg?

bash 复制代码
rustc --print cfg                              # 当前主机
rustc --print cfg --target x86_64-unknown-linux-musl   # 指定目标

全部内置 cfg------按"你可能关心的顺序"分 6 类

类别 代表 cfg 说明 / 典型用途
A. 构建模式 & panic debug_assertions test panic="unwind" / "abort" 开 debug 断言?写单元测试?想把 panic 改为 crash?
B. 平台家族 unix windows target_family="unix" 一行判断 "有没有 fork()" 或 "路径分隔符是 \ 还是 /"
C. 具体 OS / 发行商 / 环境 target_os="linux" target_vendor="apple" 区分 Linux-glibc / Linux-musl / macOS / Android...
D. CPU 架构 & 数据布局 target_arch="x86_64" target_pointer_width="64" target_endian="little" 写裸机 / FFI / 内存映射时决定字节序、指针大小
E. CPU 指令特性 target_feature="sse2" target_feature="neon" ... 写 SIMD、加速 AES/SHA、Run-time feature detection
F. 原子指令支持 target_has_atomic="64" "128" "ptr" 在 no-std/嵌入式里判断能否安全使用 AtomicU64/128

想看自己电脑的真实列表?直接跑 rustc --print cfg,结果大概就和你贴的一样。

A. 构建模式 & panic

cfg 何时为真 用来干啥
debug_assertions cargo build(debug profile 保留开销较大的检测:debug_assert!() / 额外日志
test cargo test 时 在测试代码里启用内部 helper
panic="unwind" vs "abort" 由 panic = "..." (Cargo.toml [profile]) 决定 依赖栈展开的接口(catch_unwind、C++ FFI)

B. 平台家族 (最粗粒度)

cfg 平台 常见 if 分支
unix / target_family="unix" Linux, macOS, *BSD, Android, iOS... 使用 libc、std::os::unix::fs::PermissionsExt
windows / target_family="windows" Windows 路径分隔 \、WinAPI FFI
wasm / target_family="wasm"(夜版) WebAssembly no-std + wasm-bindgen

C. OS / vendor / env / abi

cfg 例子 什么时候才需要
target_os "linux"、"macos"、"android"... 系统调用号、socket 特性、文件权限
target_vendor "apple" "pc" "unknown" 很少单独用;偶尔区分 Apple vs. PC BSD
target_env "gnu" "musl" "msvc" 选 glibc / musl / MSVC CRT,或链接方式不同
target_abi "eabi" "gnueabihf" 裸机 ARM,决定调用约定 & 浮点规则
rust 复制代码
#[cfg(all(target_os = "linux", target_env = "musl"))]
static LIBC_PATH: &str = "/lib/ld-musl-x86_64.so.1";

D. CPU 架构 & 数据布局

cfg 例子 何用
target_arch "x86_64" "aarch64" "riscv64" 包含对应 core::arch::* 模块
target_pointer_width "32" "64" 数据结构 on-disk 格式是否需要固定 64-bit
target_endian "little" "big" 网络协议、读写 mmap 文件
target_cpu(nightly) native / znver4 生成汇编时推断微架构

E. CPU 指令特性 (target_feature)

这些是 "默认就启用" 的特性;若想手动开关,可用 RUSTFLAGS='-C target-feature=+aes,+neon' cargo build

常见 ARM (aarch64):

  • neon -- SIMD 基础

  • aes / sha2 / sha3 -- 专用加密指令

  • lse -- 更强的原子读改写

  • fp16 -- 半精度浮点

  • rdm -- carry-less multiply 常见 x86_64:

  • sse2, avx, avx2, aes, pclmulqdq, sha, bmi2... 示例

rust 复制代码
#[cfg(target_feature = "neon")]
pub fn mul_matrix_neon(a: &[f32], b: &[f32]) { ... }

#[cfg(not(target_feature = "neon"))]
pub fn mul_matrix_scalar(a: &[f32], b: &[f32]) { ... }

F. 原子指令宽度

cfg 值 意义
target_has_atomic="8" / "16" / "32" / "64" / "128" CPU 原生支持该位宽的 Atomic*
target_has_atomic="ptr" 保障 AtomicUsize 可用

嵌入式裸机经常碰到 没有 64-bit 原子 的情况:

rust 复制代码
#[cfg(target_has_atomic = "64")]
static CNT: AtomicU64 = AtomicU64::new(0);

#[cfg(not(target_has_atomic = "64"))]
static CNT: core::cell::Cell<u64> = Cell::new(0); // 退化实现

写法小抄

3.1 代码里裁剪

rust 复制代码
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;

#[cfg(windows)]
use std::os::windows::fs::MetadataExt;

3.2 Cargo 里裁剪依赖

toml 复制代码
[target.'cfg(target_os = "linux")'.dependencies]
nix = "0.27"

[target.'cfg(target_arch = "aarch64")'.dependencies]
faster-aarch64 = "2"

3.3 批量宏(自定义)

rust 复制代码
macro_rules! cfg_unix {
    ($($item:item)*) => {
        $(
            #[cfg(unix)]
            $item
        )*
    }
}

cfg_unix! {
    pub fn only_unix() { /* ... */ }
}

我到底什么时候才需要手写 cfg?

  • 跨平台库:同一份源码想在 Windows、Linux、WASM 都编过。
  • 性能极限:在支持 AVX2 的机器上走 SIMD,不支持就退纯标量。
  • no-std / bare-metal:32-bit MCU 没有 64-bit 原子,必须降级实现。
  • 区分 debug / release:调试版打开额外检查。
  • 挑 libc:Docker alpine (musl) 静态链接 vs. 普通 glibc。
  • 如果你的项目只在 单一 平台运行(比如 WebAssembly + wasm-bindgen),理论上可以一行 cfg 都不写------Rust 会按默认三元组把代码全部编进来。

参考命令 & 资料

bash 复制代码
rustc --print cfg                           # 当前 cfg 列表
rustc --print target-spec-json --target ...   # 夜ly可用,查看详细 target
RUSTFLAGS='-C target-feature=?' rustc -      # 查看可选特性
Rust Reference -- Conditional Compilation
Cargo Book -- Target-specific Dependencies
The Rustonomicon -- Unstable Features & target_feature

结语 cfg 像一把"手术刀": 用它,可以把同一套代码精准切割给不同平台;不用时,也不会带来任何运行时成本。 只要记得这 6 大类常用 cfg,遇到跨平台场景再回来查表就足够了。Pomelo_刘金 ,转载请注明出处,感谢! Happy hacking!

相关推荐
m0_480502642 小时前
Rust 登堂 之 函数式编程(三)
开发语言·后端·rust
小喷友9 小时前
阶段一:入门(理解 Rust 的基本概念)
前端·rust
m0_480502641 天前
Rust 入门 注释和文档之 cargo doc (二十三)
开发语言·后端·rust
盒马盒马1 天前
Rust:变量、常量与数据类型
开发语言·rust
傻啦嘿哟1 天前
Rust爬虫实战:用reqwest+select打造高效网页抓取工具
开发语言·爬虫·rust
咸甜适中2 天前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十四)垂直滚动条
笔记·学习·rust·egui
张志鹏PHP全栈2 天前
Rust第四天,Rust中常见编程概念
后端·rust
咸甜适中2 天前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(十五)网格布局
笔记·学习·rust·egui
susnm3 天前
最后的最后
rust·全栈
bruce541104 天前
深入理解 Rust Axum:两种依赖注入模式的实践与对比(二)
rust