我想编写一个 cmake 文件,在调试和发布版本中为 clang++、g++ 和 MSVC 设置不同的编译器选项。我目前正在做的事情看起来像这样:
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++latest /W4")
# Default debug flags are OK
set(CMAKE_CXX_FLAGS_RELEASE "{CMAKE_CXX_FLAGS_RELEASE} /O2")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z -Wall -Wextra -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} some other flags")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
else()
# nothing special for gcc at the moment
endif()
endif()
但我有几个问题:
- 首先是微不足道的:真的没有像 appen 这样的命令可以让我用
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} Foo")
append(CMAKE_CXX_FLAGS "Foo")
吗? - 我已经读过很多次了,不应该首先手动设置
CMAKE_CXX_FLAGS
和类似的变量,但我不确定要使用什么其他机制。 - 最重要的是:我在这里做的方式,我需要为每个编译器和配置一个单独的构建目录理想情况下,我想将其转换为同一目录中的多个目标,这样我就可以调用
make foo_debug_clang
。
所以我的问题是
- a) 有没有更好的方法来编写解决我的“痛点”的 cmake 脚本?解决上述几点?
- b) 关于如何建立此类项目,是否存在类似公认的现代最佳实践?
我可以在互联网上找到的大多数参考资料要么已过时,要么仅显示琐碎的示例。我目前使用 cmake3.8,但如果这有什么不同,我对更新版本的答案更感兴趣。
原文由 MikeMB 发布,翻译遵循 CC BY-SA 4.0 许可协议
您的方法 - 正如@Tsyvarev 评论的那样 - 绝对没问题,因为您在 CMake 中要求使用“新”方法,您的代码将转换为:
你把
add_compile_options()
和 - 作为@Al.G.已评论 - “使用肮脏的 生成器表达式”。生成器表达式有一些缺点:
$<IF:...,...,...>
表达式仅在 CMake 版本 >= 3.8 中可用string(APPEND ...)
,您也可以使用它来“优化”您的set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ...
调用。所以最好使用
add_compile_options()
的更具可读性和向后兼容的方法:是的,您不再明确指定 C++ 标准,您只需使用
target_compile_features()
调用命名您的代码/目标确实依赖的 C++ 功能。对于这个例子,我选择了
cxx_lambda_init_captures
例如,旧的 GCC 编译器会给出以下错误(例如,如果编译器不支持此功能会发生什么情况):您需要编写一个包装脚本来使用 “单一配置”makefile 生成器 构建多个配置,或者使用 “多配置”IDE 作为 Visual Studio。
以下是对示例的引用:
因此,我使用
Open Folder
Visual Studio 2017 CMake 支持测试了以下内容,以在此示例中结合 cl 、 clang 和 mingw 编译器:CMakeSettings.json
mingw32-make.cmd
因此,您可以使用 Visual Studio 2017 中的任何 CMake 生成器,有一些不健康的引用正在进行(至于 2017 年 9 月,可能稍后修复),需要
mingw32-make.cmd
中介(删除引号)。