From 1baf122cd41d6500139649661052236b8e684565 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 19 Apr 2019 11:11:53 -0400 Subject: MSVC: Do not add /W3 to CMAKE__FLAGS by default We do not add default warning flags on other compilers, and having a warning flag in the default flags makes it hard for projects to customize the warning level. They need to use string processing to remove `/W3` from `CMAKE_{C,CXX}_FLAGS`. Therefore we should drop it. However, projects may be using string processing to replace `/W3` with another flag, so we cannot simply drop it. Add a policy to drop it in a compatible way. Fixes: #18317 --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0092.rst | 38 ++++++++++++++++++++++ Help/release/dev/msvc-warning-flags.rst | 6 ++++ Modules/Platform/Windows-Intel-Fortran.cmake | 9 ++++- Modules/Platform/Windows-MSVC.cmake | 17 ++++++++-- Modules/Platform/Windows-NVIDIA-CUDA.cmake | 11 ++++++- Source/cmPolicies.h | 5 ++- Tests/RunCMake/CMakeLists.txt | 1 + Tests/RunCMake/MSVCWarningFlags/CMP0092-NEW.cmake | 2 ++ Tests/RunCMake/MSVCWarningFlags/CMP0092-OLD.cmake | 2 ++ Tests/RunCMake/MSVCWarningFlags/CMP0092-WARN.cmake | 2 ++ .../RunCMake/MSVCWarningFlags/CMP0092-common.cmake | 12 +++++++ Tests/RunCMake/MSVCWarningFlags/CMakeLists.txt | 3 ++ Tests/RunCMake/MSVCWarningFlags/RunCMakeTest.cmake | 5 +++ 14 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 Help/policy/CMP0092.rst create mode 100644 Help/release/dev/msvc-warning-flags.rst create mode 100644 Tests/RunCMake/MSVCWarningFlags/CMP0092-NEW.cmake create mode 100644 Tests/RunCMake/MSVCWarningFlags/CMP0092-OLD.cmake create mode 100644 Tests/RunCMake/MSVCWarningFlags/CMP0092-WARN.cmake create mode 100644 Tests/RunCMake/MSVCWarningFlags/CMP0092-common.cmake create mode 100644 Tests/RunCMake/MSVCWarningFlags/CMakeLists.txt create mode 100644 Tests/RunCMake/MSVCWarningFlags/RunCMakeTest.cmake diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 043fb5c..8fcd386 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.15 .. toctree:: :maxdepth: 1 + CMP0092: MSVC warning flags are not in CMAKE_{C,CXX}_FLAGS by default. CMP0091: MSVC runtime library flags are selected by an abstraction. CMP0090: export(PACKAGE) does not populate package registry by default. CMP0089: Compiler id for IBM Clang-based XL compilers is now XLClang. diff --git a/Help/policy/CMP0092.rst b/Help/policy/CMP0092.rst new file mode 100644 index 0000000..8d3a288 --- /dev/null +++ b/Help/policy/CMP0092.rst @@ -0,0 +1,38 @@ +CMP0092 +------- + +MSVC warning flags are not in :variable:`CMAKE__FLAGS` by default. + +When using MSVC-like compilers in CMake 3.14 and below, warning flags +like ``/W3`` are added to :variable:`CMAKE__FLAGS` by default. +This is problematic for projects that want to choose a different warning +level programmatically. In particular, it requires string editing of the +:variable:`CMAKE__FLAGS` variables with knowledge of the +CMake builtin defaults so they can be replaced. + +CMake 3.15 and above prefer to leave out warning flags from the value of +:variable:`CMAKE__FLAGS` by default. + +This policy provides compatibility with projects that have not been updated +to expect the lack of warning flags. The policy setting takes effect as of +the first :command:`project` or :command:`enable_language` command that +initializes :variable:`CMAKE__FLAGS` for a given lanuage ````. + +.. note:: + + Once the policy has taken effect at the top of a project for a given + language, that choice must be used throughout the tree for that language. + In projects that have nested projects in subdirectories, be sure to + convert everything together. + +The ``OLD`` behavior for this policy is to place MSVC warning flags in the +default :variable:`CMAKE__FLAGS` cache entries. The ``NEW`` behavior +for this policy is to *not* place MSVC warning flags in the default cache +entries. + +This policy was introduced in CMake version 3.15. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike many policies, CMake version |release| does *not* warn +when this policy is not set and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/msvc-warning-flags.rst b/Help/release/dev/msvc-warning-flags.rst new file mode 100644 index 0000000..b89d6fa --- /dev/null +++ b/Help/release/dev/msvc-warning-flags.rst @@ -0,0 +1,6 @@ +msvc-warning-flags +------------------ + +* With MSVC-like compilers the value of :variable:`CMAKE__FLAGS` + no longer contains warning flags like ``/W3`` by default. + See policy :policy:`CMP0092`. diff --git a/Modules/Platform/Windows-Intel-Fortran.cmake b/Modules/Platform/Windows-Intel-Fortran.cmake index f00a8e4..e3804fb 100644 --- a/Modules/Platform/Windows-Intel-Fortran.cmake +++ b/Modules/Platform/Windows-Intel-Fortran.cmake @@ -13,7 +13,14 @@ else() set(_DBGLIBS " /dbglibs") set(_THREADS " /threads") endif() -string(APPEND CMAKE_Fortran_FLAGS_INIT " /W1 /nologo /fpp${_LIBSDLL}${_THREADS}") + +cmake_policy(GET CMP0092 _cmp0092) +if(NOT _cmp0092 STREQUAL "NEW") + string(APPEND CMAKE_Fortran_FLAGS_INIT " /W1") +endif() +unset(_cmp0092) + +string(APPEND CMAKE_Fortran_FLAGS_INIT " /nologo /fpp${_LIBSDLL}${_THREADS}") string(APPEND CMAKE_Fortran_FLAGS_DEBUG_INIT " /Od /debug:full${_DBGLIBS}") string(APPEND CMAKE_Fortran_FLAGS_MINSIZEREL_INIT " /O1 /DNDEBUG") string(APPEND CMAKE_Fortran_FLAGS_RELEASE_INIT " /O2 /DNDEBUG") diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 4279a74..ed0e7fb 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -366,21 +366,34 @@ macro(__windows_compiler_msvc lang) set(_MDd " /MDd") set(_MD " /MD") endif() + + cmake_policy(GET CMP0092 _cmp0092) + if(_cmp0092 STREQUAL "NEW") + set(_W3 "") + set(_Wall "") + else() + set(_W3 " /W3") + set(_Wall " -Wall") + endif() + unset(_cmp0092) + if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*") # note: MSVC 14 2015 Update 1 sets -fno-ms-compatibility by default, but this does not allow one to compile many projects # that include MS's own headers. CMake itself is affected project too. - string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} -fms-extensions -fms-compatibility -D_WINDOWS -Wall${_FLAGS_${lang}}") + string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} -fms-extensions -fms-compatibility -D_WINDOWS${_Wall}${_FLAGS_${lang}}") string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} -gline-tables-only -fno-inline -O0 ${_RTC1}") string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT "${_MD} -O2 -DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD} -gline-tables-only -O2 -fno-inline -DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} -DNDEBUG") # TODO: Add '-Os' once VS generator maps it properly for Clang else() - string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3${_FLAGS_${lang}}") + string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS${_W3}${_FLAGS_${lang}}") string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT "${_MDd} /Zi /Ob0 /Od ${_RTC1}") string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT "${_MD} /O2 /Ob2 /DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "${_MD} /Zi /O2 /Ob1 /DNDEBUG") string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT "${_MD} /O1 /Ob1 /DNDEBUG") endif() + unset(_Wall) + unset(_W3) unset(_MDd) unset(_MD) diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake index 6a2667a..f160c7b 100644 --- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake +++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake @@ -60,11 +60,20 @@ unset(__IMPLICT_DLINK_FLAGS) string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}") -string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"/W3${_FLAGS_CXX}\"") +cmake_policy(GET CMP0092 _cmp0092) +if(_cmp0092 STREQUAL "NEW") + set(_W3 "") +else() + set(_W3 "/W3") +endif() +unset(_cmp0092) + +string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"") string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"-MDd -Zi -Ob0 -Od ${_RTC1}\"") string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"-MD -O2 -Ob2\" -DNDEBUG") string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -Xcompiler=\"-MD -Zi -O2 -Ob1\" -DNDEBUG") string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -Xcompiler=\"-MD -O1 -Ob1\" -DNDEBUG") +unset(_W3) set(CMAKE_CUDA_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 113dd35..0e42295 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -270,7 +270,10 @@ class cmMakefile; 15, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0091, \ "MSVC runtime library flags are selected by an abstraction.", 3, 15, \ - 0, cmPolicies::WARN) + 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0092, \ + "MSVC warning flags are not in CMAKE__FLAGS by default.", 3, \ + 15, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index a8dcb4b..4973e55 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -197,6 +197,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "^(Cray|PGI|XL|XLClang)$") endif() if(MSVC) add_RunCMake_test(MSVCRuntimeLibrary) + add_RunCMake_test(MSVCWarningFlags) endif() add_RunCMake_test(ObjectLibrary) add_RunCMake_test(ParseImplicitIncludeInfo) diff --git a/Tests/RunCMake/MSVCWarningFlags/CMP0092-NEW.cmake b/Tests/RunCMake/MSVCWarningFlags/CMP0092-NEW.cmake new file mode 100644 index 0000000..15c52d2 --- /dev/null +++ b/Tests/RunCMake/MSVCWarningFlags/CMP0092-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0092 NEW) +include(CMP0092-common.cmake) diff --git a/Tests/RunCMake/MSVCWarningFlags/CMP0092-OLD.cmake b/Tests/RunCMake/MSVCWarningFlags/CMP0092-OLD.cmake new file mode 100644 index 0000000..ea75445 --- /dev/null +++ b/Tests/RunCMake/MSVCWarningFlags/CMP0092-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0092 OLD) +include(CMP0092-common.cmake) diff --git a/Tests/RunCMake/MSVCWarningFlags/CMP0092-WARN.cmake b/Tests/RunCMake/MSVCWarningFlags/CMP0092-WARN.cmake new file mode 100644 index 0000000..45e183f --- /dev/null +++ b/Tests/RunCMake/MSVCWarningFlags/CMP0092-WARN.cmake @@ -0,0 +1,2 @@ + +include(CMP0092-common.cmake) diff --git a/Tests/RunCMake/MSVCWarningFlags/CMP0092-common.cmake b/Tests/RunCMake/MSVCWarningFlags/CMP0092-common.cmake new file mode 100644 index 0000000..87d7f67 --- /dev/null +++ b/Tests/RunCMake/MSVCWarningFlags/CMP0092-common.cmake @@ -0,0 +1,12 @@ +enable_language(C) + +cmake_policy(GET CMP0092 cmp0092) +if(cmp0092 STREQUAL "NEW") + if("${CMAKE_C_FLAGS}" MATCHES "([/-]W[0-9])") + message(SEND_ERROR "CMAKE_C_FLAGS has '${CMAKE_MATCH_1}' under NEW behavior") + endif() +else() + if(NOT " ${CMAKE_C_FLAGS} " MATCHES " /W3 ") + message(SEND_ERROR "CMAKE_C_FLAGS does not have '/W3' under OLD behavior") + endif() +endif() diff --git a/Tests/RunCMake/MSVCWarningFlags/CMakeLists.txt b/Tests/RunCMake/MSVCWarningFlags/CMakeLists.txt new file mode 100644 index 0000000..3e470a2 --- /dev/null +++ b/Tests/RunCMake/MSVCWarningFlags/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.14) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/MSVCWarningFlags/RunCMakeTest.cmake b/Tests/RunCMake/MSVCWarningFlags/RunCMakeTest.cmake new file mode 100644 index 0000000..7ce448d --- /dev/null +++ b/Tests/RunCMake/MSVCWarningFlags/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0092-WARN) +run_cmake(CMP0092-OLD) +run_cmake(CMP0092-NEW) -- cgit v0.12