c++ - 使用 cmake 和 msvc 构建 C++ - `/permissive-` 标志被删除
问题描述
我有一个非常大的项目,由于逻辑运算符关键字的替代拼写,我无法在 Windows 上编译。
我将我的问题分解为这个最小的示例:它包含以下两个文件:
main.cpp
#include <iostream>
int main() {
int a = 0;
int b = 1;
if (a == b or a-1 == 1) {
std::cout << "a and b are close\n";
}
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(example VERSION 1.0)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) # The behaviour is the same setting this flag to ON or OFF
set(CXXFLAGS "${CXXFLAGS} /permissive-")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /permissive-")
add_compile_options(/permissive-)
add_executable(example main.cpp)
target_compile_options(example PUBLIC /permissive-)
set_target_properties(example PROPERTIES C_ISO_COMPLIANT ON)
message(STATUS "CXX FLAGS ARE ${CMAKE_CXX_FLAGS}")
message(STATUS "CXX FLAGS ARE ${CMAKE_CXX_FLAGS_RELEASE}")
我在 Windows 系统上编译它们,如下所示:
C:\tmp>cmake -E env CXXFLAGS="/foo /permissive-" cmake -H. -Bbuild -G "Visual Studio 15 2017 Win64" -LA
-- The C compiler identification is MSVC 19.11.25547.0
-- The CXX compiler identification is MSVC 19.11.25547.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/cl.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CXX FLAGS ARE /foo /permissive- /DWIN32 /D_WINDOWS /W3 /GR /EHsc /permissive-
-- CXX FLAGS ARE /MD /O2 /Ob2 /DNDEBUG /permissive-
-- Configuring done
-- Generating done
-- Build files have been written to: C:/gtmp/build
-- Cache values
CMAKE_CONFIGURATION_TYPES:STRING=Debug;Release;MinSizeRel;RelWithDebInfo
CMAKE_CXX_FLAGS:STRING=/foo /permissive- /DWIN32 /D_WINDOWS /W3 /GR /EHsc
CMAKE_CXX_FLAGS_DEBUG:STRING=/MDd /Zi /Ob0 /Od /RTC1
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=/MD /O1 /Ob1 /DNDEBUG
CMAKE_CXX_FLAGS_RELEASE:STRING=/MD /O2 /Ob2 /DNDEBUG
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=/MD /Zi /O2 /Ob1 /DNDEBUG
CMAKE_CXX_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
CMAKE_C_FLAGS:STRING=/DWIN32 /D_WINDOWS /W3
CMAKE_C_FLAGS_DEBUG:STRING=/MDd /Zi /Ob0 /Od /RTC1
CMAKE_C_FLAGS_MINSIZEREL:STRING=/MD /O1 /Ob1 /DNDEBUG
CMAKE_C_FLAGS_RELEASE:STRING=/MD /O2 /Ob2 /DNDEBUG
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=/MD /Zi /O2 /Ob1 /DNDEBUG
CMAKE_C_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib
CMAKE_EXE_LINKER_FLAGS:STRING=/machine:x64
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL
CMAKE_INSTALL_PREFIX:PATH=C:/Program Files/example
CMAKE_LINKER:FILEPATH=C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x64/link.exe
CMAKE_MODULE_LINKER_FLAGS:STRING=/machine:x64
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL
CMAKE_MT:FILEPATH=C:/Program Files (x86)/Windows Kits/10/bin/10.0.16299.0/x64/mt.exe
CMAKE_RC_COMPILER:FILEPATH=C:/Program Files (x86)/Windows Kits/10/bin/10.0.16299.0/x64/rc.exe
CMAKE_RC_FLAGS:STRING=-DWIN32
CMAKE_RC_FLAGS_DEBUG:STRING=-D_DEBUG
CMAKE_RC_FLAGS_MINSIZEREL:STRING=
CMAKE_RC_FLAGS_RELEASE:STRING=
CMAKE_RC_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_SHARED_LINKER_FLAGS:STRING=/machine:x64
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
CMAKE_SKIP_RPATH:BOOL=NO
CMAKE_STATIC_LINKER_FLAGS:STRING=/machine:x64
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
C:\tmp>cmake --build build --config Release --verbose
Microsoft (R)-Buildmodul, Version 15.4.8.50001 für .NET Framework
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
Der Buildvorgang wurde am 26.08.2021 13:00:43 gestartet.
Projekt "C:\tmp\build\ALL_BUILD.vcxproj" auf Knoten "1" (Standardziele).
Das Projekt "C:\tmp\build\ALL_BUILD.vcxproj" (1) erstellt "C:\tmp\build\ZERO_CHECK.vcxproj" (2) auf Knoten "1" (Standardziele).
PrepareForBuild:
Das Verzeichnis "x64\Release\ZERO_CHECK\" wird erstellt.
Das Verzeichnis "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\" wird erstellt.
InitializeBuildStatus:
"x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild" wird erstellt, da "AlwaysCreate" angegeben wurde.
CustomBuild:
Checking Build System
FinalizeBuildStatus:
Die Datei "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild" wird gelöscht.
Aktualisieren des Timestamps von "x64\Release\ZERO_CHECK\ZERO_CHECK.tlog\ZERO_CHECK.lastbuildstate".
Die Erstellung von Projekt "C:\tmp\build\ZERO_CHECK.vcxproj" ist abgeschlossen (Standardziele).
Das Projekt "C:\tmp\build\ALL_BUILD.vcxproj" (1) erstellt "C:\tmp\build\example.vcxproj" (3) auf Knoten "1" (Standardziele).
PrepareForBuild:
Das Verzeichnis "example.dir\Release\" wird erstellt.
Das Verzeichnis "C:\tmp\build\Release\" wird erstellt.
Das Verzeichnis "example.dir\Release\example.tlog\" wird erstellt.
InitializeBuildStatus:
"example.dir\Release\example.tlog\unsuccessfulbuild" wird erstellt, da "AlwaysCreate" angegeben wurde.
CustomBuild:
Building Custom Rule C:/gtmp/CMakeLists.txt
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\bin\HostX86\x64\CL.exe /c /nologo /W3 /WX- /diagnostics:classic /O2 /Ob2 /D WIN32 /D _WINDOWS /D NDEBUG /D "CMAKE_INTDIR=\"Release\"" /D _MBCS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++14 /Fo"example.dir\Release\\" /Fd"example.dir\Release\vc141.pdb" /Gd /TP /errorReport:queue /foo C:\tmp\main.cpp
cl : Command line warning D9002: ignoring unknown option '/foo' [C:\tmp\build\example.vcxproj]
main.cpp
C:\tmp\main.cpp(7): error C2146: syntax error: missing ')' before identifier 'or' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(7): error C2065: 'or': undeclared identifier [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(7): error C2146: syntax error: missing ';' before identifier 'a' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(7): error C2059: syntax error: ')' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(8): error C2059: syntax error: ';' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(10): error C2059: syntax error: 'return' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(11): error C2059: syntax error: '}' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(11): error C2143: syntax error: missing ';' before '}' [C:\tmp\build\example.vcxproj]
Die Erstellung des Projekts "C:\tmp\build\example.vcxproj" ist abgeschlossen (Standardziele) -- FEHLER.
Die Erstellung des Projekts "C:\tmp\build\ALL_BUILD.vcxproj" ist abgeschlossen (Standardziele) -- FEHLER.
Fehler beim Buildvorgang.
"C:\tmp\build\ALL_BUILD.vcxproj" (Standardziel) (1) ->
"C:\tmp\build\example.vcxproj" (Standardziel) (3) ->
(ClCompile Ziel) ->
cl : Command line warning D9002: ignoring unknown option '/foo' [C:\tmp\build\example.vcxproj]
"C:\tmp\build\ALL_BUILD.vcxproj" (Standardziel) (1) ->
"C:\tmp\build\example.vcxproj" (Standardziel) (3) ->
(ClCompile Ziel) ->
C:\tmp\main.cpp(7): error C2146: syntax error: missing ')' before identifier 'or' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(7): error C2065: 'or': undeclared identifier [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(7): error C2146: syntax error: missing ';' before identifier 'a' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(7): error C2059: syntax error: ')' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(8): error C2059: syntax error: ';' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(10): error C2059: syntax error: 'return' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(11): error C2059: syntax error: '}' [C:\tmp\build\example.vcxproj]
C:\tmp\main.cpp(11): error C2143: syntax error: missing ';' before '}' [C:\tmp\build\example.vcxproj]
1 Warnung(en)
8 Fehler
Verstrichene Zeit 00:00:00.89
C:\tmp>:
它失败并抱怨or
in的错误main.cpp
。要接受此行为,需要使用/permissive-
标志 ( ref ) 调用编译器。看到我通过它几乎发疯了。请注意,该\foo
标志确实已通过环境变量传递给编译器,但是该\permissive-
标志已被删除。
健全性检查:如果我使用生成的编译命令并/permissive-
手动添加标志,它编译得很好:
"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\bin\HostX86\x64\CL.exe" /c /nologo /W3 /WX- /diagnostics:classic /O2 /Ob2 /D WIN32 /D _WINDOWS /D NDEBUG /D "CMAKE_INTDIR=\"Release\"" /D _MBCS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++14 /Fo"example.dir\Release\\" /Fd"example.dir\Release\vc141.pdb" /Gd /TP /errorReport:queue /permissive- /foo C:\tmp\main.cpp
C:\tmp\build>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\bin\HostX86\x64\CL.exe" /c /nologo /W3 /WX- /diagnostics:classic /O2 /Ob2 /D WIN32 /D _WINDOWS /D NDEBUG /D "CMAKE_INTDIR=\"Release\"" /D _MBCS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++14 /Fo"example.dir\Release\\" /Fd"example.dir\Release\vc141.pdb" /Gd /TP /errorReport:queue /permissive- /foo C:\Jenkins\workspace\SCIPOptSuite_windows_libs_release\tmp\main.cpp
cl : Command line warning D9002 : ignoring unknown option '/foo'
main.cpp
C:\tmp\build>
如何说服 CMake 不要将此标志放到编译命令中?
解决方案
事实证明,从 15.4 到 15.9 的更新起到了作用,显然该选项是在 15.5 版中引入的:https ://docs.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view= msvc-140
C:\tmp>cmake -H. -Bbuild -G "Visual Studio 15 2017 Win64"
-- The C compiler identification is MSVC 19.16.27045.0
-- The CXX compiler identification is MSVC 19.16.27045.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.ex
e
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.ex
e - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.
exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.
exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- CXX FLAGS ARE /DWIN32 /D_WINDOWS /W3 /GR /EHsc /permissive-
-- CXX FLAGS ARE /MD /O2 /Ob2 /DNDEBUG /permissive-
-- Configuring done
-- Generating done
-- Build files have been written to: C:/tmp/build
C:\tmp>cmake --build build --config Release
Microsoft (R)-Build-Engine, Version 15.9.21+g9802d43bc3 für .NET Framework
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
Checking Build System
Building Custom Rule C:/tmp/CMakeLists.txt
main.cpp
example.vcxproj -> C:\tmp\build\Release\example.exe
Building Custom Rule C:/tmp/CMakeLists.txt
C:\tmp>
推荐阅读
- vhdl - 变量是否也需要 VHDL 默认信号分配?
- c - 如何在C中自动缩放浮点值?
- python - pexpect的python输出
- html - 两个边缘不同倾斜的 Div
- siri - 在哪里可以找到有关 Siri 快捷方式中操作的更多具体信息?
- vba - 为什么 VBA 的 Recordset 只返回一条记录?
- java - 使用 System.in 中的缓冲读取器 readline() 时字符的最大大小是多少
- kubernetes - minikube 上的 istio-pilot 始终处于挂起状态
- android - 如何理解像 Whatsapp for EditText 这样的停止和开始输入?
- kotlin - 如何更新可嵌入的 kotlin 编译器?