瀏覽代碼

Merge topic 'file-set-build-export'

9ee47188c0 cmExportBuildFileGenerator: handle genex-wrapped source paths
60fab8a6e0 cmInstallCommand: tweak error message

Acked-by: Kitware Robot <[email protected]>
Merge-request: !7182
Brad King 3 年之前
父節點
當前提交
49c96c6508

+ 85 - 8
Source/cmExportBuildFileGenerator.cxx

@@ -2,6 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmExportBuildFileGenerator.h"
 
+#include <algorithm>
 #include <map>
 #include <memory>
 #include <set>
@@ -15,7 +16,6 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
-#include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -357,16 +357,93 @@ std::string cmExportBuildFileGenerator::InstallNameDir(
   return install_name_dir;
 }
 
+namespace {
+bool EntryIsContextSensitive(
+  const std::unique_ptr<cmCompiledGeneratorExpression>& cge)
+{
+  return cge->GetHadContextSensitiveCondition();
+}
+}
+
 std::string cmExportBuildFileGenerator::GetFileSetDirectories(
-  cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
+  cmGeneratorTarget* gte, cmFileSet* fileSet, cmTargetExport* /*te*/)
 {
-  return cmOutputConverter::EscapeForCMake(
-    cmJoin(fileSet->GetDirectoryEntries(), ";"));
+  std::vector<std::string> resultVector;
+
+  auto configs =
+    gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+  auto directoryEntries = fileSet->CompileDirectoryEntries();
+
+  for (auto const& config : configs) {
+    auto directories = fileSet->EvaluateDirectoryEntries(
+      directoryEntries, gte->LocalGenerator, config, gte);
+
+    bool const contextSensitive =
+      std::any_of(directoryEntries.begin(), directoryEntries.end(),
+                  EntryIsContextSensitive);
+
+    for (auto const& directory : directories) {
+      auto dest = cmOutputConverter::EscapeForCMake(
+        directory, cmOutputConverter::WrapQuotes::NoWrap);
+
+      if (contextSensitive && configs.size() != 1) {
+        resultVector.push_back(
+          cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
+      } else {
+        resultVector.push_back(cmStrCat('"', dest, '"'));
+        break;
+      }
+    }
+  }
+
+  return cmJoin(resultVector, " ");
 }
 
-std::string cmExportBuildFileGenerator::GetFileSetFiles(
-  cmGeneratorTarget* /*gte*/, cmFileSet* fileSet, cmTargetExport* /*te*/)
+std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
+                                                        cmFileSet* fileSet,
+                                                        cmTargetExport* /*te*/)
 {
-  return cmOutputConverter::EscapeForCMake(
-    cmJoin(fileSet->GetFileEntries(), ";"));
+  std::vector<std::string> resultVector;
+
+  auto configs =
+    gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
+  auto fileEntries = fileSet->CompileFileEntries();
+  auto directoryEntries = fileSet->CompileDirectoryEntries();
+
+  for (auto const& config : configs) {
+    auto directories = fileSet->EvaluateDirectoryEntries(
+      directoryEntries, gte->LocalGenerator, config, gte);
+
+    std::map<std::string, std::vector<std::string>> files;
+    for (auto const& entry : fileEntries) {
+      fileSet->EvaluateFileEntry(directories, files, entry,
+                                 gte->LocalGenerator, config, gte);
+    }
+
+    bool const contextSensitive =
+      std::any_of(directoryEntries.begin(), directoryEntries.end(),
+                  EntryIsContextSensitive) ||
+      std::any_of(fileEntries.begin(), fileEntries.end(),
+                  EntryIsContextSensitive);
+
+    for (auto const& it : files) {
+      for (auto const& filename : it.second) {
+        auto escapedFile = cmOutputConverter::EscapeForCMake(
+          filename, cmOutputConverter::WrapQuotes::NoWrap);
+        if (contextSensitive && configs.size() != 1) {
+          resultVector.push_back(
+            cmStrCat("\"$<$<CONFIG:", config, ">:", escapedFile, ">\""));
+        } else {
+          resultVector.push_back(cmStrCat('"', escapedFile, '"'));
+        }
+      }
+    }
+
+    if (!(contextSensitive && configs.size() != 1)) {
+      break;
+    }
+  }
+
+  return cmJoin(resultVector, " ");
 }

+ 3 - 3
Source/cmInstallCommand.cxx

@@ -742,9 +742,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
                   [=](const cmInstallCommandFileSetArguments& fileSetArg)
                     -> bool { return fileSetArg.GetFileSet() == name; });
               })) {
-          status.SetError(cmStrCat(
-            "TARGETS target ", target.GetName(),
-            " is exported but not all of its file sets are installed"));
+          status.SetError(cmStrCat("TARGETS target ", target.GetName(),
+                                   " is exported but not all of its interface "
+                                   "file sets are installed"));
           return false;
         }
 

+ 45 - 11
Tests/RunCMake/target_sources/FileSetImport.cmake

@@ -19,20 +19,54 @@ include("${export_build_dir}/install/lib/cmake/export.cmake")
 assert_prop_eq(export::lib1 HEADER_SETS "")
 assert_prop_eq(export::lib1 INTERFACE_HEADER_SETS "HEADERS;b;c;d;dir3;e;f;g")
 assert_prop_eq(export::lib1 HEADER_SET "${CMAKE_CURRENT_SOURCE_DIR}/error.c")
-assert_prop_eq(export::lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
+else ()
+  assert_prop_eq(export::lib1 HEADER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}")
+endif ()
 assert_prop_eq(export::lib1 HEADER_SET_b "${CMAKE_CURRENT_SOURCE_DIR}/h2.h")
-assert_prop_eq(export::lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR}")
-assert_prop_eq(export::lib1 HEADER_SET_c "$<1:dir/dir.h>")
-assert_prop_eq(export::lib1 HEADER_DIRS_c "$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>")
-assert_prop_eq(export::lib1 HEADER_SET_d "${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>/empty.h")
-assert_prop_eq(export::lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR}")
-assert_prop_eq(export::lib1 HEADER_SET_e "${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>/empty2.h")
-assert_prop_eq(export::lib1 HEADER_DIRS_e "${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>")
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
+else ()
+  assert_prop_eq(export::lib1 HEADER_DIRS_b "${CMAKE_CURRENT_SOURCE_DIR}")
+endif ()
+assert_prop_eq(export::lib1 HEADER_SET_c "${CMAKE_CURRENT_SOURCE_DIR}/dir/dir.h")
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_DIRS_c "${CMAKE_CURRENT_SOURCE_DIR}/dir;${CMAKE_CURRENT_SOURCE_DIR}/dir")
+else ()
+  assert_prop_eq(export::lib1 HEADER_DIRS_c "${CMAKE_CURRENT_SOURCE_DIR}/dir")
+endif ()
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_SET_d "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug/empty.h>;$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release/empty.h>")
+  assert_prop_eq(export::lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
+else ()
+  assert_prop_eq(export::lib1 HEADER_SET_d "${CMAKE_CURRENT_SOURCE_DIR}/debug/empty.h")
+  assert_prop_eq(export::lib1 HEADER_DIRS_d "${CMAKE_CURRENT_SOURCE_DIR}")
+endif ()
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_SET_e "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug/empty2.h>;$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release/empty2.h>")
+  assert_prop_eq(export::lib1 HEADER_DIRS_e "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug>;$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release>")
+else ()
+  assert_prop_eq(export::lib1 HEADER_SET_e "${CMAKE_CURRENT_SOURCE_DIR}/debug/empty2.h")
+  assert_prop_eq(export::lib1 HEADER_DIRS_e "${CMAKE_CURRENT_SOURCE_DIR}/debug")
+endif ()
 assert_prop_eq(export::lib1 HEADER_SET_f "${CMAKE_CURRENT_SOURCE_DIR}/empty3.h")
-assert_prop_eq(export::lib1 HEADER_DIRS_f "${CMAKE_CURRENT_SOURCE_DIR}")
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_DIRS_f "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}")
+else ()
+  assert_prop_eq(export::lib1 HEADER_DIRS_f "${CMAKE_CURRENT_SOURCE_DIR}")
+endif ()
 assert_prop_eq(export::lib1 HEADER_SET_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1/file1.h;${CMAKE_CURRENT_SOURCE_DIR}/dir2/file2.h")
-assert_prop_eq(export::lib1 HEADER_DIRS_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2")
-assert_prop_eq(export::lib1 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR};$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2;${CMAKE_CURRENT_SOURCE_DIR}/dir3;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir2>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>")
+if (_multi_config)
+  assert_prop_eq(export::lib1 HEADER_DIRS_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir1")
+else ()
+  assert_prop_eq(export::lib1 HEADER_DIRS_g "${CMAKE_CURRENT_SOURCE_DIR}/dir1")
+endif ()
+if (_multi_config)
+  assert_prop_eq(export::lib1 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR};$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2;${CMAKE_CURRENT_SOURCE_DIR}/dir3;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/debug>>;$<BUILD_INTERFACE:$<$<CONFIG:Release>:${CMAKE_CURRENT_SOURCE_DIR}/release>>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>")
+else ()
+  assert_prop_eq(export::lib1 INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR};$<1:${CMAKE_CURRENT_SOURCE_DIR}/dir>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/$<IF:$<CONFIG:Debug>,debug,release>;${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/dir1;${CMAKE_CURRENT_SOURCE_DIR}/dir2;${CMAKE_CURRENT_SOURCE_DIR}/dir3;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/debug>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir1>;$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dir3>")
+endif ()
 
 assert_prop_eq(install::lib1 HEADER_SETS "")
 assert_prop_eq(install::lib1 INTERFACE_HEADER_SETS "HEADERS;b;c;d;dir3;e;f;g")

+ 2 - 2
Tests/RunCMake/target_sources/FileSetInstallMissingSetsInterface-stderr.txt

@@ -1,5 +1,5 @@
 ^CMake Error at FileSetInstallMissingSetsInterface\.cmake:[0-9]+ \(install\):
-  install TARGETS target lib1 is exported but not all of its file sets are
-  installed
+  install TARGETS target lib1 is exported but not all of its interface file
+  sets are installed
 Call Stack \(most recent call first\):
   CMakeLists\.txt:[0-9]+ \(include\)$