From d70a0f8681919713940d254f9e23141f69f68c31 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 31 Jul 2019 15:17:45 -0400 Subject: 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 --- Source/cmFileAPICodemodel.cxx | 9 +++---- Source/cmInstallCommand.cxx | 4 +++- Source/cmTarget.cxx | 12 ++++++++++ Source/cmTarget.h | 4 ++++ Tests/RunCMake/FileAPI/codemodel-v2-check.py | 35 +++++++++++++++++++++++++++- Tests/RunCMake/FileAPI/codemodel-v2.cmake | 2 ++ 6 files changed, 58 insertions(+), 8 deletions(-) diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 0fb166a..6025025 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/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(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; } diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index dba4bbb..c9e6923 100644 --- a/Source/cmInstallCommand.cxx +++ b/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( diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index cd67586..a67122c 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -177,6 +177,7 @@ public: std::vector PreBuildCommands; std::vector PreLinkCommands; std::vector PostBuildCommands; + std::vector InstallGenerators; std::set SystemIncludeDirectories; cmTarget::LinkLibraryVectorType OriginalLinkLibraries; std::vector 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 const& cmTarget::GetInstallGenerators() + const +{ + return impl->InstallGenerators; +} + bool cmTarget::GetIsGeneratorProvided() const { return impl->IsGeneratorProvided; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index fdcca47..2bd9e6d 100644 --- a/Source/cmTarget.h +++ b/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 const& GetInstallGenerators() const; + /** * Get/Set whether this target was auto-created by a generator. */ diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py index 18b9347..3096358 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py +++ b/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, diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake index 72073d5..c98a84c 100644 --- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake +++ b/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) -- cgit v0.12