소스 검색

File set: Allow absolute CMAKE_INSTALL_INCLUDEDIR

When install(TARGETS) and install(EXPORT) were called with file sets
and an absolute CMAKE_INSTALL_INCLUDEDIR, "${_IMPORT_PREFIX}/" was
still being prepended to the base directory and files, resulting in
incorrect paths. Don't prepend this when absolute paths are used.

Fixes: #25010
Kyle Edwards 2 년 전
부모
커밋
70f36de1e5

+ 14 - 9
Source/cmExportInstallFileGenerator.cxx

@@ -590,10 +590,12 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
   auto cge = ge.Parse(te->FileSetGenerators.at(fileSet)->GetDestination());
 
   for (auto const& config : configs) {
-    auto dest = cmStrCat("${_IMPORT_PREFIX}/",
-                         cmOutputConverter::EscapeForCMake(
-                           cge->Evaluate(gte->LocalGenerator, config, gte),
-                           cmOutputConverter::WrapQuotes::NoWrap));
+    auto unescapedDest = cge->Evaluate(gte->LocalGenerator, config, gte);
+    auto dest = cmOutputConverter::EscapeForCMake(
+      unescapedDest, cmOutputConverter::WrapQuotes::NoWrap);
+    if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
+      dest = cmStrCat("${_IMPORT_PREFIX}/", dest);
+    }
 
     auto const& type = fileSet->GetType();
     // C++ modules do not support interface file sets which are dependent upon
@@ -645,11 +647,14 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
       fileSet->EvaluateFileEntry(directories, files, entry,
                                  gte->LocalGenerator, config, gte);
     }
-    auto dest = cmStrCat("${_IMPORT_PREFIX}/",
-                         cmOutputConverter::EscapeForCMake(
-                           destCge->Evaluate(gte->LocalGenerator, config, gte),
-                           cmOutputConverter::WrapQuotes::NoWrap),
-                         '/');
+    auto unescapedDest = destCge->Evaluate(gte->LocalGenerator, config, gte);
+    auto dest =
+      cmStrCat(cmOutputConverter::EscapeForCMake(
+                 unescapedDest, cmOutputConverter::WrapQuotes::NoWrap),
+               '/');
+    if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
+      dest = cmStrCat("${_IMPORT_PREFIX}/", dest);
+    }
 
     bool const contextSensitive = destCge->GetHadContextSensitiveCondition() ||
       std::any_of(directoryEntries.begin(), directoryEntries.end(),

+ 16 - 0
Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirExport.cmake

@@ -0,0 +1,16 @@
+enable_language(C)
+
+# According to https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html#module:GNUInstallDirs
+# relative CMAKE_INSTALL_<dir> are encouraged, but absolute path's are also allowed.
+# Construct an absolute CMAKE_INSTALL_INCLUDEDIR.
+set(CMAKE_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_PREFIX}/include")
+
+add_library(lib1)
+target_sources(lib1
+    PRIVATE lib1.c
+    PUBLIC FILE_SET HEADERS BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} FILES h1.h)
+# Expect install(TARGETS) to respect absolute CMAKE_INSTALL_INCLUDEDIR
+# when installing the HEADERS.
+# Must not prepend the CMAKE_INSTALL_PREFIX in the <pkg>-config.cmake.
+install(TARGETS lib1 EXPORT lib1-config FILE_SET HEADERS)
+install(EXPORT lib1-config NAMESPACE lib1:: DESTINATION share/lib1)

+ 9 - 0
Tests/RunCMake/target_sources/FileSetAbsoluteInstallIncludeDirImport.cmake

@@ -0,0 +1,9 @@
+enable_language(CXX)
+
+get_filename_component(CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}" DIRECTORY)
+string(APPEND CMAKE_PREFIX_PATH "/FileSetAbsoluteInstallIncludeDirExport-build/install")
+
+find_package(lib1 REQUIRED)
+
+add_executable(exe main.cpp)
+target_link_libraries(exe PRIVATE lib1::lib1)

+ 1 - 0
Tests/RunCMake/target_sources/RunCMakeTest.cmake

@@ -99,3 +99,4 @@ function(run_export_import name)
 endfunction()
 
 run_export_import(FileSet)
+run_export_import(FileSetAbsoluteInstallIncludeDir)