Bladeren bron

IPO: Consider support for each language separately

We only define `INTERPROCEDURAL_OPTIMIZATION` behavior for C, CXX, and
Fortran languages.  Do not try to enable support for other languages.
Furthermore, each language builds with a different compiler, so check
for support by CMake and the compiler for each language independently.

Fixes: #16944
Brad King 8 jaren geleden
bovenliggende
commit
ba247ccaba

+ 10 - 8
Modules/CheckIPOSupported.cmake

@@ -207,15 +207,17 @@ function(check_ipo_supported)
     endif()
   endif()
 
-  if(NOT _CMAKE_IPO_SUPPORTED_BY_CMAKE)
-    _ipo_not_supported("CMake doesn't support IPO for current compiler")
-    return()
-  endif()
+  foreach(lang ${languages})
+    if(NOT _CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE)
+      _ipo_not_supported("CMake doesn't support IPO for current ${lang} compiler")
+      return()
+    endif()
 
-  if(NOT _CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER)
-    _ipo_not_supported("Compiler doesn't support IPO")
-    return()
-  endif()
+    if(NOT _CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER)
+      _ipo_not_supported("${lang} compiler doesn't support IPO")
+      return()
+    endif()
+  endforeach()
 
   if(CMAKE_GENERATOR MATCHES "^Visual Studio ")
     _ipo_not_supported("CMake doesn't support IPO for current generator")

+ 2 - 2
Modules/Compiler/Clang.cmake

@@ -30,8 +30,8 @@ else()
       set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "--gcc-toolchain=")
     endif()
 
-    set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
-    set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+    set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
+    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
 
     string(COMPARE EQUAL "${CMAKE_${lang}_COMPILER_ID}" "AppleClang" __is_apple_clang)
 

+ 3 - 3
Modules/Compiler/GNU.cmake

@@ -48,14 +48,14 @@ macro(__compiler_gnu lang)
     set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
   endif()
 
-  set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
-  set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+  set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
+  set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
 
   # '-flto' introduced since GCC 4.5:
   # * https://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Option-Summary.html (no)
   # * https://gcc.gnu.org/onlinedocs/gcc-4.5.4/gcc/Option-Summary.html (yes)
   if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.5)
-    set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
     set(__lto_flags -flto)
 
     if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.7)

+ 2 - 2
Modules/Compiler/QCC.cmake

@@ -13,8 +13,8 @@ macro(__compiler_qcc lang)
   set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,")
   set(CMAKE_DEPFILE_FLAGS_${lang} "-Wc,-MD,<DEPFILE>,-MT,<OBJECT>,-MF,<DEPFILE>")
 
-  set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO)
-  set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+  set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE NO)
+  set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
 
   unset(CMAKE_${lang}_COMPILE_OPTIONS_IPO)
   unset(CMAKE_${lang}_ARCHIVE_CREATE_IPO)

+ 4 - 4
Modules/Platform/Linux-Intel.cmake

@@ -30,7 +30,7 @@ macro(__linux_compiler_intel lang)
   # executables that use dlopen but do not set ENABLE_EXPORTS.
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
 
-  set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
+  set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
 
   if(XIAR)
     # INTERPROCEDURAL_OPTIMIZATION
@@ -38,10 +38,10 @@ macro(__linux_compiler_intel lang)
     set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO
       "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
       "${XIAR} -s <TARGET> ")
-    set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
-    set(_CMAKE_IPO_LEGACY_BEHAVIOR YES)
+    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+    set(_CMAKE_${lang}_IPO_LEGACY_BEHAVIOR YES)
   else()
-    set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+    set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
   endif()
 
   if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)

+ 15 - 8
Source/cmGeneratorTarget.cxx

@@ -469,7 +469,8 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
   return this->LocalGenerator->GetFeature(feature, config);
 }
 
-bool cmGeneratorTarget::IsIPOEnabled(const std::string& config) const
+bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
+                                     std::string const& config) const
 {
   const char* feature = "INTERPROCEDURAL_OPTIMIZATION";
   const bool result = cmSystemTools::IsOn(this->GetFeature(feature, config));
@@ -479,10 +480,15 @@ bool cmGeneratorTarget::IsIPOEnabled(const std::string& config) const
     return false;
   }
 
+  if (lang != "C" && lang != "CXX" && lang != "Fortran") {
+    // We do not define IPO behavior for other languages.
+    return false;
+  }
+
   cmPolicies::PolicyStatus cmp0069 = this->GetPolicyStatusCMP0069();
 
   if (cmp0069 == cmPolicies::OLD || cmp0069 == cmPolicies::WARN) {
-    if (this->Makefile->IsOn("_CMAKE_IPO_LEGACY_BEHAVIOR")) {
+    if (this->Makefile->IsOn("_CMAKE_" + lang + "_IPO_LEGACY_BEHAVIOR")) {
       return true;
     }
     if (this->PolicyReportedCMP0069) {
@@ -506,10 +512,10 @@ bool cmGeneratorTarget::IsIPOEnabled(const std::string& config) const
 
   // Note: check consistency with messages from CheckIPOSupported
   const char* message = CM_NULLPTR;
-  if (!this->Makefile->IsOn("_CMAKE_IPO_SUPPORTED_BY_CMAKE")) {
+  if (!this->Makefile->IsOn("_CMAKE_" + lang + "_IPO_SUPPORTED_BY_CMAKE")) {
     message = "CMake doesn't support IPO for current compiler";
-  } else if (!this->Makefile->IsOn(
-               "_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER")) {
+  } else if (!this->Makefile->IsOn("_CMAKE_" + lang +
+                                   "_IPO_MAY_BE_SUPPORTED_BY_COMPILER")) {
     message = "Compiler doesn't support IPO";
   } else if (!this->GlobalGenerator->IsIPOSupported()) {
     message = "CMake doesn't support IPO for current generator";
@@ -2417,9 +2423,10 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
 
 //----------------------------------------------------------------------------
 std::string cmGeneratorTarget::GetFeatureSpecificLinkRuleVariable(
-  std::string const& var, std::string const& config) const
+  std::string const& var, std::string const& lang,
+  std::string const& config) const
 {
-  if (this->IsIPOEnabled(config)) {
+  if (this->IsIPOEnabled(lang, config)) {
     std::string varIPO = var + "_IPO";
     if (this->Makefile->IsDefinitionSet(varIPO)) {
       return varIPO;
@@ -2436,7 +2443,7 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
   switch (this->GetType()) {
     case cmStateEnums::STATIC_LIBRARY: {
       std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
-      return this->GetFeatureSpecificLinkRuleVariable(var, config);
+      return this->GetFeatureSpecificLinkRuleVariable(var, lang, config);
     }
     case cmStateEnums::SHARED_LIBRARY:
       return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY";

+ 3 - 2
Source/cmGeneratorTarget.h

@@ -165,7 +165,7 @@ public:
   const char* GetFeature(const std::string& feature,
                          const std::string& config) const;
 
-  bool IsIPOEnabled(const std::string& config) const;
+  bool IsIPOEnabled(std::string const& lang, std::string const& config) const;
 
   bool IsLinkInterfaceDependentBoolProperty(const std::string& p,
                                             const std::string& config) const;
@@ -385,7 +385,8 @@ public:
                      std::vector<std::string>& archVec) const;
 
   std::string GetFeatureSpecificLinkRuleVariable(
-    std::string const& var, std::string const& config) const;
+    std::string const& var, std::string const& lang,
+    std::string const& config) const;
 
   /** Return the rule variable used to create this type of target.  */
   std::string GetCreateRuleVariable(std::string const& lang,

+ 1 - 1
Source/cmGlobalXCodeGenerator.cxx

@@ -1666,7 +1666,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     return;
   }
 
-  if (gtgt->IsIPOEnabled(configName)) {
+  if (gtgt->IsIPOEnabled(llang, configName)) {
     const char* ltoValue =
       this->CurrentMakefile->IsOn("_CMAKE_LTO_THIN") ? "YES_THIN" : "YES";
     buildSettings->AddAttribute("LLVM_LTO", this->CreateString(ltoValue));

+ 2 - 2
Source/cmLocalGenerator.cxx

@@ -1334,7 +1334,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
   flagsVar += "_FLAGS";
   this->AddConfigVariableFlags(flags, flagsVar, config);
 
-  if (target->IsIPOEnabled(config)) {
+  if (target->IsIPOEnabled(lang, config)) {
     this->AppendFeatureOptions(flags, lang, "IPO");
   }
 }
@@ -1836,7 +1836,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
                                             const std::string& config,
                                             const std::string& lang)
 {
-  if (!target->IsIPOEnabled(config)) {
+  if (!target->IsIPOEnabled(lang, config)) {
     return;
   }
 

+ 1 - 1
Source/cmLocalVisualStudio7Generator.cxx

@@ -672,7 +672,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
     this->AddCompileOptions(flags, target, linkLanguage, configName);
 
     // Check IPO related warning/error.
-    target->IsIPOEnabled(configName);
+    target->IsIPOEnabled(linkLanguage, configName);
   }
 
   if (this->FortranProject) {

+ 3 - 3
Source/cmMakefileLibraryTargetGenerator.cxx

@@ -699,7 +699,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     arCreateVar += "_ARCHIVE_CREATE";
 
     arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-      arCreateVar, this->ConfigName);
+      arCreateVar, linkLanguage, this->ConfigName);
 
     if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
       cmSystemTools::ExpandListArgument(rule, archiveCreateCommands);
@@ -709,7 +709,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     arAppendVar += "_ARCHIVE_APPEND";
 
     arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-      arAppendVar, this->ConfigName);
+      arAppendVar, linkLanguage, this->ConfigName);
 
     if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
       cmSystemTools::ExpandListArgument(rule, archiveAppendCommands);
@@ -719,7 +719,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
     arFinishVar += "_ARCHIVE_FINISH";
 
     arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-      arFinishVar, this->ConfigName);
+      arFinishVar, linkLanguage, this->ConfigName);
 
     if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
       cmSystemTools::ExpandListArgument(rule, archiveFinishCommands);

+ 2 - 2
Source/cmNinjaNormalTargetGenerator.cxx

@@ -512,7 +512,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
         linkCmdVar += "_ARCHIVE_CREATE";
 
         linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-          linkCmdVar, this->GetConfigName());
+          linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
 
         const char* linkCmd = mf->GetRequiredDefinition(linkCmdVar);
         cmSystemTools::ExpandListArgument(linkCmd, linkCmds);
@@ -523,7 +523,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
         linkCmdVar += "_ARCHIVE_FINISH";
 
         linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
-          linkCmdVar, this->GetConfigName());
+          linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
 
         const char* linkCmd = mf->GetRequiredDefinition(linkCmdVar);
         cmSystemTools::ExpandListArgument(linkCmd, linkCmds);

+ 1 - 1
Source/cmVisualStudio10TargetGenerator.cxx

@@ -2255,7 +2255,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
   }
 
   // Check IPO related warning/error.
-  this->GeneratorTarget->IsIPOEnabled(configName);
+  this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName);
 
   // Get preprocessor definitions for this directory.
   std::string defineFlags =

+ 1 - 1
Tests/RunCMake/CMP0069/CMP0069-NEW-cmake.cmake

@@ -1,6 +1,6 @@
 cmake_policy(SET CMP0069 NEW)
 
-set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO)
+set(_CMAKE_CXX_IPO_SUPPORTED_BY_CMAKE NO)
 
 add_executable(foo main.cpp)
 set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

+ 2 - 2
Tests/RunCMake/CMP0069/CMP0069-NEW-compiler.cmake

@@ -1,7 +1,7 @@
 cmake_policy(SET CMP0069 NEW)
 
-set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
-set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+set(_CMAKE_CXX_IPO_SUPPORTED_BY_CMAKE YES)
+set(_CMAKE_CXX_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
 
 add_executable(foo main.cpp)
 set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

+ 2 - 2
Tests/RunCMake/CMP0069/CMP0069-NEW-generator.cmake

@@ -1,7 +1,7 @@
 cmake_policy(SET CMP0069 NEW)
 
-set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
-set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+set(_CMAKE_CXX_IPO_SUPPORTED_BY_CMAKE YES)
+set(_CMAKE_CXX_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
 
 add_executable(foo main.cpp)
 set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

+ 1 - 1
Tests/RunCMake/CMP0069/CMP0069-WARN.cmake

@@ -1,4 +1,4 @@
-set(_CMAKE_IPO_LEGACY_BEHAVIOR NO)
+set(_CMAKE_CXX_IPO_LEGACY_BEHAVIOR NO)
 
 add_executable(foo main.cpp)
 set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)

+ 1 - 1
Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake-stderr.txt

@@ -1,5 +1,5 @@
 ^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
-  IPO is not supported \(CMake doesn't support IPO for current compiler\)\.
+  IPO is not supported \(CMake doesn't support IPO for current C compiler\)\.
 Call Stack \(most recent call first\):
   .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\)
   not-supported-by-cmake\.cmake:[0-9]+ \(check_ipo_supported\)

+ 1 - 1
Tests/RunCMake/CheckIPOSupported/not-supported-by-cmake.cmake

@@ -1,3 +1,3 @@
 project(${RunCMake_TEST} LANGUAGES C)
-set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO)
+set(_CMAKE_C_IPO_SUPPORTED_BY_CMAKE NO)
 check_ipo_supported()

+ 1 - 1
Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler-stderr.txt

@@ -1,5 +1,5 @@
 ^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
-  IPO is not supported \(Compiler doesn't support IPO\)\.
+  IPO is not supported \(C compiler doesn't support IPO\)\.
 Call Stack \(most recent call first\):
   .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\)
   not-supported-by-compiler\.cmake:[0-9]+ \(check_ipo_supported\)

+ 2 - 2
Tests/RunCMake/CheckIPOSupported/not-supported-by-compiler.cmake

@@ -1,4 +1,4 @@
 project(${RunCMake_TEST} LANGUAGES C)
-set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
-set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+set(_CMAKE_C_IPO_SUPPORTED_BY_CMAKE YES)
+set(_CMAKE_C_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
 check_ipo_supported()

+ 2 - 2
Tests/RunCMake/CheckIPOSupported/not-supported-by-generator.cmake

@@ -1,6 +1,6 @@
 project(${RunCMake_TEST} LANGUAGES C)
 
-set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
-set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+set(_CMAKE_C_IPO_SUPPORTED_BY_CMAKE YES)
+set(_CMAKE_C_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
 
 check_ipo_supported()