From ab65862417adc80dfb18170a6bd70889a24fe045 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 2 Oct 2013 13:52:48 -0400 Subject: [PATCH 1/3] Clang: Add separate "AppleClang" compiler id Apple distributes their own Clang build with their own version numbers that differ from upstream Clang. Use the __apple_build_version__ symbol to identify the Apple Clang compiler and report the Apple Build Version as the fourth version component in CMAKE__COMPILER_VERSION. Add Compiler/AppleClang- and Platform/Darwin-AppleClang- modules that simply include the upstream equivalents. Fix comparisons of CMAKE__COMPILER_ID to Clang in CMake's own source and tests to account for AppleClang. --- Modules/CMakeCCompilerId.c.in | 7 ++++++- Modules/CMakeCXXCompilerId.cpp.in | 7 ++++++- Modules/Compiler/AppleClang-ASM.cmake | 1 + Modules/Compiler/AppleClang-C.cmake | 1 + Modules/Compiler/AppleClang-CXX.cmake | 1 + Modules/Platform/Darwin-AppleClang-C.cmake | 1 + Modules/Platform/Darwin-AppleClang-CXX.cmake | 1 + Source/cmDocumentVariables.cxx | 1 + Tests/Assembler/CMakeLists.txt | 2 +- Tests/IncludeDirectories/CMakeLists.txt | 2 +- Utilities/cmlibarchive/CMakeLists.txt | 2 +- 11 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 Modules/Compiler/AppleClang-ASM.cmake create mode 100644 Modules/Compiler/AppleClang-C.cmake create mode 100644 Modules/Compiler/AppleClang-CXX.cmake create mode 100644 Modules/Platform/Darwin-AppleClang-C.cmake create mode 100644 Modules/Platform/Darwin-AppleClang-CXX.cmake diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 66a5582650..56c11a0bbd 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -29,7 +29,12 @@ # endif #elif defined(__clang__) -# define COMPILER_ID "Clang" +# if defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) +# else +# define COMPILER_ID "Clang" +# endif # define COMPILER_VERSION_MAJOR DEC(__clang_major__) # define COMPILER_VERSION_MINOR DEC(__clang_minor__) # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 5e87715c03..2b8bf6e2a1 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -34,7 +34,12 @@ # endif #elif defined(__clang__) -# define COMPILER_ID "Clang" +# if defined(__apple_build_version__) +# define COMPILER_ID "AppleClang" +# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__) +# else +# define COMPILER_ID "Clang" +# endif # define COMPILER_VERSION_MAJOR DEC(__clang_major__) # define COMPILER_VERSION_MINOR DEC(__clang_minor__) # define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__) diff --git a/Modules/Compiler/AppleClang-ASM.cmake b/Modules/Compiler/AppleClang-ASM.cmake new file mode 100644 index 0000000000..f52bde05eb --- /dev/null +++ b/Modules/Compiler/AppleClang-ASM.cmake @@ -0,0 +1 @@ +include(Compiler/Clang-ASM) diff --git a/Modules/Compiler/AppleClang-C.cmake b/Modules/Compiler/AppleClang-C.cmake new file mode 100644 index 0000000000..44070b83fe --- /dev/null +++ b/Modules/Compiler/AppleClang-C.cmake @@ -0,0 +1 @@ +include(Compiler/Clang-C) diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake new file mode 100644 index 0000000000..680f7208e4 --- /dev/null +++ b/Modules/Compiler/AppleClang-CXX.cmake @@ -0,0 +1 @@ +include(Compiler/Clang-CXX) diff --git a/Modules/Platform/Darwin-AppleClang-C.cmake b/Modules/Platform/Darwin-AppleClang-C.cmake new file mode 100644 index 0000000000..98971bbca3 --- /dev/null +++ b/Modules/Platform/Darwin-AppleClang-C.cmake @@ -0,0 +1 @@ +include(Platform/Darwin-Clang-C) diff --git a/Modules/Platform/Darwin-AppleClang-CXX.cmake b/Modules/Platform/Darwin-AppleClang-CXX.cmake new file mode 100644 index 0000000000..4e9e7c12e7 --- /dev/null +++ b/Modules/Platform/Darwin-AppleClang-CXX.cmake @@ -0,0 +1 @@ +include(Platform/Darwin-Clang-CXX) diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index c4f6216b6c..a2a1bd683d 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1606,6 +1606,7 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Possible values include:\n" " Absoft = Absoft Fortran (absoft.com)\n" " ADSP = Analog VisualDSP++ (analog.com)\n" + " AppleClang = Apple Clang (apple.com)\n" " Clang = LLVM Clang (clang.llvm.org)\n" " Cray = Cray Compiler (cray.com)\n" " Embarcadero, Borland = Embarcadero (embarcadero.com)\n" diff --git a/Tests/Assembler/CMakeLists.txt b/Tests/Assembler/CMakeLists.txt index bb4bcccbe8..1f07dc9cf4 100644 --- a/Tests/Assembler/CMakeLists.txt +++ b/Tests/Assembler/CMakeLists.txt @@ -9,7 +9,7 @@ set(SRCS) # and also generate assembler files from C: if("${CMAKE_GENERATOR}" MATCHES "Makefile|Xcode" AND NOT CMAKE_OSX_ARCHITECTURES) - if(("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|Clang|HP|SunPro|XL)$") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" AND UNIX)) + if(("${CMAKE_C_COMPILER_ID}" MATCHES "^(GNU|Clang|AppleClang|HP|SunPro|XL)$") OR ("${CMAKE_C_COMPILER_ID}" STREQUAL "Intel" AND UNIX)) set(C_FLAGS "${CMAKE_C_FLAGS}") separate_arguments(C_FLAGS) if(CMAKE_OSX_SYSROOT AND CMAKE_C_SYSROOT_FLAG AND NOT ";${C_FLAGS};" MATCHES ";${CMAKE_C_SYSROOT_FLAG};") diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt index 35ad8dc90d..9ee195714c 100644 --- a/Tests/IncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6) project(IncludeDirectories) if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4) - OR CMAKE_C_COMPILER_ID STREQUAL Clang) + OR CMAKE_C_COMPILER_ID STREQUAL Clang OR CMAKE_C_COMPILER_ID STREQUAL AppleClang) AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "Ninja")) include(CheckCXXCompilerFlag) check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test) diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt index 8ef0e89d6d..132bfebdb3 100644 --- a/Utilities/cmlibarchive/CMakeLists.txt +++ b/Utilities/cmlibarchive/CMakeLists.txt @@ -56,7 +56,7 @@ SET(CMAKE_REQUIRED_FLAGS) # Disable warnings to avoid changing 3rd party code. IF("${CMAKE_C_COMPILER_ID}" MATCHES - "^(GNU|Clang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$") + "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") ELSEIF("${CMAKE_C_COMPILER_ID}" MATCHES "^(PathScale)$") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall") From aa53ee57bb50faa3aa64e86cb58bbe2df6688335 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 2 Oct 2013 14:10:38 -0400 Subject: [PATCH 2/3] Add policy CMP0025 for Apple Clang compiler id compatibility The parent commit introduced a separate "AppleClang" compiler id for Apple's Clang distribution. Add a policy in order to support projects that expect this compiler's id to be just "Clang". When the policy is OLD or not set, map AppleClang back to Clang. Continue to use the AppleClang id internally while enabling the language, but set the CMAKE__COMPILER_ID after project() or enable_language() to the compatible value for use by project code. --- Source/cmGlobalGenerator.cxx | 41 ++++++++++++++++++++++++++++++++++++ Source/cmGlobalGenerator.h | 2 ++ Source/cmPolicies.cxx | 17 +++++++++++++++ Source/cmPolicies.h | 1 + 4 files changed, 61 insertions(+) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 7f2b592f3e..2c3834a0ee 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -616,6 +616,9 @@ cmGlobalGenerator::EnableLanguage(std::vectorconst& languages, { this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags; } + + // Translate compiler ids for compatibility. + this->CheckCompilerIdCompatibility(mf, lang); } // end for each language // Now load files that can override any settings on the platform or for @@ -631,6 +634,44 @@ cmGlobalGenerator::EnableLanguage(std::vectorconst& languages, } } +//---------------------------------------------------------------------------- +void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf, + std::string lang) +{ + std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID"; + const char* compilerId = mf->GetDefinition(compilerIdVar.c_str()); + if(compilerId && strcmp(compilerId, "AppleClang") == 0) + { + cmPolicies* policies = this->CMakeInstance->GetPolicies(); + switch(mf->GetPolicyStatus(cmPolicies::CMP0025)) + { + case cmPolicies::WARN: + if(!this->CMakeInstance->GetIsInTryCompile()) + { + cmOStringStream w; + w << policies->GetPolicyWarning(cmPolicies::CMP0025) << "\n" + "Converting " << lang << + " compiler id \"AppleClang\" to \"Clang\" for compatibility." + ; + mf->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + } + case cmPolicies::OLD: + // OLD behavior is to convert AppleClang to Clang. + mf->AddDefinition(compilerIdVar.c_str(), "Clang"); + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + mf->IssueMessage( + cmake::FATAL_ERROR, + policies->GetRequiredPolicyError(cmPolicies::CMP0025) + ); + case cmPolicies::NEW: + // NEW behavior is to keep AppleClang. + break; + } + } +} + //---------------------------------------------------------------------------- const char* cmGlobalGenerator::GetLanguageOutputExtension(cmSourceFile const& source) diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 18aba24bf8..70f6e32b2c 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -383,6 +383,8 @@ private: void WriteSummary(); void WriteSummary(cmTarget* target); + void CheckCompilerIdCompatibility(cmMakefile* mf, std::string lang); + cmExternalMakefileProjectGenerator* ExtraGenerator; // track files replaced during a Generate diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 45670b3ca4..c3d6a946e4 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -620,6 +620,23 @@ cmPolicies::cmPolicies() "The NEW behavior for this policy is to not to allow including the " "result of an export() command.", 2,8,13,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0025, "CMP0025", + "Compiler id for Apple Clang is now AppleClang.", + "CMake >= 2.8.13 recognize that Apple Clang is a different compiler " + "than upstream Clang and that they have different version numbers. " + "CMake now prefers to present this to projects by setting " + "CMAKE__COMPILER_ID to \"AppleClang\" instead of \"Clang\". " + "However, existing projects may assume the compiler id for Apple Clang " + "is just \"Clang\" as it was in CMake < 2.8.13. " + "Therefore this policy determines for Apple Clang which compiler id " + "to report in CMAKE__COMPILER_ID after is enabled by " + "the project() or enable_language() command." + "\n" + "The OLD behavior for this policy is to use compiler id \"Clang\". " + "The NEW behavior for this policy is to use compiler id \"AppleClang\".", + 2,8,13,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index bafe5b2d3e..ec8959d456 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -75,6 +75,7 @@ public: CMP0022, ///< INTERFACE_LINK_LIBRARIES defines the link interface CMP0023, ///< Disallow mixing keyword and plain tll signatures CMP0024, ///< Disallow including export() result. + CMP0025, ///< Compiler id for Apple Clang is now AppleClang /** \brief Always the last entry. * From 1763c31c3b964343b88f8f26dc2941dd8c0e1fbe Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 2 Oct 2013 14:45:54 -0400 Subject: [PATCH 3/3] Set policy CMP0025 to NEW while building CMake itself CMake is aware of the policy's NEW behavior and the AppleClang compiler id. Set the policy to NEW explicitly to avoid the warning and get the NEW behavior. Also teach the RunCMake test infrastructure to build tests with -DCMAKE_POLICY_DEFAULT_CMP0025=NEW to avoid the policy warning in test output that must match specific regular expressions. --- CMakeLists.txt | 3 +++ Source/kwsys/CMakeLists.txt | 3 +++ Tests/RunCMake/RunCMake.cmake | 3 +++ Utilities/cmcurl/CMakeLists.txt | 3 +++ 4 files changed, 12 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fbbe08a11..77b4604404 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,9 @@ #============================================================================= cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR) set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required +if(POLICY CMP0025) + cmake_policy(SET CMP0025 NEW) +endif() project(CMake) if(CMAKE_BOOTSTRAP) diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt index 0f2783689d..a9d89d4742 100644 --- a/Source/kwsys/CMakeLists.txt +++ b/Source/kwsys/CMakeLists.txt @@ -85,6 +85,9 @@ # written. CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR) +IF(POLICY CMP0025) + CMAKE_POLICY(SET CMP0025 NEW) +ENDIF() #----------------------------------------------------------------------------- # If a namespace is not specified, use "kwsys" and enable testing. diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake index 00faa4ca7a..6e58d62882 100644 --- a/Tests/RunCMake/RunCMake.cmake +++ b/Tests/RunCMake/RunCMake.cmake @@ -36,6 +36,9 @@ function(run_cmake test) if(NOT DEFINED RunCMake_TEST_OPTIONS) set(RunCMake_TEST_OPTIONS "") endif() + if(APPLE) + list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0025=NEW) + endif() execute_process( COMMAND ${CMAKE_COMMAND} "${RunCMake_TEST_SOURCE_DIR}" -G "${RunCMake_GENERATOR}" diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt index 74a713dd81..abf04d8b08 100644 --- a/Utilities/cmcurl/CMakeLists.txt +++ b/Utilities/cmcurl/CMakeLists.txt @@ -1,4 +1,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6.3 FATAL_ERROR) +IF(POLICY CMP0025) + CMAKE_POLICY(SET CMP0025 NEW) +ENDIF() PROJECT(LIBCURL C) # Setup package meta-data