From 1588a577d16cfb1a689a444b1db1df3ccff2cc3d Mon Sep 17 00:00:00 2001
From: Ruslan Baratov <ruslan_baratov@yahoo.com>
Date: Thu, 9 Mar 2017 21:05:19 +0800
Subject: Add policy CMP0069 to enforce INTERPROCEDURAL_OPTIMIZATION

Previously the `INTERPROCEDURAL_OPTIMIZATION` target property was
honored only for the Intel compiler on Linux and otherwise ignored.  In
order to add support for more compilers incrementally without changing
behavior in the future, add a new policy whose NEW behavior enforces the
`INTERPROCEDURAL_OPTIMIZATION` property.  Add flags for supported
compilers and otherwise produce an error.
---
 Help/manual/cmake-policies.7.rst                   |  1 +
 Help/policy/CMP0069.rst                            | 92 ++++++++++++++++++++++
 .../dev/interprocedural_optimization_policy.rst    |  8 ++
 Modules/CheckIPOSupported.cmake                    | 15 +++-
 Modules/CheckIPOSupported/CMakeLists-C.txt.in      |  2 +-
 Modules/CheckIPOSupported/CMakeLists-CXX.txt.in    |  2 +-
 Modules/Platform/Linux-Intel.cmake                 |  1 +
 Source/cmGeneratorTarget.cxx                       | 58 +++++++++++++-
 Source/cmGeneratorTarget.h                         |  1 +
 Source/cmGlobalGenerator.h                         |  2 +
 Source/cmGlobalNinjaGenerator.h                    |  2 +
 Source/cmGlobalUnixMakefileGenerator3.h            |  2 +
 Source/cmGlobalXCodeGenerator.cxx                  |  3 +
 Source/cmLocalVisualStudio7Generator.cxx           |  3 +
 Source/cmPolicies.h                                |  6 +-
 Source/cmVisualStudio10TargetGenerator.cxx         |  3 +
 .../RunCMake/CMP0069/CMP0069-NEW-cmake-result.txt  |  1 +
 .../RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt  |  4 +
 Tests/RunCMake/CMP0069/CMP0069-NEW-cmake.cmake     |  6 ++
 .../CMP0069/CMP0069-NEW-compiler-result.txt        |  1 +
 .../CMP0069/CMP0069-NEW-compiler-stderr.txt        |  4 +
 Tests/RunCMake/CMP0069/CMP0069-NEW-compiler.cmake  |  7 ++
 .../CMP0069/CMP0069-NEW-generator-result.txt       |  1 +
 .../CMP0069/CMP0069-NEW-generator-stderr.txt       |  4 +
 Tests/RunCMake/CMP0069/CMP0069-NEW-generator.cmake |  7 ++
 Tests/RunCMake/CMP0069/CMP0069-OLD.cmake           |  4 +
 Tests/RunCMake/CMP0069/CMP0069-WARN-stderr.txt     |  9 +++
 Tests/RunCMake/CMP0069/CMP0069-WARN.cmake          |  4 +
 Tests/RunCMake/CMP0069/CMakeLists.txt              |  3 +
 Tests/RunCMake/CMP0069/RunCMakeTest.cmake          | 11 +++
 Tests/RunCMake/CMP0069/main.cpp                    |  3 +
 Tests/RunCMake/CMakeLists.txt                      |  1 +
 Tests/RunCMake/CheckIPOSupported/CMakeLists.txt    |  3 +
 .../RunCMake/CheckIPOSupported/RunCMakeTest.cmake  |  1 +
 .../CheckIPOSupported/cmp0069-is-old-result.txt    |  1 +
 .../CheckIPOSupported/cmp0069-is-old-stderr.txt    |  5 ++
 .../CheckIPOSupported/cmp0069-is-old.cmake         |  6 ++
 .../RunCMake/TargetPolicies/PolicyList-stderr.txt  |  1 +
 38 files changed, 283 insertions(+), 5 deletions(-)
 create mode 100644 Help/policy/CMP0069.rst
 create mode 100644 Help/release/dev/interprocedural_optimization_policy.rst
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-result.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-cmake.cmake
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-result.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-compiler.cmake
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-generator-result.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-NEW-generator.cmake
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-OLD.cmake
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-WARN-stderr.txt
 create mode 100644 Tests/RunCMake/CMP0069/CMP0069-WARN.cmake
 create mode 100644 Tests/RunCMake/CMP0069/CMakeLists.txt
 create mode 100644 Tests/RunCMake/CMP0069/RunCMakeTest.cmake
 create mode 100644 Tests/RunCMake/CMP0069/main.cpp
 create mode 100644 Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-result.txt
 create mode 100644 Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
 create mode 100644 Tests/RunCMake/CheckIPOSupported/cmp0069-is-old.cmake

diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 0c9ee2d..7b85817 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.9
 .. toctree::
    :maxdepth: 1
 
+   CMP0069: INTERPROCEDURAL_OPTIMIZATION is enforced when enabled. </policy/CMP0069>
    CMP0068: RPATH settings on macOS do not affect install_name. </policy/CMP0068>
 
 Policies Introduced by CMake 3.8
diff --git a/Help/policy/CMP0069.rst b/Help/policy/CMP0069.rst
new file mode 100644
index 0000000..b8f5d80
--- /dev/null
+++ b/Help/policy/CMP0069.rst
@@ -0,0 +1,92 @@
+CMP0069
+-------
+
+:prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` is enforced when enabled.
+
+CMake 3.9 and newer prefer to add IPO flags whenever the
+:prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property is enabled and
+produce an error if flags are not known to CMake for the current compiler.
+Since a given compiler may not support IPO flags in all environments in which
+it is used, it is now the project's responsibility to use the
+:module:`CheckIPOSupported` module to check for support before enabling the
+:prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property.  This approach
+allows a project to conditionally activate IPO when supported.  It also
+allows an end user to set the :variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION`
+variable in an environment known to support IPO even if the project does
+not enable the property.
+
+Since CMake 3.8 and lower only honored :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION`
+for the Intel compiler on Linux, some projects may unconditionally enable the
+target property.  Policy ``CMP0069`` provides compatibility with such projects.
+
+This policy takes effect whenever the IPO property is enabled.  The ``OLD``
+behavior for this policy is to add IPO flags only for Intel compiler on Linux.
+The ``NEW`` behavior for this policy is to add IPO flags for the current
+compiler or produce an error if CMake does not know the flags.
+
+This policy was introduced in CMake version 3.9.  CMake version
+|release| warns when the policy is not set and uses ``OLD`` behavior.
+Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
+explicitly.
+
+.. include:: DEPRECATED.txt
+
+Examples
+^^^^^^^^
+
+Behave like CMake 3.8 and do not apply any IPO flags except for Intel compiler
+on Linux:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.8)
+  project(foo)
+
+  # ...
+
+  set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
+
+Use the :module:`CheckIPOSupported` module to detect whether IPO is
+supported by the current compiler, environment, and CMake version.
+Produce a fatal error if support is not available:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
+  project(foo)
+
+  include(CheckIPOSupport)
+  check_ipo_support()
+
+  # ...
+
+  set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
+
+Apply IPO flags only if compiler supports it:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
+  project(foo)
+
+  include(CheckIPOSupport)
+
+  # ...
+
+  check_ipo_support(RESULT result)
+  if(result)
+    set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
+  endif()
+
+Apply IPO flags without any checks.  This may lead to build errors if IPO
+is not supported by the compiler in the current environment.  Produce an
+error if CMake does not know IPO flags for the current compiler:
+
+.. code-block:: cmake
+
+  cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
+  project(foo)
+
+  # ...
+
+  set_property(TARGET ... PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
diff --git a/Help/release/dev/interprocedural_optimization_policy.rst b/Help/release/dev/interprocedural_optimization_policy.rst
new file mode 100644
index 0000000..93a9d68
--- /dev/null
+++ b/Help/release/dev/interprocedural_optimization_policy.rst
@@ -0,0 +1,8 @@
+interprocedural_optimization_policy
+-----------------------------------
+
+* The :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property is now enforced
+  when enabled.  CMake will add IPO flags unconditionally or produce an error
+  if it does not know the flags for the current compiler.  The project is now
+  responsible to use the :module:`CheckIPOSupported` module to check for IPO
+  support before enabling the target property.  See policy :policy:`CMP0069`.
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index 55c8901..31c1bd3 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -28,6 +28,9 @@ property.
     Specify languages whose compilers to check.
     Languages ``C`` and ``CXX`` are supported.
 
+It makes no sense to use this module when :policy:`CMP0069` is set to ``OLD`` so
+module will return error in this case. See policy :policy:`CMP0069` for details.
+
 Examples
 ^^^^^^^^
 
@@ -125,7 +128,17 @@ macro(_ipo_run_language_check language)
 endmacro()
 
 function(check_ipo_supported)
-  # TODO: IPO policy
+  cmake_policy(GET CMP0069 x)
+
+  string(COMPARE EQUAL "${x}" "" not_set)
+  if(not_set)
+    message(FATAL_ERROR "Policy CMP0069 is not set")
+  endif()
+
+  string(COMPARE EQUAL "${x}" "OLD" is_old)
+  if(is_old)
+    message(FATAL_ERROR "Policy CMP0069 set to OLD")
+  endif()
 
   set(optional)
   set(one RESULT OUTPUT)
diff --git a/Modules/CheckIPOSupported/CMakeLists-C.txt.in b/Modules/CheckIPOSupported/CMakeLists-C.txt.in
index d20f31f..5a3b8ee 100644
--- a/Modules/CheckIPOSupported/CMakeLists-C.txt.in
+++ b/Modules/CheckIPOSupported/CMakeLists-C.txt.in
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION "@CMAKE_VERSION@")
 project("@TRY_COMPILE_PROJECT_NAME@" LANGUAGES C)
 
-# TODO: IPO policy
+cmake_policy(SET CMP0069 NEW)
 
 add_library(foo foo.c)
 add_executable(boo main.c)
diff --git a/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in b/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in
index 4b55c70..30993fa 100644
--- a/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in
+++ b/Modules/CheckIPOSupported/CMakeLists-CXX.txt.in
@@ -1,7 +1,7 @@
 cmake_minimum_required(VERSION "@CMAKE_VERSION@")
 project("@TRY_COMPILE_PROJECT_NAME@" LANGUAGES CXX)
 
-# TODO: IPO policy
+cmake_policy(SET CMP0069 NEW)
 
 add_library(foo foo.cpp)
 add_executable(boo main.cpp)
diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake
index 45dc36f..6e2978a 100644
--- a/Modules/Platform/Linux-Intel.cmake
+++ b/Modules/Platform/Linux-Intel.cmake
@@ -39,6 +39,7 @@ macro(__linux_compiler_intel lang)
       "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
       "${XIAR} -s <TARGET> ")
     set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+    set(_CMAKE_IPO_LEGACY_BEHAVIOR YES)
   else()
     set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
   endif()
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 2199e4a..bb79050 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -286,6 +286,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   , FortranModuleDirectoryCreated(false)
   , SourceFileFlagsConstructed(false)
   , PolicyWarnedCMP0022(false)
+  , PolicyReportedCMP0069(false)
   , DebugIncludesDone(false)
   , DebugCompileOptionsDone(false)
   , DebugCompileFeaturesDone(false)
@@ -659,7 +660,62 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
 bool cmGeneratorTarget::IsIPOEnabled(const std::string& config) const
 {
   const char* feature = "INTERPROCEDURAL_OPTIMIZATION";
-  return cmSystemTools::IsOn(this->GetFeature(feature, config));
+  const bool result = cmSystemTools::IsOn(this->GetFeature(feature, config));
+
+  if (!result) {
+    // 'INTERPROCEDURAL_OPTIMIZATION' is off, no need to check policies
+    return false;
+  }
+
+  cmPolicies::PolicyStatus cmp0069 = this->GetPolicyStatusCMP0069();
+
+  if (cmp0069 == cmPolicies::OLD || cmp0069 == cmPolicies::WARN) {
+    if (this->Makefile->IsOn("_CMAKE_IPO_LEGACY_BEHAVIOR")) {
+      return true;
+    }
+    if (this->PolicyReportedCMP0069) {
+      // problem is already reported, no need to issue a message
+      return false;
+    }
+    if (cmp0069 == cmPolicies::WARN) {
+      std::ostringstream w;
+      w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0069) << "\n";
+      w << "INTERPROCEDURAL_OPTIMIZATION property will be ignored for target "
+        << "'" << this->GetName() << "'.";
+      this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+        cmake::AUTHOR_WARNING, w.str(), this->GetBacktrace());
+
+      this->PolicyReportedCMP0069 = true;
+    }
+    return false;
+  }
+
+  // Note: check consistency with messages from CheckIPOSupported
+  const char* message = CM_NULLPTR;
+  if (!this->Makefile->IsOn("_CMAKE_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")) {
+    message = "Compiler doesn't support IPO";
+  } else if (!this->GlobalGenerator->IsIPOSupported()) {
+    message = "CMake doesn't support IPO for current generator";
+  }
+
+  if (!message) {
+    // No error/warning messages
+    return true;
+  }
+
+  if (this->PolicyReportedCMP0069) {
+    // problem is already reported, no need to issue a message
+    return false;
+  }
+
+  this->PolicyReportedCMP0069 = true;
+
+  this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+    cmake::FATAL_ERROR, message, this->GetBacktrace());
+  return false;
 }
 
 const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 0ec7389..80bccd5 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -743,6 +743,7 @@ private:
   mutable std::set<cmLinkItem> UtilityItems;
   cmPolicies::PolicyMap PolicyMap;
   mutable bool PolicyWarnedCMP0022;
+  mutable bool PolicyReportedCMP0069;
   mutable bool DebugIncludesDone;
   mutable bool DebugCompileOptionsDone;
   mutable bool DebugCompileFeaturesDone;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index b3cb41f..6432538 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -333,6 +333,8 @@ public:
 
   virtual bool UseFolderProperty() const;
 
+  virtual bool IsIPOSupported() const { return false; }
+
   /** Return whether the generator should use EFFECTIVE_PLATFORM_NAME. This is
       relevant for mixed macOS and iOS builds. */
   virtual bool UseEffectivePlatformName(cmMakefile*) const { return false; }
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index a51e919..956af51 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -99,6 +99,8 @@ public:
    */
   static bool SupportsPlatform() { return false; }
 
+  bool IsIPOSupported() const CM_OVERRIDE { return true; }
+
   /**
    * Write a build statement to @a os with the @a comment using
    * the @a rule the list of @a outputs files and inputs.
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 67d7bc9..bbf9f0f 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -149,6 +149,8 @@ public:
   /** Does the make tool tolerate .DELETE_ON_ERROR? */
   virtual bool AllowDeleteOnError() const { return true; }
 
+  bool IsIPOSupported() const CM_OVERRIDE { return true; }
+
   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const CM_OVERRIDE;
 
   std::string IncludeDirective;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 77f3408..45993ce 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1664,6 +1664,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
     return;
   }
 
+  // Check IPO related warning/error.
+  gtgt->IsIPOEnabled(configName);
+
   // Add define flags
   this->CurrentLocalGenerator->AppendFlags(
     defFlags, this->CurrentMakefile->GetDefineFlags());
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 7c33821..cd5b46b 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -670,6 +670,9 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
 
     // Add the target-specific flags.
     this->AddCompileOptions(flags, target, linkLanguage, configName);
+
+    // Check IPO related warning/error.
+    target->IsIPOEnabled(configName);
   }
 
   if (this->FortranProject) {
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index ecf06b3..72dcc4f 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -203,6 +203,9 @@ class cmMakefile;
          3, 8, 0, cmPolicies::WARN)                                           \
   SELECT(POLICY, CMP0068,                                                     \
          "RPATH settings on macOS do not affect install_name.", 3, 9, 0,      \
+         cmPolicies::WARN)                                                    \
+  SELECT(POLICY, CMP0069,                                                     \
+         "INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.", 3, 9, 0,   \
          cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -225,7 +228,8 @@ class cmMakefile;
   F(CMP0060)                                                                  \
   F(CMP0063)                                                                  \
   F(CMP0065)                                                                  \
-  F(CMP0068)
+  F(CMP0068)                                                                  \
+  F(CMP0069)
 
 /** \class cmPolicies
  * \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 84767a8..2ab72dc 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2239,6 +2239,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
                                             linkLanguage, configName.c_str());
   }
 
+  // Check IPO related warning/error.
+  this->GeneratorTarget->IsIPOEnabled(configName);
+
   // Get preprocessor definitions for this directory.
   std::string defineFlags =
     this->GeneratorTarget->Target->GetMakefile()->GetDefineFlags();
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-result.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt
new file mode 100644
index 0000000..ddb3cae
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0069-NEW-cmake\.cmake:[0-9]+ \(add_executable\):
+  CMake doesn't support IPO for current compiler
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake.cmake b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake.cmake
new file mode 100644
index 0000000..23fae13
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-cmake.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0069 NEW)
+
+set(_CMAKE_IPO_SUPPORTED_BY_CMAKE NO)
+
+add_executable(foo main.cpp)
+set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-result.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt
new file mode 100644
index 0000000..8decfab
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0069-NEW-compiler\.cmake:[0-9]+ \(add_executable\):
+  Compiler doesn't support IPO
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler.cmake b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler.cmake
new file mode 100644
index 0000000..24b409a
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-compiler.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0069 NEW)
+
+set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
+set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+
+add_executable(foo main.cpp)
+set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-result.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt
new file mode 100644
index 0000000..0e05ee7
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at CMP0069-NEW-generator\.cmake:[0-9]+ \(add_executable\):
+  CMake doesn't support IPO for current generator
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-NEW-generator.cmake b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator.cmake
new file mode 100644
index 0000000..df2a888
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-NEW-generator.cmake
@@ -0,0 +1,7 @@
+cmake_policy(SET CMP0069 NEW)
+
+set(_CMAKE_IPO_SUPPORTED_BY_CMAKE YES)
+set(_CMAKE_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+
+add_executable(foo main.cpp)
+set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
diff --git a/Tests/RunCMake/CMP0069/CMP0069-OLD.cmake b/Tests/RunCMake/CMP0069/CMP0069-OLD.cmake
new file mode 100644
index 0000000..cfe1e9d
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-OLD.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0069 OLD)
+
+add_executable(foo main.cpp)
+set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
diff --git a/Tests/RunCMake/CMP0069/CMP0069-WARN-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-WARN-stderr.txt
new file mode 100644
index 0000000..314e180
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-WARN-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Warning \(dev\) at CMP0069-WARN\.cmake:[0-9]+ \(add_executable\):
+  Policy CMP0069 is not set: INTERPROCEDURAL_OPTIMIZATION is enforced when
+  enabled.  Run "cmake --help-policy CMP0069" for policy details\.  Use the
+  cmake_policy command to set the policy and suppress this warning\.
+
+  INTERPROCEDURAL_OPTIMIZATION property will be ignored for target 'foo'\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.$
diff --git a/Tests/RunCMake/CMP0069/CMP0069-WARN.cmake b/Tests/RunCMake/CMP0069/CMP0069-WARN.cmake
new file mode 100644
index 0000000..0e3e670
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-WARN.cmake
@@ -0,0 +1,4 @@
+set(_CMAKE_IPO_LEGACY_BEHAVIOR NO)
+
+add_executable(foo main.cpp)
+set_target_properties(foo PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
diff --git a/Tests/RunCMake/CMP0069/CMakeLists.txt b/Tests/RunCMake/CMP0069/CMakeLists.txt
new file mode 100644
index 0000000..375cbdb
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.8)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0069/RunCMakeTest.cmake b/Tests/RunCMake/CMP0069/RunCMakeTest.cmake
new file mode 100644
index 0000000..61ba458
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+run_cmake(CMP0069-OLD)
+run_cmake(CMP0069-NEW-cmake)
+run_cmake(CMP0069-NEW-compiler)
+run_cmake(CMP0069-WARN)
+
+string(COMPARE EQUAL "${RunCMake_GENERATOR}" "Xcode" is_xcode)
+if(is_xcode OR RunCMake_GENERATOR MATCHES "^Visual Studio ")
+  run_cmake(CMP0069-NEW-generator)
+endif()
diff --git a/Tests/RunCMake/CMP0069/main.cpp b/Tests/RunCMake/CMP0069/main.cpp
new file mode 100644
index 0000000..5047a34
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/main.cpp
@@ -0,0 +1,3 @@
+int main()
+{
+}
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 217f0d5..0715a1a 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -107,6 +107,7 @@ add_RunCMake_test(CMP0064)
 if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
   add_RunCMake_test(CMP0068)
 endif()
+add_RunCMake_test(CMP0069)
 
 # The test for Policy 65 requires the use of the
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
diff --git a/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt b/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt
index a0effc9..4a13d29 100644
--- a/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt
+++ b/Tests/RunCMake/CheckIPOSupported/CMakeLists.txt
@@ -1,4 +1,7 @@
 cmake_minimum_required(VERSION 3.0)
 project(${RunCMake_TEST} NONE)
+
+cmake_policy(SET CMP0069 NEW)
+
 include(CheckIPOSupported)
 include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake
index 2815037..812f79b 100644
--- a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake
@@ -7,6 +7,7 @@ run_cmake(default-lang-none)
 run_cmake(not-supported-by-cmake)
 run_cmake(not-supported-by-compiler)
 run_cmake(save-to-result)
+run_cmake(cmp0069-is-old)
 
 if(RunCMake_GENERATOR MATCHES "^(Visual Studio |Xcode$)")
   run_cmake(not-supported-by-generator)
diff --git a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-result.txt b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
new file mode 100644
index 0000000..f183594
--- /dev/null
+++ b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
+  Policy CMP0069 set to OLD
+Call Stack \(most recent call first\):
+  cmp0069-is-old\.cmake:[0-9]+ \(check_ipo_supported\)
+  CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old.cmake b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old.cmake
new file mode 100644
index 0000000..14fed04
--- /dev/null
+++ b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old.cmake
@@ -0,0 +1,6 @@
+project(${RunCMake_TEST} LANGUAGES C CXX)
+
+cmake_policy(SET CMP0069 OLD)
+
+include(CheckIPOSupported)
+check_ipo_supported()
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 78657ef..5f6be87 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -21,6 +21,7 @@
    \* CMP0063
    \* CMP0065
    \* CMP0068
+   \* CMP0069
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)
-- 
cgit v0.12