你的办法将 - 如@Tsyvarev曾评论 - 绝对很好,只是因为你已经要求在C进行“新”办法这里是你的代码会翻译什么:
cmake_minimum_required(VERSION 3.8)
project(HelloWorld)
string(
APPEND _opts
"$<IF:$<CXX_COMPILER_ID:MSVC>,"
"/W4;$<$<CONFIG:RELEASE>:/O2>,"
"-Wall;-Wextra;-Werror;"
"$<$<CONFIG:RELEASE>:-O3>"
"$<$<CXX_COMPILER_ID:Clang>:-stdlib=libc++>"
">"
)
add_compile_options("${_opts}")
add_executable(HelloWorld "main.cpp")
target_compile_features(HelloWorld PUBLIC cxx_lambda_init_captures)
你拿add_compile_options()
和 - as @ Al.G。已评论 - “使用脏generator expressions”。
有发电机表达式的一些缺点:
- 很有帮助
$<IF:...,...,...>
表达只是CMake的版本> = 3.8
- 你必须把它写在一行可用。为了避免它,我使用了
string(APPEND ...)
,您也可以使用它来“优化”您的set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ...
调用。
- 这很难阅读和理解。例如。需要分号才能使其成为编译选项列表(否则CMake会引用它)。
所以最好使用一个更具可读性和向后兼容的方式与add_compile_options()
:
if(MSVC)
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")
else()
add_compile_options("-Wall" "-Wextra" "-Werror" "$<$<CONFIG:RELEASE>:-O3>")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options("-stdlib=libc++")
else()
# nothing special for gcc at the moment
endif()
endif()
是的,你没有明确指定C++标准了,你刚才命名C++ feature代码/目标确实取决于target_compile_features()
调用。
在这个例子中,我选择了cxx_lambda_init_captures
,旧的GCC编译器提供以下错误(作为一个例子会发生什么,如果编译器不支持此功能):
The compiler feature "cxx_lambda_init_captures" is not known to CXX compiler
"GNU"
version 4.8.4.
而且你需要写一个包装脚本构建与"single configuration" makefile generator或多个配置作为Visual Studio使用"multi configuration" IDE。
下面是引用的例子:
所以,我测试了Open Folder
Visual Studio中的下列2017年CMake的支持,在结合此示例为cl,clang和mingw编译器:
CMakeSettings.json
{
// See https://go.microsoft.com//fwlink//?linkid=834763 for more information about this file.
"configurations": [
{
"name": "x86-Debug",
"generator": "Visual Studio 15 2017",
"configurationType": "Debug",
"buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"buildCommandArgs": "-m -v:minimal",
},
{
"name": "x86-Release",
"generator": "Visual Studio 15 2017",
"configurationType": "Release",
"buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"buildCommandArgs": "-m -v:minimal",
},
{
"name": "Clang-Debug",
"generator": "Visual Studio 15 2017",
"configurationType": "Debug",
"buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "-T\"LLVM-vs2014\"",
"buildCommandArgs": "-m -v:minimal",
},
{
"name": "Clang-Release",
"generator": "Visual Studio 15 2017",
"configurationType": "Release",
"buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"cmakeCommandArgs": "-T\"LLVM-vs2014\"",
"buildCommandArgs": "-m -v:minimal",
},
{
"name": "GNU-Debug",
"generator": "MinGW Makefiles",
"configurationType": "Debug",
"buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"variables": [
{
"name": "CMAKE_MAKE_PROGRAM",
"value": "${projectDir}\\mingw32-make.cmd"
}
]
},
{
"name": "GNU-Release",
"generator": "Unix Makefiles",
"configurationType": "Release",
"buildRoot": "${env.LOCALAPPDATA}\\CMakeBuild\\${workspaceHash}\\build\\${name}",
"variables": [
{
"name": "CMAKE_MAKE_PROGRAM",
"value": "${projectDir}\\mingw32-make.cmd"
}
]
}
]
}
的mingw32-make.cmd
@echo off
mingw32-make.exe %~1 %~2 %~3 %~4
所以,你可以使用任何CMake的发电机从Visual Studio 2017年中,还有一些不健康的报价正在进行(截至2017年9月,mayb e稍后修复),即需要mingw32-make.cmd
中介(删除引号)。
关于前两点:https://cmake.org/cmake/help/v3.3/command/add_compile_options.html –
@ AI.G。谢谢。是否还有单独的调试和释放集,我必须通过另一级别的if_else解决?我用生成器表达式进行了一些尝试,但我感觉这变得更不可读。 – MikeMB
当我看到它,你既可以用脏发电机表达式或'设置(CMAKE_CXX_FLAGS_DEBUG“$ {} CMAKE_CXX_FLAGS_DEBUG --flags”)'相当详细的语法。在这种情况下(考虑到这些不满意),你可以尝试编写一些帮助函数,将脏代码包装成更令人愉快的东西。 –