install(TARGETS): Restore per-export INCLUDES DESTINATION

In commit 55e4753bbb (Refactor cmTargetExport removing
InterfaceIncludeDirecories, 2021-07-20, v3.22.0-rc1~337^2~1) the storage
of `INCLUDES DESTINATION` was moved into each target.  However, a target
may be installed in multiple exports, and their `INCLUDES DESTINATION`
should not be mixed.

Convert the IncludeDirectoriesEntries vector to a map and modify access
function to store the directories lists with respect to cmExportTarget
object. This fixes error when the same target is exported more than once
via different exports and each for consequent export its include
directories list grows. Add a test for this case.

Fixes: #23183
This commit is contained in:
Eugene Shalygin 2022-02-09 18:09:04 +01:00 committed by Brad King
parent b91c4dfb75
commit 83d79636bf
11 changed files with 71 additions and 13 deletions

View File

@ -367,7 +367,8 @@ void cmExportFileGenerator::PopulateSourcesInterface(
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
cmTargetExport const& te)
{
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
@ -377,7 +378,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmGeneratorExpression ge;
std::string dirs = cmGeneratorExpression::Preprocess(
cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(), ";"),
cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(te), ";"),
preprocessRule, true);
this->ReplaceInstallPrefix(dirs);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs);

View File

@ -16,6 +16,7 @@
#include "cmVersionConfig.h"
class cmGeneratorTarget;
class cmTargetExport;
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
@ -146,7 +147,8 @@ protected:
void PopulateIncludeDirectoriesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
cmTargetExport const& te);
void PopulateSourcesInterface(
cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,

View File

@ -86,7 +86,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
ImportPropertyMap properties;
this->PopulateIncludeDirectoriesInterface(
gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
gt, cmGeneratorExpression::InstallInterface, properties, missingTargets,
*te);
this->PopulateSourcesInterface(gt, cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,

View File

@ -683,7 +683,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
te->RuntimeGenerator = runtimeGenerator.get();
te->ObjectsGenerator = objectGenerator.get();
target.AddInstallIncludeDirectories(
cmMakeRange(includesArgs.GetIncludeDirs()));
*te, cmMakeRange(includesArgs.GetIncludeDirs()));
te->NamelinkOnly = namelinkOnly;
helper.Makefile->GetGlobalGenerator()
->GetExportSets()[exports]

View File

@ -191,7 +191,8 @@ public:
cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
std::map<std::string, BTs<std::string>> LanguageStandardProperties;
std::vector<BT<std::string>> IncludeDirectoriesEntries;
std::vector<std::string> InstallIncludeDirectoriesEntries;
std::map<cmTargetExport const*, std::vector<std::string>>
InstallIncludeDirectoriesEntries;
std::vector<BT<std::string>> CompileOptionsEntries;
std::vector<BT<std::string>> CompileFeaturesEntries;
std::vector<BT<std::string>> CompileDefinitionsEntries;
@ -1054,15 +1055,18 @@ std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const
return this->impl->SystemIncludeDirectories;
}
void cmTarget::AddInstallIncludeDirectories(cmStringRange const& incs)
void cmTarget::AddInstallIncludeDirectories(cmTargetExport const& te,
cmStringRange const& incs)
{
std::copy(incs.begin(), incs.end(),
std::back_inserter(this->impl->InstallIncludeDirectoriesEntries));
std::copy(
incs.begin(), incs.end(),
std::back_inserter(this->impl->InstallIncludeDirectoriesEntries[&te]));
}
cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries() const
cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries(
cmTargetExport const& te) const
{
return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries);
return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries[&te]);
}
cmBTStringRange cmTarget::GetIncludeDirectoriesEntries() const

View File

@ -26,6 +26,7 @@ class cmMakefile;
class cmMessenger;
class cmPropertyMap;
class cmSourceFile;
class cmTargetExport;
class cmTargetInternals;
/** \class cmTarget
@ -232,8 +233,10 @@ public:
void AddSystemIncludeDirectories(std::set<std::string> const& incs);
std::set<std::string> const& GetSystemIncludeDirectories() const;
void AddInstallIncludeDirectories(cmStringRange const& incs);
cmStringRange GetInstallIncludeDirectoriesEntries() const;
void AddInstallIncludeDirectories(cmTargetExport const& te,
cmStringRange const& incs);
cmStringRange GetInstallIncludeDirectoriesEntries(
cmTargetExport const& te) const;
BTs<std::string> const* GetLanguageStandardProperty(
const std::string& propertyName) const;

View File

@ -0,0 +1,19 @@
set(pkg1_cmake "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/pkg1/pkg1.cmake")
file(STRINGS "${pkg1_cmake}" pkg1_includes REGEX INTERFACE_INCLUDE_DIRECTORIES)
set(pkg1_expect [[INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg1/inc"]])
if(NOT pkg1_includes MATCHES "${pkg1_expect}")
set(RunCMake_TEST_FAILED "pkg1 has unexpected INTERFACE_INCLUDE_DIRECTORIES line:
${pkg1_includes}
It does not match:
${pkg1_expect}")
endif()
set(pkg2_cmake "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/pkg2/pkg2.cmake")
file(STRINGS "${pkg2_cmake}" pkg2_includes REGEX INTERFACE_INCLUDE_DIRECTORIES)
set(pkg2_expect [[INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg2/inc"]])
if(NOT pkg2_includes MATCHES "${pkg2_expect}")
set(RunCMake_TEST_FAILED "pkg2 has unexpected INTERFACE_INCLUDE_DIRECTORIES line:
${pkg2_includes}
It does not match:
${pkg2_expect}")
endif()

View File

@ -0,0 +1,5 @@
.+
set_target_properties\(pkg1::foo PROPERTIES
.+INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg1/inc"
\)
.+

View File

@ -0,0 +1,5 @@
.+
set_target_properties\(pkg2::foo PROPERTIES
.+INTERFACE_INCLUDE_DIRECTORIES "\${_IMPORT_PREFIX}/pkg2/inc"
\)
.+

View File

@ -0,0 +1,17 @@
enable_language(C)
add_library(foo STATIC empty.c)
install(TARGETS foo
EXPORT pkg1
ARCHIVE DESTINATION pkg1/lib
INCLUDES DESTINATION pkg1/inc
)
install(EXPORT pkg1 DESTINATION pkg1)
install(TARGETS foo
EXPORT pkg2
ARCHIVE DESTINATION pkg2/lib
INCLUDES DESTINATION pkg2/inc
)
install(EXPORT pkg2 DESTINATION pkg2)

View File

@ -82,6 +82,7 @@ run_cmake(EXPORT-OldIFace)
run_cmake(EXPORT-UnknownExport)
run_cmake(EXPORT-NamelinkOnly)
run_cmake(EXPORT-SeparateNamelink)
run_cmake(EXPORT-TargetTwice)
run_cmake(CMP0062-OLD)
run_cmake(CMP0062-NEW)
run_cmake(CMP0062-WARN)