繁体   English   中英

使用 cmake 和 msvc 构建 C++ - `/permissive-` 标志被删除

[英]building C++ with cmake and msvc - `/permissive-` flag gets dropped

我有一个非常大的项目,由于逻辑运算符关键字的替代拼写,我无法在 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>:

它因抱怨main.cppor错误而失败。 要接受此行为,需要使用/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>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM