有时,您希望根据编译器支持的功能来控制是否构建构建目标。例如,假设您有一个测试文件“test_constexpr_128.cpp”,它需要三个关键功能才能构建
constexpr
关键字。__int128
数据类型。显然,如果编译器不支持这些功能,那么即使尝试构建测试程序也没有意义。主要优点包括:
回到我们的示例,测试用例可能在其 Jamfile 中通过“run”规则执行
run test_constexpr_128.cpp ;
现在我们需要使此目标有条件地依赖于必要的功能。我们可以在 Jamfile 的开头导入必要的规则来做到这一点
import path-to-config-lib/checks/config : requires ;
假设测试用例位于常用目录
libs/yourlib/test
那么导入规则实际上将是
import ../../config/checks/config : requires ;
然后将“requires”规则调用添加到目标的需求部分
run test_constexpr_128.cpp : : : #requirements: [ requires cxx11_constexpr cxx11_user_defined_literals int128 ] ;
请注意,可以向 requires 规则添加多个参数,并且这些参数始终与 Boost.Config 宏名称相同,但小写且删除了boost_no_ 或boost_has_ 前缀。您还可以使用任何 C++ 标准功能宏名称,并删除前导下划线(参见下面的更多信息)。
构建上述示例时,您将在构建过程的开始看到配置结果,例如,C++11模式下的 GCC 给出
- Boost.Config Feature Check: int128 : yes - Boost.Config Feature Check: cxx11_constexpr : yes - Boost.Config Feature Check: cxx11_user_defined_literals : yes
如果您希望使构建有条件地依赖于 C++ 标准功能宏,那么您也可以指定它们,只需删除名称中的前导下划线即可。例如
[ requires cpp_constexpr ]
需要 C++11 样式的常量表达式。如果您想指定特定标准的宏,则可以在其后附加下划线,然后是标准的(两位数)年份,例如
[ requires cpp_constexpr_17 ]
对于 C++17 constepxr。如果您没有指定标准,则会获得引入宏的第一个版本。此外,对于宏的每个版本升级,只有特定于标准的规则,因此
[ requires cpp_if_constexpr_17 ]
很好,因为宏是在 C++17 中引入的,并且与未版本化的名称相同,但是
[ requires cpp_if_constexpr_20 ]
将导致构建错误,因为__cpp_if_constexpr
没有 C++20 版本升级。
这就是这个方便功能的全部内容,如果您随时不确定要传递给“requires”规则的功能测试名称,则可以在 libs/config/checks/Jamfiles.v2 中搜索感兴趣的 Boost.Config 宏,并且功能检查的名称将跟随它。
最后,此功能构建在 Boost.Build 内置规则check-target-builds 之上,可用于执行更通用的构建时功能测试。此库中的检查作为便捷的简写提供,无需您自己编写测试用例。