mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
MSVC,Clang: Set CMAKE_CXX_COMPILER_PREDEFINES_COMMAND for the MSVC ABI
The variable was only set by the GNU-like compiler modules, so AUTOMOC never generated a moc_predefs.h for compilers targeting the MSVC ABI and moc parsed headers without the compiler's predefined macros. MSVC dumps its predefined macros with '/PD', which needs the conforming preprocessor. Require VS 2019 16.8, because 16.7 and older ignore the flag with warning D9002 and emit no macros at all. clang-cl takes '-dM' through '-Xclang'. Both also echo the preprocessed source, so feed them an empty translation unit. clang with the GNU driver is excluded from 'Compiler/GNU' as well when it simulates MSVC, so give it the usual '-dM -E' command there. Fixes: #28093
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
// An empty translation unit for CMAKE_<LANG>_COMPILER_PREDEFINES_COMMAND.
|
||||
// MSVC-like compilers echo the preprocessed source along with the macro
|
||||
// definitions, so the input must contribute no output of its own.
|
||||
@@ -20,6 +20,31 @@ if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl")
|
||||
endif()
|
||||
|
||||
# 'Compiler/GNU' is not included when clang simulates MSVC, so the predefines
|
||||
# command is not set up there.
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER_PREDEFINES_COMMAND)
|
||||
set(CMAKE_CXX_COMPILER_PREDEFINES_COMMAND "${CMAKE_CXX_COMPILER}")
|
||||
if(CMAKE_CXX_COMPILER_ARG1)
|
||||
separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_CXX_COMPILER_ARG1}")
|
||||
list(APPEND CMAKE_CXX_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
|
||||
unset(_COMPILER_ARGS)
|
||||
endif()
|
||||
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
|
||||
# '-dM' is a cc1 option in this driver mode, and '-EP' also echoes the
|
||||
# preprocessed source, hence the empty translation unit.
|
||||
list(APPEND CMAKE_CXX_COMPILER_PREDEFINES_COMMAND
|
||||
"-nologo" "-w" "-Xclang" "-dM" "-EP"
|
||||
"${CMAKE_ROOT}/Modules/CMakeCXXCompilerPredefines.cpp")
|
||||
else()
|
||||
list(APPEND CMAKE_CXX_COMPILER_PREDEFINES_COMMAND
|
||||
"-w" "-dM" "-E" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER_TARGET)
|
||||
list(APPEND CMAKE_CXX_COMPILER_PREDEFINES_COMMAND
|
||||
"--target=${CMAKE_CXX_COMPILER_TARGET}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0 AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU") OR
|
||||
(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.1 AND CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC"))
|
||||
if (CMAKE_CXX_COMPILER_CLANG_RESOURCE_DIR)
|
||||
|
||||
@@ -23,5 +23,22 @@ macro(__compiler_msvc lang)
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang}_WARNING "-external:W0 ")
|
||||
endif ()
|
||||
|
||||
# '/PD' dumps the predefined macros, but it needs the conforming
|
||||
# preprocessor and one of '/E', '/EP' or '/P'. VS 2019 16.7 and older
|
||||
# ignore it with warning D9002, so require 16.8. '/EP' also echoes the
|
||||
# preprocessed source, hence the empty translation unit.
|
||||
if("${lang}" STREQUAL "CXX" AND
|
||||
CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28)
|
||||
set(CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "${CMAKE_${lang}_COMPILER}")
|
||||
if(CMAKE_${lang}_COMPILER_ARG1)
|
||||
separate_arguments(_COMPILER_ARGS NATIVE_COMMAND "${CMAKE_${lang}_COMPILER_ARG1}")
|
||||
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND ${_COMPILER_ARGS})
|
||||
unset(_COMPILER_ARGS)
|
||||
endif()
|
||||
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND
|
||||
"-nologo" "-w" "-Zc:preprocessor" "-PD" "-EP"
|
||||
"${CMAKE_ROOT}/Modules/CMakeCXXCompilerPredefines.cpp")
|
||||
endif()
|
||||
|
||||
set(CMAKE_${lang}_LINK_MODE LINKER)
|
||||
endmacro()
|
||||
|
||||
@@ -11,6 +11,14 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
add_library(MocPredefs MocPredefs.cxx)
|
||||
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER_PREDEFINES_COMMAND)
|
||||
# Do not silently skip on toolchains that are expected to provide it.
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER_EQUAL 1928)
|
||||
OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"
|
||||
AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
|
||||
message(FATAL_ERROR
|
||||
"CMAKE_CXX_COMPILER_PREDEFINES_COMMAND is not defined for "
|
||||
"${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}.")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user