Rust中的cfg是条件编译(Configuration)的缩写,用于根据不同编译条件选择性地包含或排除代码。 ‌

基本用法

使用#[cfg(name)]属性标记代码块,其中name为条件编译表达式。例如:

  • #[cfg(target_os = “linux”)]:仅在Linux系统编译时包含该代码块

  • #[cfg(not(target_os = “windows”))]:在非Windows系统编译时包含该代码块 ‌
    常用预定义属性

  • ‌操作系统‌:target_os(如”linux”、”windows”) ‌

  • ‌架构‌:target_arch(如”x86_64”) ‌

  • ‌环境‌:target_env(如”gnu”(Linux)或”msvc”(Windows)) ‌

  • ‌特性‌:feature(需在Cargo.toml中定义并启用) ‌
    查看所有内置cfg

    通过命令rustc –print cfg查看当前平台支持的配置选项,指定目标平台可用–target参数(如rustc –print cfg –target x86_64-unknown-linux-musl)。 ‌

测试相关用法
使用#[cfg(test)]标记测试代码,仅在Cargo测试时编译。例如:

1
2
3
4
#[cfg(test)]  
fn test_example() {
// 测试代码
}

测试代码需放在tests目录下,并通过cargo test –test test_example.rs运行。

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

想看自己电脑的真实列表?直接跑 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,决定调用约定 & 浮点规则
1
2
#[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… 示例
1
2
3
4
5
#[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 原子 的情况:

1
2
3
4
5
#[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 代码里裁剪

1
2
3
4
5
#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;

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

3.2 Cargo 里裁剪依赖

1
2
3
4
5
[target.'cfg(target_os = "linux")'.dependencies]
nix = "0.27"

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

3.3 批量宏(自定义)

1
2
3
4
5
6
7
8
9
10
11
12
macro_rules! cfg_unix {
($($item:item)*) => {
$(
#[cfg(unix)]
$item
)*
}
}

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