由于不同的编译器对 C++ 标准的支持力度都是不同的,有些编译器可能并不支持 C++ 的一些高版本标准中的特性,这时我们就可以通过 xmake 提供的编译器特性检测接口去检测它们。
这里以 C++11 的 constexpr 为例,在编译代码时,检测判断是否支持 constexpr,如果不支持,我们就不使用这个关键字。
为了简化实验步骤,这里重新修改 xmake.lua 配置,去掉对 config.h 的使用,直接通过 check_features 接口去完成 C++ 特性的检测,例如。
includes("check_features.lua")
target("check")
set_kind("binary")
add_files("src/*.cpp")
check_features("HAS_CONSTEXPR", "cxx_constexpr")
其中 cxx_constexpr 就是指 C++ 的 constexpr 特性名称,关于完整的 C++ 特性名称列表,我们可以到 C++ 特性列表名称 查看。
然后修改 src/main.cpp 中的代码,改成如下对 constexpr 的使用。
#ifdef HAS_CONSTEXPR
constexpr int a = 1;
constexpr int c = a * 2 + 1;
#else
# error "constexpr not supported!"
#endif
int main(int argc, char** argv)
{
return 0;
}
这个时候,如果我们执行 xmake 编译后,会发现 constexpr 的特性并没有检测通过,编译也是失败的,如下图。
那是因为这个关键字仅仅只在 c++11 标准之后才生效,因此需要对 target 启用 c++11 标准,并且对于 check_features 检测接口,也需要传递 c++11 的语言标准给它才能通过检测。
因此继续修改完善 xmake.lua 配置,修改如下。
includes("check_features.lua")
target("check")
set_kind("binary")
add_files("src/*.cpp")
set_languages("c++11")
check_features("HAS_CONSTEXPR", "cxx_constexpr", {languages = "c++11"})
设置上 c++11 语言标准后,再来执行 xmake 命令就能顺利通过检测和编译了。
配置自定义 C/C++ 代码片段检测
虽然,xmake 提供了很多内置的辅助检测接口,可以方便的检测头文件、库接口、类型定义、编译器特性等等,但是对于一些比较复杂的检测,单纯靠这些是无法满足的,这时我们还可以通过 xmake 提供的通用检测接口,也就是 C/C++ 代码片段检测,来实现任意的用户检测需求。
可以在检测接口中,传入一小段 C/C++ 代码片段,来实现我们所希望的检测逻辑,其中 check_csnippets 用于检测 C 代码片段,而 check_cxxsnippets 用于检测 C++ 代码片段。
继续修改之前的 xmake.lua 文件,加上对这两个接口的配置使用,例如。
includes("check_csnippets.lua")
includes("check_cxxsnippets.lua")
target("check")
set_kind("binary")
add_files("src/*.cpp")
set_languages("c++11")
check_csnippets("HAS_STATIC_ASSERT", "_Static_assert(1, \"\");")
check_cxxsnippets("HAS_CONSTEXPR", "constexpr int a = 1;", {languages = "c++11"})
通过上面的配置,我们看到其中加了两个代码片段,一个是 C 代码片段,用来检测能否使用 _Static_assert 来实现静态断言,而另外一个是 C++ 代码片段,用来实现跟之前的编译器特性检测配置一样的效果,也就是检测 constexpr 是否可用。
但是跟之前不同的是,我们这里是直接在配置中传入了完整的 C++ 代码片段,在里面去使用 constexpr,然后 xmake 会尝试调用 gcc 等编译器去编译它,如果编译通过,就会定义 HAS_CONSTEXPR 宏,也就是通过了检测。
同时也需要修改 src/main.cpp 文件,加上对 HAS_STATIC_ASSERT 和 HAS_CONSTEXPR 的宏定义检测。
#ifdef HAS_CONSTEXPR
constexpr int a = 1;
constexpr int c = a * 2 + 1;
#else
# error "constexpr not supported!"
#endif
#ifndef HAS_STATIC_ASSERT
# error "_Static_assert not supported!"
#endif
int main(int argc, char** argv)
{
return 0;
}
然后执行 xmake 编译,如果一切顺利,就会看到下图编译通过的输出信息。
在本节实验中,我们了解了怎样才能实现跨平台开发和编译,并且主要学习了如何去使用 xmake 提供的辅助接口来配置检测 C/C++ 的头文件、库接口是否存在,以及检测指定的编译器特性和 C/C++ 代码片段是否能够支持并使用。
本实验的参考代码可以使用如下命令下载:
wget https://labfile.oss-internal.aliyuncs.com/courses/2764/code11.zip
本文介绍了如何利用Xmake进行编译器特性检测,以C++11的constexpr为例,展示了如何在不支持该特性的编译器上进行适配。通过Xmake的接口,可以方便地检测头文件、库接口、类型定义等,并提供了C/C++代码片段检测以应对复杂需求。实验中还详细说明了如何配置Xmake.lua以实现跨平台的编译检测。

2159

被折叠的 条评论
为什么被折叠?



