我想用crate cpp创建一个宏,但是这个crate有宏扩展的问题。
上下文
crate的工作原理是获取内联C代码的cpp!{ ... }
宏,将其内容编译为函数,然后用结果函数替换宏调用。这是通过在build.rs
中调用cpp_build::build("src/lib.rs")
来触发的。
问题
正如crate的作者所述,cpp!
宏在宏扩展之前被编译。这意味着它将尝试按原样解释宏的参数,并在宏声明中进行扩展。
在调用cpp_build
函数之前,是否有方法可以触发build.rs
内部特定宏或文件的扩展?
1条答案
按热度按时间baubqpgj1#
实现这一点的方法是不使用宏(技术上)。
syn
crate有一个parse_file
函数,你可以从构建脚本中调用它。然后,您必须遍历语法树并找到实际的宏调用。syn
有一个visit
特性(请参阅模块文档),它将帮助您完成此操作。使用syn
定位宏调用时,可以直接运行宏。然后,您需要提供您自己的宏版本(如果它们不是您自己的),通过从
Cargo.toml
中删除proc_macro
属性并将这些版本添加到dev-dependencies
,将内部内容暴露给构建脚本。请注意,只有当你没有询问
cpp!{}
宏中嵌套的宏时,这才有效-如果你是,宏的内部只能被视为语义上的令牌流(即使它是纯Rust代码),syn将给予你。如果内部代码是有效的Rust,则需要使用syn::parse
手动重新处理。如果是C/C++,你必须提供并扩展一个带有Rust宏支持的C/C++解析器-但你可能可以采取更好/更简单的方法。