Browse Source

fileapi: Fix codemodel target install destination for cross-dir rules

Since commit e89ad0f94e (install: Allow installing targets created in
another directory, 2018-06-18, v3.13.0-rc1~407^2) we support calling
`install(TARGETS)` for targets created in another directory.  However,
install generators are associated with the directory in which the call
to `install()` appears.  This may not be the same directory in which the
target is defined.  Record in each target the list of install generators
it has.

Fixes: #19546
Brad King 6 years ago
parent
commit
d70a0f8681

+ 3 - 6
Source/cmFileAPICodemodel.cxx

@@ -1025,12 +1025,9 @@ Json::Value Target::DumpInstallPrefix()
 Json::Value Target::DumpInstallDestinations()
 {
   Json::Value destinations = Json::arrayValue;
-  auto installGens = this->GT->Makefile->GetInstallGenerators();
-  for (auto iGen : installGens) {
-    auto itGen = dynamic_cast<cmInstallTargetGenerator*>(iGen);
-    if (itGen != nullptr && itGen->GetTarget() == this->GT) {
-      destinations.append(this->DumpInstallDestination(itGen));
-    }
+  auto installGens = this->GT->Target->GetInstallGenerators();
+  for (auto itGen : installGens) {
+    destinations.append(this->DumpInstallDestination(itGen));
   }
   return destinations;
 }

+ 3 - 1
Source/cmInstallCommand.cxx

@@ -43,11 +43,13 @@ static cmInstallTargetGenerator* CreateInstallTargetGenerator(
   target.SetHaveInstallRule(true);
   const char* component = namelink ? args.GetNamelinkComponent().c_str()
                                    : args.GetComponent().c_str();
-  return new cmInstallTargetGenerator(
+  auto g = new cmInstallTargetGenerator(
     target.GetName(), destination.c_str(), impLib,
     args.GetPermissions().c_str(), args.GetConfigurations(), component,
     message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
     backtrace);
+  target.AddInstallGenerator(g);
+  return g;
 }
 
 static cmInstallTargetGenerator* CreateInstallTargetGenerator(

+ 12 - 0
Source/cmTarget.cxx

@@ -177,6 +177,7 @@ public:
   std::vector<cmCustomCommand> PreBuildCommands;
   std::vector<cmCustomCommand> PreLinkCommands;
   std::vector<cmCustomCommand> PostBuildCommands;
+  std::vector<cmInstallTargetGenerator*> InstallGenerators;
   std::set<std::string> SystemIncludeDirectories;
   cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
   std::vector<std::string> IncludeDirectoriesEntries;
@@ -857,6 +858,17 @@ void cmTarget::SetHaveInstallRule(bool hir)
   impl->HaveInstallRule = hir;
 }
 
+void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g)
+{
+  impl->InstallGenerators.emplace_back(g);
+}
+
+std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators()
+  const
+{
+  return impl->InstallGenerators;
+}
+
 bool cmTarget::GetIsGeneratorProvided() const
 {
   return impl->IsGeneratorProvided;

+ 4 - 0
Source/cmTarget.h

@@ -20,6 +20,7 @@
 
 class cmCustomCommand;
 class cmGlobalGenerator;
+class cmInstallTargetGenerator;
 class cmMakefile;
 class cmMessenger;
 class cmPropertyMap;
@@ -146,6 +147,9 @@ public:
   bool GetHaveInstallRule() const;
   void SetHaveInstallRule(bool hir);
 
+  void AddInstallGenerator(cmInstallTargetGenerator* g);
+  std::vector<cmInstallTargetGenerator*> const& GetInstallGenerators() const;
+
   /**
    * Get/Set whether this target was auto-created by a generator.
    */

+ 34 - 1
Tests/RunCMake/FileAPI/codemodel-v2-check.py

@@ -2087,7 +2087,40 @@ def gen_check_targets(c, g, inSource):
             ],
             "build": "^cxx$",
             "source": "^cxx$",
-            "install": None,
+            "install": {
+                "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+                "destinations": [
+                    {
+                        "path": "bin",
+                        "backtrace": [
+                            {
+                                "file": "^codemodel-v2\\.cmake$",
+                                "line": 37,
+                                "command": "install",
+                                "hasParent": True,
+                            },
+                            {
+                                "file": "^codemodel-v2\\.cmake$",
+                                "line": None,
+                                "command": None,
+                                "hasParent": True,
+                            },
+                            {
+                                "file": "^CMakeLists\\.txt$",
+                                "line": 3,
+                                "command": "include",
+                                "hasParent": True,
+                            },
+                            {
+                                "file": "^CMakeLists\\.txt$",
+                                "line": None,
+                                "command": None,
+                                "hasParent": False,
+                            },
+                        ],
+                    },
+                ],
+            },
             "link": {
                 "language": "CXX",
                 "lto": None,

+ 2 - 0
Tests/RunCMake/FileAPI/codemodel-v2.cmake

@@ -33,3 +33,5 @@ if(_ipo)
   set_property(TARGET c_static_lib PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
   file(WRITE "${CMAKE_BINARY_DIR}/ipo_enabled.txt" "")
 endif()
+
+install(TARGETS cxx_exe)