Browse Source

install(EXPORT): Fix SYSTEM include directories relative to install prefix

Fixes: #23393
6ziv 1 month ago
parent
commit
b5793cf41b

+ 34 - 3
Source/cmExportInstallFileGenerator.cxx

@@ -388,9 +388,8 @@ bool cmExportInstallFileGenerator::PopulateInterfaceProperties(
   cmGeneratorTarget const* const gt = targetExport->Target;
 
   std::string includesDestinationDirs;
-  this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,
-                                  cmGeneratorExpression::InstallInterface,
-                                  properties);
+  this->PopulateSystemIncludeDirectoriesInterface(
+    gt, cmGeneratorExpression::InstallInterface, properties);
   this->PopulateIncludeDirectoriesInterface(
     gt, cmGeneratorExpression::InstallInterface, properties, *targetExport,
     includesDestinationDirs);
@@ -519,6 +518,38 @@ void cmExportInstallFileGenerator::PopulateSourcesInterface(
   }
 }
 
+void cmExportInstallFileGenerator::PopulateSystemIncludeDirectoriesInterface(
+  cmGeneratorTarget const* target,
+  cmGeneratorExpression::PreprocessContext preprocessRule,
+  ImportPropertyMap& properties)
+{
+  assert(preprocessRule == cmGeneratorExpression::InstallInterface);
+
+  char const* const propName = "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES";
+  cmValue input = target->GetProperty(propName);
+
+  if (!input) {
+    return;
+  }
+  if (input->empty()) {
+    // Set to empty
+    properties[propName].clear();
+    return;
+  }
+
+  std::string includes = (input ? *input : "");
+  std::string prepro = cmGeneratorExpression::Preprocess(
+    includes, preprocessRule, this->GetImportPrefixWithSlash());
+  if (!prepro.empty()) {
+    this->ResolveTargetsInGeneratorExpressions(prepro, target);
+
+    if (!this->CheckInterfaceDirs(prepro, target, propName)) {
+      return;
+    }
+    properties[propName] = prepro;
+  }
+}
+
 void cmExportInstallFileGenerator::PopulateIncludeDirectoriesInterface(
   cmGeneratorTarget const* target,
   cmGeneratorExpression::PreprocessContext preprocessRule,

+ 4 - 0
Source/cmExportInstallFileGenerator.h

@@ -159,6 +159,10 @@ private:
     cmGeneratorExpression::PreprocessContext preprocessRule,
     ImportPropertyMap& properties, cmTargetExport const& te,
     std::string& includesDestinationDirs);
+  void PopulateSystemIncludeDirectoriesInterface(
+    cmGeneratorTarget const* target,
+    cmGeneratorExpression::PreprocessContext preprocessRule,
+    ImportPropertyMap& properties);
   void PopulateSourcesInterface(
     cmGeneratorTarget const* target,
     cmGeneratorExpression::PreprocessContext preprocessRule,

+ 4 - 0
Tests/RunCMake/install/EXPORT-SystemInclude-check.cmake

@@ -0,0 +1,4 @@
+RunCMake_check_file(export "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/22ecfa717ccadd33cf3e4bcbabcbde6b/foo.cmake" [[
+ *INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/include"
+ *INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/include"
+]])

+ 4 - 0
Tests/RunCMake/install/EXPORT-SystemInclude.cmake

@@ -0,0 +1,4 @@
+add_library(iface INTERFACE)
+target_include_directories(iface SYSTEM INTERFACE "$<INSTALL_INTERFACE:include>")
+install(TARGETS iface EXPORT foo)
+install(EXPORT foo DESTINATION lib/cmake/foo)

+ 2 - 0
Tests/RunCMake/install/RunCMakeTest.cmake

@@ -1,3 +1,4 @@
+cmake_minimum_required(VERSION 4.0)
 include(RunCMake)
 
 # Function to build and install a project.  The latter step *-check.cmake
@@ -87,6 +88,7 @@ run_cmake(EXPORT-OldIFace)
 run_cmake(EXPORT-UnknownExport)
 run_cmake(EXPORT-NamelinkOnly)
 run_cmake(EXPORT-SeparateNamelink)
+run_cmake(EXPORT-SystemInclude)
 run_cmake(EXPORT-TargetTwice)
 run_cmake(EXPORT-InterfaceLinkNoexist)
 run_cmake(CMP0062-NEW)