Rust 编程: 条件编译-Features

本文深入探讨Rust的条件编译特性,包括类型条件如target_family、target_arch和target_os,以及如何在属性和宏中使用它们。文章还详细介绍了限定条件、自设条件(如rustc和cargo编译配置),并讨论了条件编译如何在Rust的模块化系统中,尤其是从根包传递到子包的方式。

Rust 编程: 条件编译-Features

Rust 支持条件编译,可通过两种不同的操作实现:

  • cfg 属性:在属性位置中使用 #[cfg(...)]
  • cfg! 宏:在布尔表达式中使用 cfg!(...)

// 根据操作系统引用不同文件的相同模块
#[cfg_attr(target_os = "linux", path = "linux.rs")]
#[cfg_attr(windows, path = "windows.rs")]
mod os;

// 函数仅当操作系统是 Linux 的时候才会编译
#[cfg(target_os = "linux")]
fn do_on_linux() {
    println!("You are running linux!")
}

// 函数仅当操作系统不是 Linux 的时候才会编译
#[cfg(not(target_os = "linux"))]
fn do_on_notlinux() {
    println!("You are *not* running linux!")
}

if cfg!(target_os = "windows") {
  // windows系统要执行的代码段
} else if cfg!(target_os = "linux") {
  // linux系统要执行的代码段
}

// 依赖自设条件是否引用模块 foo
#[cfg(feature = "foo")]
mod foo;

1. 参考资料

2. 类型条件

Rust 预设类型条件:

  • target_family : 目标操作系统的类别,比如windows和unix。这个属性可以直接作为条件使用,如#[unix],#[cfg(unix)]
  • target_arch : 目标平台的CPU架构,包括但不限于x86, x86_64, mips, powerpc, arm或aarch64
  • target_os : 目标操作系统,包括但不限于windows, macos, ios, linux, android, freebsd, dragonfly, bitrig, openbsd, netbsd
  • target_pointer_width : 目标平台的指针宽度,一般就是32或64
  • test : 启动单元测试(即编译时加了–test参数,或使用cargo test)

3. 限定条件

Rust 支持使用any,all,not等限定条件编译的条件之间的关系

4. 自设条件


// 自设条件 myfeaone 为真才会编译
#[cfg(myfeaone)]
fn do_myfeaone() {
    println!("do_myfeaone!")
}

fn main() {
    do_myfeaone();

    if cfg!(feature = "myfeatwo") {
      // 自设条件 myfeatwo 为真要执行的代码段
    }

}

4.1. rustc 编译


rustc --cfg feature="myfeaone myfeatwo" demo.rs

4.2. cargo 编译

  1. 修改 cargo.toml

[features]
myfeaone = []
myfeatwo = []

  1. 条件编译

cargo build --features="myfeaone myfeatwo"

5. 传递条件

Rust 的模块化系统: 包Packages, 箱Crates, 和模块Modules

  • packages: 通过cargo new 创建;
  • crates: 通过cargo new --lib 创建。有根包和子包。即一个根包下可以包含多个子包。
  • modules: 通过关键字mod加模块定义

Rust/Cargo 自设条件如何从根包传递到子包?

  1. 修改根包 cargo.toml

[features]
myfeaone = ["subcrateone/myfeaone", "subcratetwo/myfeaone"]
myfeatwo = ["subcrateone/myfeatwo", "subcratetwo/myfeatwo"]

  1. 修改子包 cargo.toml

[features]
myfeaone = []
myfeatwo = []

  1. 在根包目录下,条件编译

cargo build --features="myfeaone myfeatwo"

Looking in indexes: https://pypi.python.org/simple Collecting cryptography Downloading cryptography-45.0.6.tar.gz (744 kB) ---------------------------------------- 744.9/744.9 kB 3.2 MB/s 0:00:00 Installing build dependencies ... done Getting requirements to build wheel ... done Preparing metadata (pyproject.toml) ... done Requirement already satisfied: cffi>=1.14 in d:\desktop\乐骐编程\python 3.13.5\lib\site-packages (from cryptography) (1.17.1) Requirement already satisfied: pycparser in d:\desktop\乐骐编程\python 3.13.5\lib\site-packages (from cffi>=1.14->cryptography) (2.22) Building wheels for collected packages: cryptography Building wheel for cryptography (pyproject.toml) ... error error: subprocess-exited-with-error × Building wheel for cryptography (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> [189 lines of output] Running `maturin pep517 build-wheel -i D:\Desktop\乐骐编程\python 3.13.5\python3.13t.exe --compatibility off` 馃嵐 Building a mixed python/rust project 馃敆 Found pyo3 bindings with abi3 support 馃悕 Found CPython 3.13t at D:\Desktop\涔愰獝缂栫▼\python 3.13.5\python3.13t.exe 馃摗 Using build options locked from pyproject.toml 鈿狅笍 Warning: CPython 3.13t at D:\Desktop\涔愰獝缂栫▼\python 3.13.5\python3.13t.exe does not yet support abi3 so the build artifacts will be version-specific. Compiling target-lexicon v0.13.2 Compiling proc-macro2 v1.0.95 Compiling unicode-ident v1.0.18 Compiling shlex v1.3.0 Compiling once_cell v1.21.3 Compiling vcpkg v0.2.15 Compiling pkg-config v0.3.32 Compiling libc v0.2.172 Compiling cc v1.2.23 Compiling autocfg v1.4.0 Compiling openssl v0.10.72 Compiling foreign-types-shared v0.1.1 Compiling memoffset v0.9.1 Compiling heck v0.5.0 Compiling foreign-types v0.3.2 Compiling cfg-if v1.0.0 Compiling bitflags v2.9.1 Compiling itoa v1.0.15 Compiling indoc v2.0.6 Compiling unindent v0.2.4 Compiling cryptography-key-parsing v0.1.0 (C:\Users\awei006\AppData\Local\Temp\pip-install-ptzrqy6d\cryptography_dffa39c3c63c4ae4b53a322803c200d9\src\rust\cryptography-key-parsing) Compiling pyo3-build-config v0.25.0 Compiling quote v1.0.40 Compiling cryptography-openssl v0.1.0 (C:\Users\awei006\AppData\Local\Temp\pip-install-ptzrqy6d\cryptography_dffa39c3c63c4ae4b53a322803c200d9\src\rust\cryptography-openssl) Compiling base64 v0.22.1 Compiling self_cell v1.2.0 Compiling syn v2.0.101 Compiling pem v3.0.5 Compiling openssl-sys v0.9.108 Compiling cryptography-cffi v0.1.0 (C:\Users\awei006\AppData\Local\Temp\pip-install-ptzrqy6d\cryptography_dffa39c3c63c4ae4b53a322803c200d9\src\rust\cryptography-cffi) warning: openssl-sys@0.9.108: Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. See stderr section below for further information. error: failed to run custom build command for `openssl-sys v0.9.108` Caused by: process didn't exit successfully: `C:\Users\awei006\AppData\Local\Temp\pip-install-ptzrqy6d\cryptography_dffa39c3c63c4ae4b53a322803c200d9\target\release\build\openssl-sys-81bfb0a89f2ad101\build-script-main` (exit code: 101) --- stdout cargo:rustc-check-cfg=cfg(osslconf, values("OPENSSL_NO_OCB", "OPENSSL_NO_SM4", "OPENSSL_NO_SEED", "OPENSSL_NO_CHACHA", "OPENSSL_NO_CAST", "OPENSSL_NO_IDEA", "OPENSSL_NO_CAMELLIA", "OPENSSL_NO_RC4", "OPENSSL_NO_BF", "OPENSSL_NO_PSK", "OPENSSL_NO_DEPRECATED_3_0", "OPENSSL_NO_SCRYPT", "OPENSSL_NO_SM3", "OPENSSL_NO_RMD160", "OPENSSL_NO_EC2M", "OPENSSL_NO_OCSP", "OPENSSL_NO_CMS", "OPENSSL_NO_COMP", "OPENSSL_NO_SOCK", "OPENSSL_NO_STDIO", "OPENSSL_NO_EC", "OPENSSL_NO_SSL3_METHOD", "OPENSSL_NO_KRB5", "OPENSSL_NO_TLSEXT", "OPENSSL_NO_SRP", "OPENSSL_NO_RFC3779", "OPENSSL_NO_SHA", "OPENSSL_NO_NEXTPROTONEG", "OPENSSL_NO_ENGINE", "OPENSSL_NO_BUF_FREELISTS", "OPENSSL_NO_RC2")) cargo:rustc-check-cfg=cfg(openssl) cargo:rustc-check-cfg=cfg(libressl) cargo:rustc-check-cfg=cfg(boringssl) cargo:rustc-check-cfg=cfg(awslc) cargo:rustc-check-cfg=cfg(libressl250) cargo:rustc-check-cfg=cfg(libressl251) cargo:rustc-check-cfg=cfg(libressl252) cargo:rustc-check-cfg=cfg(libressl261) cargo:rustc-check-cfg=cfg(libressl270) cargo:rustc-check-cfg=cfg(libressl271) cargo:rustc-check-cfg=cfg(libressl273) cargo:rustc-check-cfg=cfg(libressl280) cargo:rustc-check-cfg=cfg(libressl281) cargo:rustc-check-cfg=cfg(libressl291) cargo:rustc-check-cfg=cfg(libressl310) cargo:rustc-check-cfg=cfg(libressl321) cargo:rustc-check-cfg=cfg(libressl332) cargo:rustc-check-cfg=cfg(libressl340) cargo:rustc-check-cfg=cfg(libressl350) cargo:rustc-check-cfg=cfg(libressl360) cargo:rustc-check-cfg=cfg(libressl361) cargo:rustc-check-cfg=cfg(libressl370) cargo:rustc-check-cfg=cfg(libressl380) cargo:rustc-check-cfg=cfg(libressl381) cargo:rustc-check-cfg=cfg(libressl382) cargo:rustc-check-cfg=cfg(libressl390) cargo:rustc-check-cfg=cfg(libressl400) cargo:rustc-check-cfg=cfg(libressl410) cargo:rustc-check-cfg=cfg(ossl101) cargo:rustc-check-cfg=cfg(ossl102) cargo:rustc-check-cfg=cfg(ossl102f) cargo:rustc-check-cfg=cfg(ossl102h) cargo:rustc-check-cfg=cfg(ossl110) cargo:rustc-check-cfg=cfg(ossl110f) cargo:rustc-check-cfg=cfg(ossl110g) cargo:rustc-check-cfg=cfg(ossl110h) cargo:rustc-check-cfg=cfg(ossl111) cargo:rustc-check-cfg=cfg(ossl111b) cargo:rustc-check-cfg=cfg(ossl111c) cargo:rustc-check-cfg=cfg(ossl111d) cargo:rustc-check-cfg=cfg(ossl300) cargo:rustc-check-cfg=cfg(ossl310) cargo:rustc-check-cfg=cfg(ossl320) cargo:rustc-check-cfg=cfg(ossl330) cargo:rustc-check-cfg=cfg(ossl340) cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_LIB_DIR X86_64_PC_WINDOWS_GNU_OPENSSL_LIB_DIR unset cargo:rerun-if-env-changed=OPENSSL_LIB_DIR OPENSSL_LIB_DIR unset cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_INCLUDE_DIR X86_64_PC_WINDOWS_GNU_OPENSSL_INCLUDE_DIR unset cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR OPENSSL_INCLUDE_DIR unset cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_DIR X86_64_PC_WINDOWS_GNU_OPENSSL_DIR unset cargo:rerun-if-env-changed=OPENSSL_DIR OPENSSL_DIR unset cargo:rerun-if-env-changed=OPENSSL_NO_PKG_CONFIG cargo:rerun-if-env-changed=PKG_CONFIG_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG cargo:rerun-if-env-changed=PKG_CONFIG cargo:rerun-if-env-changed=OPENSSL_STATIC cargo:rerun-if-env-changed=OPENSSL_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=OPENSSL_STATIC cargo:rerun-if-env-changed=OPENSSL_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_PATH_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_PATH cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64-pc-windows-gnu cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_x86_64_pc_windows_gnu cargo:rerun-if-env-changed=HOST_PKG_CONFIG_SYSROOT_DIR cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR Could not find openssl via pkg-config: Could not run `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 pkg-config --libs --cflags openssl` The pkg-config command could not be found. Most likely, you need to install a pkg-config package for your OS. If you've already installed it, ensure the pkg-config command is one of the directories in the PATH environment variable. If you did not expect this build to link to a pre-installed system library, then check documentation of the openssl-sys crate for an option to build the library from source, or disable features or dependencies that require pkg-config. note: vcpkg did not find openssl: the vcpkg-rs Vcpkg build helper can only find libraries built for the MSVC ABI. cargo:warning=Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. See stderr section below for further information. --- stderr Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. Make sure you also have the development packages of openssl installed. For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. If you're in a situation where you think the directory *should* be found automatically, please open a bug at https://github.com/sfackler/rust-openssl and include information about your system as well as this message. $HOST = x86_64-pc-windows-gnu $TARGET = x86_64-pc-windows-gnu openssl-sys = 0.9.108 It looks like you're compiling for MinGW but you may not have either OpenSSL or pkg-config installed. You can install these two dependencies with: pacman -S openssl-devel pkgconf and try building this crate again. warning: build failed, waiting for other jobs to finish... 馃挜 maturin failed Caused by: Failed to build a native library through cargo Caused by: Cargo build finished with "exit code: 101": `"cargo" "rustc" "--message-format" "json-render-diagnostics" "--locked" "--manifest-path" "C:\\Users\\awei006\\AppData\\Local\\Temp\\pip-install-ptzrqy6d\\cryptography_dffa39c3c63c4ae4b53a322803c200d9\\src\\rust\\Cargo.toml" "--release" "--lib"` Error: command ['maturin', 'pep517', 'build-wheel', '-i', 'D:\\Desktop\\乐骐编程\\python 3.13.5\\python3.13t.exe', '--compatibility', 'off'] returned non-zero exit status 1 [end of output] note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for cryptography Failed to build cryptography error: failed-wheel-build-for-install × Failed to build installable wheels for some pyproject.toml based projects ╰─> cryptography
08-29
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值