From be10826bf130d7568011ec3cf97355686c298dd3 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 4 Oct 2013 10:07:08 -0400 Subject: CMakeDetermineCompilerId: Fix local var init Add initialization of the ARCHITECTURE_ID local and fix the initialization of the COMPILER_ID_TWICE local. --- Modules/CMakeDetermineCompilerId.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 8ca5334..c14372f 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -308,9 +308,10 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(COMPILER_ID) set(COMPILER_VERSION) set(PLATFORM_ID) + set(ARCHITECTURE_ID) file(STRINGS ${file} CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 4 REGEX "INFO:") - set(HAVE_COMPILER_TWICE 0) + set(COMPILER_ID_TWICE) foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS}) if("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*") if(COMPILER_ID) -- cgit v0.12 From 51ab85c398319c074200ca51f37baa0e4c47ed7c Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 4 Oct 2013 10:10:22 -0400 Subject: CMakeDetermineCompilerId: Add notion of "simulated" id/version Some compilers try to simulate other compilers as a drop-in replacement supporting all the same command-line options and predefined preprocessor macros. In such cases it will be useful to have CMake load the compiler information files for the simulated compiler instead of duplicating the information. Teach CMakeDetermineCompilerId to extract the simulated compiler id and version when the compiler id detection provides it. --- Modules/CMakeCCompiler.cmake.in | 2 ++ Modules/CMakeCCompilerId.c.in | 9 +++++++++ Modules/CMakeCXXCompiler.cmake.in | 2 ++ Modules/CMakeCXXCompilerId.cpp.in | 9 +++++++++ Modules/CMakeDetermineCompilerId.cmake | 18 +++++++++++++++++- Modules/CMakePlatformId.h.in | 18 ++++++++++++++++++ Source/cmDocumentVariables.cxx | 22 ++++++++++++++++++++++ 7 files changed, 79 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index c41adc9..3e8d4ff 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -3,6 +3,8 @@ set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@") set(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@") set(CMAKE_C_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@") set(CMAKE_C_PLATFORM_ID "@CMAKE_C_PLATFORM_ID@") +set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@") +set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@") @SET_MSVC_C_ARCHITECTURE_ID@ set(CMAKE_AR "@CMAKE_AR@") set(CMAKE_RANLIB "@CMAKE_RANLIB@") diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 66a5582..48b46fa 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -206,6 +206,9 @@ because some compilers will just produce instructions to fill the array rather than assigning a pointer to a static array. */ char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@ @@ -223,6 +226,12 @@ int main(int argc, char* argv[]) #ifdef COMPILER_VERSION_MAJOR require += info_version[argc]; #endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif (void)argv; return require; } diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 9287b81..777f007 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -3,6 +3,8 @@ set(CMAKE_CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@") set(CMAKE_CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@") set(CMAKE_CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@") set(CMAKE_CXX_PLATFORM_ID "@CMAKE_CXX_PLATFORM_ID@") +set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@") +set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@") @SET_MSVC_CXX_ARCHITECTURE_ID@ set(CMAKE_AR "@CMAKE_AR@") set(CMAKE_RANLIB "@CMAKE_RANLIB@") diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 5e87715..f4a4176 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -199,6 +199,9 @@ because some compilers will just produce instructions to fill the array rather than assigning a pointer to a static array. */ char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; +#ifdef SIMULATE_ID +char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]"; +#endif @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@ @@ -212,6 +215,12 @@ int main(int argc, char* argv[]) #ifdef COMPILER_VERSION_MAJOR require += info_version[argc]; #endif +#ifdef SIMULATE_ID + require += info_simulate[argc]; +#endif +#ifdef SIMULATE_VERSION_MAJOR + require += info_simulate_version[argc]; +#endif (void)argv; return require; } diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index c14372f..cf2a7bd 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -80,6 +80,8 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}" PARENT_SCOPE) set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE) + set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE) + set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE) endfunction() #----------------------------------------------------------------------------- @@ -309,8 +311,10 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(COMPILER_VERSION) set(PLATFORM_ID) set(ARCHITECTURE_ID) + set(SIMULATE_ID) + set(SIMULATE_VERSION) file(STRINGS ${file} - CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 4 REGEX "INFO:") + CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 6 REGEX "INFO:") set(COMPILER_ID_TWICE) foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS}) if("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*") @@ -333,6 +337,14 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${COMPILER_VERSION}") string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}") endif() + if("${info}" MATCHES ".*INFO:simulate\\[([^]\"]*)\\].*") + set(SIMULATE_ID "${CMAKE_MATCH_1}") + endif() + if("${info}" MATCHES ".*INFO:simulate_version\\[([^]\"]*)\\].*") + set(SIMULATE_VERSION "${CMAKE_MATCH_1}") + string(REGEX REPLACE "^0+([0-9])" "\\1" SIMULATE_VERSION "${SIMULATE_VERSION}") + string(REGEX REPLACE "\\.0+([0-9])" ".\\1" SIMULATE_VERSION "${SIMULATE_VERSION}") + endif() endforeach() # Detect the exact architecture from the PE header. @@ -370,6 +382,8 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}") set(MSVC_${lang}_ARCHITECTURE_ID "${ARCHITECTURE_ID}") set(CMAKE_${lang}_COMPILER_VERSION "${COMPILER_VERSION}") + set(CMAKE_${lang}_SIMULATE_ID "${SIMULATE_ID}") + set(CMAKE_${lang}_SIMULATE_VERSION "${SIMULATE_VERSION}") endif() # Check the compiler identification string. @@ -418,6 +432,8 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}" PARENT_SCOPE) set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE) + set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE) + set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE) set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE) endfunction() diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index 69171c2..1e41fec 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -151,6 +151,24 @@ char const info_version[] = { ']','\0'}; #endif +/* Construct a string literal encoding the version number components. */ +#ifdef SIMULATE_VERSION_MAJOR +char const info_simulate_version[] = { + 'I', 'N', 'F', 'O', ':', + 's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[', + SIMULATE_VERSION_MAJOR, +# ifdef SIMULATE_VERSION_MINOR + '.', SIMULATE_VERSION_MINOR, +# ifdef SIMULATE_VERSION_PATCH + '.', SIMULATE_VERSION_PATCH, +# ifdef SIMULATE_VERSION_TWEAK + '.', SIMULATE_VERSION_TWEAK, +# endif +# endif +# endif + ']','\0'}; +#endif + /* Construct the string literal in pieces to prevent the source from getting matched. Store it in a pointer rather than an array because some compilers will just produce instructions to fill the diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index c4f6216..2fafef5 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1659,6 +1659,28 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables for Languages"); cm->DefineProperty + ("CMAKE__SIMULATE_ID", cmProperty::VARIABLE, + "Identification string of \"simulated\" compiler.", + "Some compilers simulate other compilers to serve as drop-in " + "replacements. " + "When CMake detects such a compiler it sets this variable to what " + "would have been the CMAKE__COMPILER_ID for the simulated " + "compiler.", + false, + "Variables for Languages"); + + cm->DefineProperty + ("CMAKE__SIMULATE_VERSION", cmProperty::VARIABLE, + "Version string of \"simulated\" compiler.", + "Some compilers simulate other compilers to serve as drop-in " + "replacements. " + "When CMake detects such a compiler it sets this variable to what " + "would have been the CMAKE__COMPILER_VERSION for the simulated " + "compiler.", + false, + "Variables for Languages"); + + cm->DefineProperty ("CMAKE__SIZEOF_DATA_PTR", cmProperty::VARIABLE, "Size of pointer-to-data types for language .", "This holds the size (in bytes) of pointer-to-data types in the target " -- cgit v0.12 From 3d8356d486ae736d1ba151aedfeb928222e7a084 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 4 Oct 2013 10:13:08 -0400 Subject: Clang: Support Windows variants for GNU and MSVC (#13035, #14458) Teach the compiler identification preprocessor tests to report when Clang simulates MSVC, and what version. If not MSVC, assume GNU. Teach compiler information modules Clang-(C|CXX) to recognize when Clang simulates MSVC and skip loading the GNU information. Teach the Windows-MSVC platform information to recognize when it is loaded as the simulated compiler and use that version information instead of the real compiler's (different) version scheme. Add platform modules Windows-Clang-(C|CXX) and support module Windows-Clang to load either Windows-MSVC or Windows-GNU and wrap the corresponding information macros. --- Modules/CMakeCCompilerId.c.in | 6 ++++++ Modules/CMakeCXXCompilerId.cpp.in | 6 ++++++ Modules/CMakeFindBinUtils.cmake | 6 ++++-- Modules/Compiler/Clang-CXX.cmake | 4 +++- Modules/Compiler/Clang.cmake | 20 +++++++++++++------- Modules/Platform/Windows-Clang-C.cmake | 2 ++ Modules/Platform/Windows-Clang-CXX.cmake | 2 ++ Modules/Platform/Windows-Clang.cmake | 32 ++++++++++++++++++++++++++++++++ Modules/Platform/Windows-MSVC.cmake | 8 ++++++-- 9 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 Modules/Platform/Windows-Clang-C.cmake create mode 100644 Modules/Platform/Windows-Clang-CXX.cmake create mode 100644 Modules/Platform/Windows-Clang.cmake diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 48b46fa..dda7bf6 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -33,6 +33,12 @@ # define COMPILER_VERSION_MAJOR DEC(__clang_major__) # define COMPILER_VERSION_MINOR DEC(__clang_minor__) # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif #elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) # define COMPILER_ID "Embarcadero" diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index f4a4176..915ae7f 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -38,6 +38,12 @@ # define COMPILER_VERSION_MAJOR DEC(__clang_major__) # define COMPILER_VERSION_MINOR DEC(__clang_minor__) # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) +# if defined(_MSC_VER) +# define SIMULATE_ID "MSVC" + /* _MSC_VER = VVRR */ +# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100) +# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100) +# endif #elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__) # define COMPILER_ID "Embarcadero" diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index e70c013..b4e2ae5 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -30,8 +30,10 @@ # License text for the above reference.) # if it's the MS C/CXX compiler, search for link -if("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC" - OR "${CMAKE_C_COMPILER_ID}" MATCHES "MSVC" +if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC" + OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC" + OR "${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" + OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_GENERATOR}" MATCHES "Visual Studio") find_program(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake index 972d889..0372e18 100644 --- a/Modules/Compiler/Clang-CXX.cmake +++ b/Modules/Compiler/Clang-CXX.cmake @@ -1,4 +1,6 @@ include(Compiler/Clang) __compiler_clang(CXX) -set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") +if(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") + set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") +endif() diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index ec4562a..7d7be5c 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -18,11 +18,17 @@ if(__COMPILER_CLANG) endif() set(__COMPILER_CLANG 1) -include(Compiler/GNU) +if(CMAKE_C_SIMULATE_ID STREQUAL "MSVC" + OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") + macro(__compiler_clang lang) + endmacro() +else() + include(Compiler/GNU) -macro(__compiler_clang lang) - __compiler_gnu(${lang}) - set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") - set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") - set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") -endmacro() + macro(__compiler_clang lang) + __compiler_gnu(${lang}) + set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE") + set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") + set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=") + endmacro() +endif() diff --git a/Modules/Platform/Windows-Clang-C.cmake b/Modules/Platform/Windows-Clang-C.cmake new file mode 100644 index 0000000..d007105 --- /dev/null +++ b/Modules/Platform/Windows-Clang-C.cmake @@ -0,0 +1,2 @@ +include(Platform/Windows-Clang) +__windows_compiler_clang(C) diff --git a/Modules/Platform/Windows-Clang-CXX.cmake b/Modules/Platform/Windows-Clang-CXX.cmake new file mode 100644 index 0000000..2c3688a --- /dev/null +++ b/Modules/Platform/Windows-Clang-CXX.cmake @@ -0,0 +1,2 @@ +include(Platform/Windows-Clang) +__windows_compiler_clang(CXX) diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake new file mode 100644 index 0000000..4c936fe --- /dev/null +++ b/Modules/Platform/Windows-Clang.cmake @@ -0,0 +1,32 @@ + +#============================================================================= +# Copyright 2001-2013 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# This module is shared by multiple languages; use include blocker. +if(__WINDOWS_CLANG) + return() +endif() +set(__WINDOWS_CLANG 1) + +if(CMAKE_C_SIMULATE_ID STREQUAL "MSVC" + OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") + include(Platform/Windows-MSVC) + macro(__windows_compiler_clang lang) + __windows_compiler_msvc(${lang}) + endmacro() +else() + include(Platform/Windows-GNU) + macro(__windows_compiler_clang lang) + __windows_compiler_gnu(${lang}) + endmacro() +endif() diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 7036ba0..a2cfe33 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -65,7 +65,11 @@ else() endif() if(NOT MSVC_VERSION) - if(CMAKE_C_COMPILER_VERSION) + if(CMAKE_C_SIMULATE_VERSION) + set(_compiler_version ${CMAKE_C_SIMULATE_VERSION}) + elseif(CMAKE_CXX_SIMULATE_VERSION) + set(_compiler_version ${CMAKE_CXX_SIMULATE_VERSION}) + elseif(CMAKE_C_COMPILER_VERSION) set(_compiler_version ${CMAKE_C_COMPILER_VERSION}) else() set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION}) @@ -220,7 +224,7 @@ set (CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INI set (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT}) macro(__windows_compiler_msvc lang) - if(NOT "${CMAKE_${lang}_COMPILER_VERSION}" VERSION_LESS 14) + if(NOT MSVC_VERSION LESS 1400) # for 2005 make sure the manifest is put in the dll with mt set(_CMAKE_VS_LINK_DLL " -E vs_link_dll ") set(_CMAKE_VS_LINK_EXE " -E vs_link_exe ") -- cgit v0.12