Просмотр исходного кода

Export: Disallow exported interface includes in src/build tree (#14592).

Allow directories in the source tree or build tree only if the
install tree is a subdirectory of the source tree or build tree,
as appropriate.

Re-use the test files in the RunCMake.include_directories test
to run in multiple scenarios.  Bump the required CMake version
in the test to 3.0 to ensure that the new policy warnings are
emitted correctly.
Stephen Kelly 12 лет назад
Родитель
Сommit
783bce295b
33 измененных файлов с 282 добавлено и 3 удалено
  1. 1 0
      Help/manual/cmake-policies.7.rst
  2. 21 0
      Help/policy/CMP0052.rst
  3. 5 0
      Help/release/dev/CMP0052.rst
  4. 37 1
      Source/cmExportFileGenerator.cxx
  5. 6 0
      Source/cmPolicies.cxx
  6. 2 0
      Source/cmPolicies.h
  7. 2 1
      Source/cmTarget.h
  8. 1 0
      Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
  9. 1 0
      Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-result.txt
  10. 6 0
      Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-stderr.txt
  11. 1 0
      Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-result.txt
  12. 1 0
      Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-stderr.txt
  13. 1 0
      Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-result.txt
  14. 15 0
      Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-stderr.txt
  15. 1 1
      Tests/RunCMake/include_directories/CMakeLists.txt
  16. 1 0
      Tests/RunCMake/include_directories/InstallInBinDir-result.txt
  17. 6 0
      Tests/RunCMake/include_directories/InstallInBinDir-stderr.txt
  18. 1 0
      Tests/RunCMake/include_directories/InstallInSrcDir-result.txt
  19. 6 0
      Tests/RunCMake/include_directories/InstallInSrcDir-stderr.txt
  20. 1 0
      Tests/RunCMake/include_directories/InstallPrefixInInterface-result.txt
  21. 1 0
      Tests/RunCMake/include_directories/InstallPrefixInInterface-stderr.txt
  22. 11 0
      Tests/RunCMake/include_directories/InstallPrefixInInterface.cmake
  23. 1 0
      Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-result.txt
  24. 1 0
      Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-stderr.txt
  25. 1 0
      Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-result.txt
  26. 1 0
      Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-stderr.txt
  27. 125 0
      Tests/RunCMake/include_directories/RunCMakeTest.cmake
  28. 1 0
      Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-result.txt
  29. 6 0
      Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-stderr.txt
  30. 1 0
      Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-result.txt
  31. 1 0
      Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-stderr.txt
  32. 1 0
      Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-result.txt
  33. 15 0
      Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-stderr.txt

+ 1 - 0
Help/manual/cmake-policies.7.rst

@@ -103,3 +103,4 @@ All Policies
    /policy/CMP0049
    /policy/CMP0050
    /policy/CMP0051
+   /policy/CMP0052

+ 21 - 0
Help/policy/CMP0052.rst

@@ -0,0 +1,21 @@
+CMP0052
+-------
+
+Reject source and build dirs in installed INTERFACE_INCLUDE_DIRECTORIES.
+
+CMake 3.0 and lower allowed subdirectories of the source directory or build
+directory to be in the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of
+installed and exported targets, if the directory was also a subdirectory of
+the installation prefix.  This makes the installation depend on the
+existence of the source dir or binary dir, and the installation will be
+broken if either are removed after installation.
+
+The OLD behavior for this policy is to export the content of the
+:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` with the source or binary
+directory.  The NEW behavior for this
+policy is to issue an error if such a directory is used.
+
+This policy was introduced in CMake version 3.1.
+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.

+ 5 - 0
Help/release/dev/CMP0052.rst

@@ -0,0 +1,5 @@
+CMP0052
+-------
+
+* Policy :policy:`CMP0052` introduced to control directories in the
+  :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of exported targets.

+ 37 - 1
Source/cmExportFileGenerator.cxx

@@ -279,7 +279,43 @@ static bool checkInterfaceDirs(const std::string &prepro,
       }
     if (isSubDirectory(li->c_str(), installDir))
       {
-      continue;
+      // The include directory is inside the install tree.  If the
+      // install tree is not inside the source tree or build tree then
+      // fall through to the checks below that the include directory is not
+      // also inside the source tree or build tree.
+      bool shouldContinue =
+          isSubDirectory(installDir, topBinaryDir)
+        || isSubDirectory(installDir, topSourceDir);
+
+      if (!shouldContinue)
+        {
+        switch(target->GetPolicyStatusCMP0052())
+          {
+          case cmPolicies::WARN:
+            {
+            cmOStringStream s;
+            s << target->GetMakefile()->GetPolicies()
+                      ->GetPolicyWarning(cmPolicies::CMP0052) << "\n";
+            s << "Directory:\n    \"" << *li << "\"\nin "
+              "INTERFACE_INCLUDE_DIRECTORIES of target \""
+              << target->GetName() << "\" is a subdirectory of the install "
+              "directory:\n    \"" << installDir << "\"";
+            target->GetMakefile()->IssueMessage(cmake::AUTHOR_WARNING,
+                                                s.str());
+            }
+          case cmPolicies::OLD:
+            shouldContinue = true;
+            break;
+          case cmPolicies::REQUIRED_ALWAYS:
+          case cmPolicies::REQUIRED_IF_USED:
+          case cmPolicies::NEW:
+            break;
+          }
+        }
+      if (shouldContinue)
+        {
+        continue;
+        }
       }
     if (isSubDirectory(li->c_str(), topBinaryDir))
       {

+ 6 - 0
Source/cmPolicies.cxx

@@ -348,6 +348,12 @@ cmPolicies::cmPolicies()
     CMP0051, "CMP0051",
     "List TARGET_OBJECTS in SOURCES target property.",
     3,1,0, cmPolicies::WARN);
+
+  this->DefinePolicy(
+    CMP0052, "CMP0052",
+    "Reject source and build dirs in installed "
+    "INTERFACE_INCLUDE_DIRECTORIES.",
+    3,1,0, cmPolicies::WARN);
 }
 
 cmPolicies::~cmPolicies()

+ 2 - 0
Source/cmPolicies.h

@@ -105,6 +105,8 @@ public:
     CMP0049, ///< Do not expand variables in target source entries
     CMP0050, ///< Disallow add_custom_command SOURCE signatures
     CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
+    CMP0052, ///< Reject source and build dirs in installed
+    /// INTERFACE_INCLUDE_DIRECTORIES
 
     /** \brief Always the last entry.
      *

+ 2 - 1
Source/cmTarget.h

@@ -30,7 +30,8 @@
   F(CMP0038) \
   F(CMP0041) \
   F(CMP0042) \
-  F(CMP0046)
+  F(CMP0046) \
+  F(CMP0052)
 
 class cmake;
 class cmMakefile;

+ 1 - 0
Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt

@@ -16,6 +16,7 @@
    \* CMP0041
    \* CMP0042
    \* CMP0046
+   \* CMP0052
 
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-NEW-stderr.txt

@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+    ".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-NEW-build/foo"
+
+  which is prefixed in the build directory.

+ 1 - 0
Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-result.txt

@@ -0,0 +1 @@
+0

+ 1 - 0
Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-OLD-stderr.txt

@@ -0,0 +1 @@
+^$

+ 1 - 0
Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-result.txt

@@ -0,0 +1 @@
+0

+ 15 - 0
Tests/RunCMake/include_directories/BinInInstallPrefix-CMP0052-WARN-stderr.txt

@@ -0,0 +1,15 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0052 is not set: Reject source and build dirs in installed
+  INTERFACE_INCLUDE_DIRECTORIES.  Run "cmake --help-policy CMP0052" for
+  policy details.  Use the cmake_policy command to set the policy and
+  suppress this warning.
+
+  Directory:
+
+      ".*Tests/RunCMake/include_directories/prefix/BinInInstallPrefix-CMP0052-WARN-build/foo"
+
+  in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory
+  of the install directory:
+
+      ".*Tests/RunCMake/include_directories/prefix"
+This warning is for project developers.  Use -Wno-dev to suppress it.

+ 1 - 1
Tests/RunCMake/include_directories/CMakeLists.txt

@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 2.8.4)
+cmake_minimum_required(VERSION 3.0)
 project(${RunCMake_TEST} CXX)
 include(${RunCMake_TEST}.cmake)

+ 1 - 0
Tests/RunCMake/include_directories/InstallInBinDir-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/include_directories/InstallInBinDir-stderr.txt

@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+    ".*Tests/RunCMake/include_directories/InstallInBinDir-build/foo"
+
+  which is prefixed in the build directory.

+ 1 - 0
Tests/RunCMake/include_directories/InstallInSrcDir-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/include_directories/InstallInSrcDir-stderr.txt

@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+    ".*Tests/RunCMake/include_directories/copy/foo"
+
+  which is prefixed in the source directory.

+ 1 - 0
Tests/RunCMake/include_directories/InstallPrefixInInterface-result.txt

@@ -0,0 +1 @@
+0

+ 1 - 0
Tests/RunCMake/include_directories/InstallPrefixInInterface-stderr.txt

@@ -0,0 +1 @@
+^$

+ 11 - 0
Tests/RunCMake/include_directories/InstallPrefixInInterface.cmake

@@ -0,0 +1,11 @@
+
+project(InstallPrefixInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_include_directories(testTarget INTERFACE "${CMAKE_INSTALL_PREFIX}/foo")
+
+install(TARGETS testTarget EXPORT testTargets
+  DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)

+ 1 - 0
Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-result.txt

@@ -0,0 +1 @@
+0

+ 1 - 0
Tests/RunCMake/include_directories/InstallToPrefixInSrcDirInSource-stderr.txt

@@ -0,0 +1 @@
+^$

+ 1 - 0
Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-result.txt

@@ -0,0 +1 @@
+0

+ 1 - 0
Tests/RunCMake/include_directories/InstallToPrefixInSrcDirOutOfSource-stderr.txt

@@ -0,0 +1 @@
+^$

+ 125 - 0
Tests/RunCMake/include_directories/RunCMakeTest.cmake

@@ -12,3 +12,128 @@ run_cmake(CMP0021)
 run_cmake(install_config)
 run_cmake(incomplete-genex)
 run_cmake(export-NOWARN)
+
+configure_file(
+  "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+  "${RunCMake_BINARY_DIR}/copy/CMakeLists.txt"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/empty.cpp"
+  "${RunCMake_BINARY_DIR}/copy/empty.cpp"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake"
+  "${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface.cmake"
+  COPYONLY
+)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface/prefix")
+set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/copy/SourceDirectoryInInterface")
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/copy")
+run_cmake(InstallInSrcDir)
+unset(RunCMake_TEST_SOURCE_DIR)
+unset(RunCMake_TEST_FILE)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallInBinDir-build/prefix")
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/InstallInBinDir-build")
+set(RunCMake_TEST_FILE "${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface")
+run_cmake(InstallInBinDir)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_FILE)
+
+configure_file(
+  "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+  "${RunCMake_BINARY_DIR}/prefix/src/CMakeLists.txt"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/empty.cpp"
+  "${RunCMake_BINARY_DIR}/prefix/src/empty.cpp"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/SourceDirectoryInInterface.cmake"
+  "${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface.cmake"
+  COPYONLY
+)
+
+foreach(policyStatus "" NEW OLD)
+  if (NOT "${policyStatus}" STREQUAL "")
+    set(policyOption -DCMAKE_POLICY_DEFAULT_CMP0052=${policyStatus})
+  else()
+    unset(policyOption)
+    set(policyStatus WARN)
+  endif()
+  set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/prefix" ${policyOption})
+  # Set the RunCMake_TEST_SOURCE_DIR here to the copy too. This is needed to run
+  # the test suite in-source properly.  Otherwise the install directory would be
+  # a subdirectory or the source directory, which is allowed and tested separately
+  # below.
+  set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/prefix/src")
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/prefix/BinInInstallPrefix-CMP0052-${policyStatus}-build")
+  set(RunCMake_TEST_FILE "${RunCMake_SOURCE_DIR}/BinaryDirectoryInInterface")
+  run_cmake(BinInInstallPrefix-CMP0052-${policyStatus})
+  unset(RunCMake_TEST_BINARY_DIR)
+  unset(RunCMake_TEST_FILE)
+
+  set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/prefix/src/SourceDirectoryInInterface")
+  run_cmake(SrcInInstallPrefix-CMP0052-${policyStatus})
+  unset(RunCMake_TEST_SOURCE_DIR)
+  unset(RunCMake_TEST_FILE)
+endforeach()
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/InstallPrefixInInterface-build/prefix")
+run_cmake(InstallPrefixInInterface)
+
+configure_file(
+  "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+  "${RunCMake_BINARY_DIR}/installToSrc/CMakeLists.txt"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/empty.cpp"
+  "${RunCMake_BINARY_DIR}/installToSrc/empty.cpp"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake"
+  "${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface.cmake"
+  COPYONLY
+)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface/prefix")
+set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/installToSrc/InstallPrefixInInterface")
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrc")
+run_cmake(InstallToPrefixInSrcDirOutOfSource)
+unset(RunCMake_TEST_SOURCE_DIR)
+unset(RunCMake_TEST_FILE)
+
+
+file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/installToSrcInSrc")
+set(RunCMake_TEST_NO_CLEAN ON)
+
+configure_file(
+  "${RunCMake_SOURCE_DIR}/CMakeLists.txt"
+  "${RunCMake_BINARY_DIR}/installToSrcInSrc/CMakeLists.txt"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/empty.cpp"
+  "${RunCMake_BINARY_DIR}/installToSrcInSrc/empty.cpp"
+  COPYONLY
+)
+configure_file(
+  "${RunCMake_SOURCE_DIR}/InstallPrefixInInterface.cmake"
+  "${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface.cmake"
+  COPYONLY
+)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface/prefix")
+set(RunCMake_TEST_FILE "${RunCMake_BINARY_DIR}/installToSrcInSrc/InstallPrefixInInterface")
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc")
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/installToSrcInSrc")
+run_cmake(InstallToPrefixInSrcDirInSource)
+unset(RunCMake_TEST_SOURCE_DIR)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_FILE)
+unset(RunCMake_TEST_NO_CLEAN)

+ 1 - 0
Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-NEW-stderr.txt

@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+  Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+    ".*Tests/RunCMake/include_directories/prefix/src/foo"
+
+  which is prefixed in the source directory.

+ 1 - 0
Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-result.txt

@@ -0,0 +1 @@
+0

+ 1 - 0
Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-OLD-stderr.txt

@@ -0,0 +1 @@
+^$

+ 1 - 0
Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-result.txt

@@ -0,0 +1 @@
+0

+ 15 - 0
Tests/RunCMake/include_directories/SrcInInstallPrefix-CMP0052-WARN-stderr.txt

@@ -0,0 +1,15 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+  Policy CMP0052 is not set: Reject source and build dirs in installed
+  INTERFACE_INCLUDE_DIRECTORIES.  Run "cmake --help-policy CMP0052" for
+  policy details.  Use the cmake_policy command to set the policy and
+  suppress this warning.
+
+  Directory:
+
+      ".*Tests/RunCMake/include_directories/prefix/src/foo"
+
+  in INTERFACE_INCLUDE_DIRECTORIES of target "testTarget" is a subdirectory
+  of the install directory:
+
+      ".*Tests/RunCMake/include_directories/prefix"
+This warning is for project developers.  Use -Wno-dev to suppress it.