程序宏位于它们自己的板条箱中,这些板条是为开发机器编译的(因此,在编译使用它们的板条箱时可以执行它们)。因此,程序宏板条箱中的任何conditional compilation指令都将基于their编译环境,而不是调用板条箱的编译环境。
当然,这样的宏可以扩展为包含条件编译指令的令牌,然后在调用板条箱的编译上下文中对其进行评估-但是,这并非总是可能或不希望的。
如果希望扩展令牌本身成为调用板条箱的编译环境的功能,则需要宏在运行时(当然是调用板条箱的编译时)确定该环境。显然,std::env
模块是一个完美的用例。
但是,rustc不会设置任何环境变量;而货运只设置std::env
。特别是,一些关键信息(如目标体系结构/操作系统等)根本不存在。
[我很高兴调用箱中的构建脚本可以为宏设置环境变量然后读取,但这给调用箱作者带来了不尽人意的负担。
proc宏作者可以通过任何方式获取有关调用板条箱的编译环境(目标架构和操作系统对我最感兴趣的信息)的[[runtime信息吗?]
一个hack,但是可以用。
如果是
regular Rust代码,则很可能会使用#[cfg_attr]
宏为自己收集#[cfg_attr(all(target_os = "linux"), my_macro(linux = true ))]
#[cfg_attr(not(target_os = "linux"), my_macro(linux = false))]
// ...
信息,并根据此信息定义条件编译的不同结果。
这种行为的粗略例子是:
cfg
尽管这并没有做任何特别有用的事情,但是您知道了。谁说一个宏不能产生另一个宏? ;)