使用CMake+MSVC构建C++项目时/permissive-标志被丢弃如何解决
你遇到的/permissive-标志被丢弃是Visual Studio生成器的特性导致的:MSVC默认开启/permissive(宽松模式),该参数的优先级高于你在CMAKE_CXX_FLAGS开头添加的/permissive-,后面出现的/permissive会直接覆盖前面的/permissive-,导致你的设置失效。另外你之前配置的C_ISO_COMPLIANT是C语言的合规属性,对C++项目无效,不会产生作用。
方案1:升级CMake到3.20及以上(推荐)
CMake 3.20新增了CXX_PERMISSIVE目标属性,专门控制MSVC的符合模式开关,不会被默认参数覆盖。先删掉你之前所有重复添加/permissive-的冗余代码(包括全局set、add_compile_options、target_compile_options里的重复设置,避免冲突),仅需要在添加可执行文件后加一行配置即可:
set_target_properties(example PROPERTIES CXX_PERMISSIVE OFF)
设置后CMake会自动把/permissive-放到编译参数的最后,不会被默认参数冲掉。
方案2:兼容CMake 3.10及更低版本
如果你无法升级CMake,需要显式将/permissive-追加到编译参数的末尾,保证优先级高于默认的/permissive,删掉冗余配置后,在CMakeLists.txt末尾添加一行即可:
target_compile_options(example PRIVATE $<$<CXX_COMPILER_ID:MSVC>:/permissive->)
这行配置会把/permissive-直接绑定到目标的编译参数末尾,不会被全局默认参数覆盖。
方案3:不改编译配置的兼容方案
如果你不想调整构建配置,也可以直接在代码中添加头文件引用来兼容MSVC的默认行为,在所有用到逻辑运算符替代关键字的cpp文件最开头添加:
#include <ciso646>
该头文件会把or/and/not等逻辑运算符替代关键字定义为宏,不需要开/permissive-也能正常编译。
构建时加--verbose参数看实际执行的cl.exe命令行,确认/permissive-出现在参数列表的后半段,且后面没有出现/permissive即可。
内容的提问来源于stack exchange,提问作者fariwesen

