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!

相关推荐
维维酱9 分钟前
Rust - 用异步替代线程实现并发
rust
Source.Liu11 小时前
【unitrix】 3.0 基本结构体(types.rs)
rust
大卫小东(Sheldon)2 天前
git-intelligence-message 1.3.2 发布了,智能生成、提交git的工具
git·rust
林太白2 天前
Rust-连接数据库
前端·后端·rust
林太白2 天前
Rust认识安装
前端·后端·rust
火柴就是我2 天前
每日见闻之Rust中的日志输出
rust
UestcXiye2 天前
Rust 学习笔记:面向对象语言的特点
rust
火鸟22 天前
Rust 通用代码生成器:莲花,红莲尝鲜版三十六,哑数据模式图片初始化功能介绍
开发语言·后端·rust·通用代码生成器·莲花·红莲·图片初始化功能
林太白3 天前
Rust项目搭建
前端·后端·rust