diff options
Diffstat (limited to 'Source/cmExportFileGenerator.cxx')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 196 |
1 files changed, 102 insertions, 94 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index ed1e4cb..452eb99 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportFileGenerator.h" +#include <array> #include <cassert> #include <cstring> #include <sstream> @@ -15,7 +16,6 @@ #include "cmFileSet.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" -#include "cmGlobalGenerator.h" #include "cmLinkItem.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" @@ -106,9 +106,8 @@ bool cmExportFileGenerator::GenerateImportFile() return result; } -void cmExportFileGenerator::GenerateImportConfig( - std::ostream& os, const std::string& config, - std::vector<std::string>& missingTargets) +void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, + const std::string& config) { // Construct the property configuration suffix. std::string suffix = "_"; @@ -119,7 +118,7 @@ void cmExportFileGenerator::GenerateImportConfig( } // Generate the per-config target information. - this->GenerateImportTargetsConfig(os, config, suffix, missingTargets); + this->GenerateImportTargetsConfig(os, config, suffix); } void cmExportFileGenerator::PopulateInterfaceProperty( @@ -136,7 +135,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty( const std::string& propName, const std::string& outputName, cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets) + ImportPropertyMap& properties) { cmValue input = target->GetProperty(propName); if (input) { @@ -149,8 +148,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty( std::string prepro = cmGeneratorExpression::Preprocess(*input, preprocessRule); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, target, - missingTargets); + this->ResolveTargetsInGeneratorExpressions(prepro, target); properties[outputName] = prepro; } } @@ -170,23 +168,29 @@ void cmExportFileGenerator::GenerateRequiredCMakeVersion( bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets) + ImportPropertyMap& properties) { if (!target->IsLinkable()) { return false; } - cmValue input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); - if (input) { - std::string prepro = - cmGeneratorExpression::Preprocess(*input, preprocessRule); - if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions( - prepro, target, missingTargets, ReplaceFreeTargets); - properties["INTERFACE_LINK_LIBRARIES"] = prepro; - return true; + static const std::array<std::string, 3> linkIfaceProps = { + { "INTERFACE_LINK_LIBRARIES", "INTERFACE_LINK_LIBRARIES_DIRECT", + "INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE" } + }; + bool hadINTERFACE_LINK_LIBRARIES = false; + for (std::string const& linkIfaceProp : linkIfaceProps) { + if (cmValue input = target->GetProperty(linkIfaceProp)) { + std::string prepro = + cmGeneratorExpression::Preprocess(*input, preprocessRule); + if (!prepro.empty()) { + this->ResolveTargetsInGeneratorExpressions(prepro, target, + ReplaceFreeTargets); + properties[linkIfaceProp] = prepro; + hadINTERFACE_LINK_LIBRARIES = true; + } } } - return false; + return hadINTERFACE_LINK_LIBRARIES; } static bool isSubDirectory(std::string const& a, std::string const& b) @@ -337,7 +341,7 @@ static void prefixItems(std::string& exportDirs) void cmExportFileGenerator::PopulateSourcesInterface( cmGeneratorTarget const* gt, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets) + ImportPropertyMap& properties) { assert(preprocessRule == cmGeneratorExpression::InstallInterface); @@ -356,7 +360,7 @@ void cmExportFileGenerator::PopulateSourcesInterface( std::string prepro = cmGeneratorExpression::Preprocess(*input, preprocessRule, true); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets); + this->ResolveTargetsInGeneratorExpressions(prepro, gt); if (!checkInterfaceDirs(prepro, gt, propName)) { return; @@ -368,8 +372,7 @@ void cmExportFileGenerator::PopulateSourcesInterface( void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets, - cmTargetExport const& te) + ImportPropertyMap& properties, cmTargetExport const& te) { assert(preprocessRule == cmGeneratorExpression::InstallInterface); @@ -416,7 +419,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( std::string prepro = cmGeneratorExpression::Preprocess(includes, preprocessRule, true); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets); + this->ResolveTargetsInGeneratorExpressions(prepro, target); if (!checkInterfaceDirs(prepro, target, propName)) { return; @@ -428,7 +431,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( void cmExportFileGenerator::PopulateLinkDependsInterface( cmGeneratorTarget const* gt, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets) + ImportPropertyMap& properties) { assert(preprocessRule == cmGeneratorExpression::InstallInterface); @@ -447,7 +450,7 @@ void cmExportFileGenerator::PopulateLinkDependsInterface( std::string prepro = cmGeneratorExpression::Preprocess(*input, preprocessRule, true); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets); + this->ResolveTargetsInGeneratorExpressions(prepro, gt); if (!checkInterfaceDirs(prepro, gt, propName)) { return; @@ -459,7 +462,7 @@ void cmExportFileGenerator::PopulateLinkDependsInterface( void cmExportFileGenerator::PopulateLinkDirectoriesInterface( cmGeneratorTarget const* gt, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets) + ImportPropertyMap& properties) { assert(preprocessRule == cmGeneratorExpression::InstallInterface); @@ -478,7 +481,7 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface( std::string prepro = cmGeneratorExpression::Preprocess(*input, preprocessRule, true); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets); + this->ResolveTargetsInGeneratorExpressions(prepro, gt); if (!checkInterfaceDirs(prepro, gt, propName)) { return; @@ -490,10 +493,10 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface( void cmExportFileGenerator::PopulateInterfaceProperty( const std::string& propName, cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets) + ImportPropertyMap& properties) { this->PopulateInterfaceProperty(propName, propName, target, preprocessRule, - properties, missingTargets); + properties); } static void getPropertyContents(cmGeneratorTarget const* tgt, @@ -598,12 +601,12 @@ void cmExportFileGenerator::GenerateInterfaceProperties( } } -bool cmExportFileGenerator::AddTargetNamespace( - std::string& input, cmGeneratorTarget const* target, - std::vector<std::string>& missingTargets) +bool cmExportFileGenerator::AddTargetNamespace(std::string& input, + cmGeneratorTarget const* target, + cmLocalGenerator const* lg) { cmGeneratorTarget::TargetOrString resolved = - target->ResolveTargetReference(input); + target->ResolveTargetReference(input, lg); cmGeneratorTarget* tgt = resolved.Target; if (!tgt) { @@ -619,7 +622,7 @@ bool cmExportFileGenerator::AddTargetNamespace( input = this->Namespace + tgt->GetExportName(); } else { std::string namespacedTarget; - this->HandleMissingTarget(namespacedTarget, missingTargets, target, tgt); + this->HandleMissingTarget(namespacedTarget, target, tgt); if (!namespacedTarget.empty()) { input = namespacedTarget; } else { @@ -631,10 +634,11 @@ bool cmExportFileGenerator::AddTargetNamespace( void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( std::string& input, cmGeneratorTarget const* target, - std::vector<std::string>& missingTargets, FreeTargetsReplace replace) + FreeTargetsReplace replace) { + cmLocalGenerator const* lg = target->GetLocalGenerator(); if (replace == NoReplaceFreeTargets) { - this->ResolveTargetsInGeneratorExpression(input, target, missingTargets); + this->ResolveTargetsInGeneratorExpression(input, target, lg); return; } std::vector<std::string> parts; @@ -643,13 +647,13 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( std::string sep; input.clear(); for (std::string& li : parts) { - if (cmHasLiteralPrefix(li, CMAKE_DIRECTORY_ID_SEP)) { + if (target->IsLinkLookupScope(li, lg)) { continue; } if (cmGeneratorExpression::Find(li) == std::string::npos) { - this->AddTargetNamespace(li, target, missingTargets); + this->AddTargetNamespace(li, target, lg); } else { - this->ResolveTargetsInGeneratorExpression(li, target, missingTargets); + this->ResolveTargetsInGeneratorExpression(li, target, lg); } input += sep + li; sep = ";"; @@ -658,7 +662,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( std::string& input, cmGeneratorTarget const* target, - std::vector<std::string>& missingTargets) + cmLocalGenerator const* lg) { std::string::size_type pos = 0; std::string::size_type lastPos = pos; @@ -682,7 +686,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( std::string targetName = input.substr(nameStartPos, commaPos - nameStartPos); - if (this->AddTargetNamespace(targetName, target, missingTargets)) { + if (this->AddTargetNamespace(targetName, target, lg)) { input.replace(nameStartPos, commaPos - nameStartPos, targetName); } lastPos = nameStartPos + targetName.size() + 1; @@ -704,7 +708,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( "literal."; break; } - if (!this->AddTargetNamespace(targetName, target, missingTargets)) { + if (!this->AddTargetNamespace(targetName, target, lg)) { errorString = "$<TARGET_NAME:...> requires its parameter to be a " "reachable target."; break; @@ -725,7 +729,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( } std::string libName = input.substr(nameStartPos, endPos - nameStartPos); if (cmGeneratorExpression::IsValidTargetName(libName) && - this->AddTargetNamespace(libName, target, missingTargets)) { + this->AddTargetNamespace(libName, target, lg)) { input.replace(nameStartPos, endPos - nameStartPos, libName); } lastPos = nameStartPos + libName.size() + 1; @@ -747,8 +751,7 @@ void cmExportFileGenerator::ReplaceInstallPrefix(std::string& /*unused*/) void cmExportFileGenerator::SetImportLinkInterface( const std::string& config, std::string const& suffix, cmGeneratorExpression::PreprocessContext preprocessRule, - cmGeneratorTarget const* target, ImportPropertyMap& properties, - std::vector<std::string>& missingTargets) + cmGeneratorTarget const* target, ImportPropertyMap& properties) { // Add the transitive link dependencies for this configuration. cmLinkInterface const* iface = target->GetLinkInterface(config, target); @@ -760,7 +763,7 @@ void cmExportFileGenerator::SetImportLinkInterface( // Policy CMP0022 must not be NEW. this->SetImportLinkProperty( suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries, - properties, missingTargets, ImportLinkPropertyTargetNames::Yes); + properties, ImportLinkPropertyTargetNames::Yes); return; } @@ -799,7 +802,7 @@ void cmExportFileGenerator::SetImportLinkInterface( std::string prepro = cmGeneratorExpression::Preprocess(*propContent, preprocessRule); if (!prepro.empty()) { - this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets, + this->ResolveTargetsInGeneratorExpressions(prepro, target, ReplaceFreeTargets); properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro; } @@ -807,8 +810,7 @@ void cmExportFileGenerator::SetImportLinkInterface( void cmExportFileGenerator::SetImportDetailProperties( const std::string& config, std::string const& suffix, - cmGeneratorTarget* target, ImportPropertyMap& properties, - std::vector<std::string>& missingTargets) + cmGeneratorTarget* target, ImportPropertyMap& properties) { // Get the makefile in which to lookup target information. cmMakefile* mf = target->Makefile; @@ -839,12 +841,11 @@ void cmExportFileGenerator::SetImportDetailProperties( target->GetLinkInterface(config, target)) { this->SetImportLinkProperty( suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", iface->Languages, - properties, missingTargets, ImportLinkPropertyTargetNames::No); + properties, ImportLinkPropertyTargetNames::No); - std::vector<std::string> dummy; this->SetImportLinkProperty( suffix, target, "IMPORTED_LINK_DEPENDENT_LIBRARIES", iface->SharedDeps, - properties, dummy, ImportLinkPropertyTargetNames::Yes); + properties, ImportLinkPropertyTargetNames::Yes); if (iface->Multiplicity > 0) { std::string prop = cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix); @@ -885,14 +886,15 @@ template <typename T> void cmExportFileGenerator::SetImportLinkProperty( std::string const& suffix, cmGeneratorTarget const* target, const std::string& propName, std::vector<T> const& entries, - ImportPropertyMap& properties, std::vector<std::string>& missingTargets, - ImportLinkPropertyTargetNames targetNames) + ImportPropertyMap& properties, ImportLinkPropertyTargetNames targetNames) { // Skip the property if there are no entries. if (entries.empty()) { return; } + cmLocalGenerator const* lg = target->GetLocalGenerator(); + // Construct the property value. std::string link_entries; const char* sep = ""; @@ -903,7 +905,7 @@ void cmExportFileGenerator::SetImportLinkProperty( if (targetNames == ImportLinkPropertyTargetNames::Yes) { std::string temp = asString(l); - this->AddTargetNamespace(temp, target, missingTargets); + this->AddTargetNamespace(temp, target, lg); link_entries += temp; } else { link_entries += asString(l); @@ -920,20 +922,23 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os) // Protect that file against use with older CMake versions. /* clang-format off */ os << "# Generated by CMake\n\n"; - os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.6)\n" - << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n" + os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.8)\n" + << " message(FATAL_ERROR \"CMake >= 2.8.0 required\")\n" + << "endif()\n" + << "if(CMAKE_VERSION VERSION_LESS \"2.8.3\")\n" + << " message(FATAL_ERROR \"CMake >= 2.8.3 required\")\n" << "endif()\n"; /* clang-format on */ // Isolate the file policy level. // Support CMake versions as far back as 2.6 but also support using NEW - // policy settings for up to CMake 3.21 (this upper limit may be reviewed + // policy settings for up to CMake 3.22 (this upper limit may be reviewed // and increased from time to time). This reduces the opportunity for CMake // warnings when an older export file is later used with newer CMake // versions. /* clang-format off */ os << "cmake_policy(PUSH)\n" - << "cmake_policy(VERSION 2.6...3.21)\n"; + << "cmake_policy(VERSION 2.8.3...3.22)\n"; /* clang-format on */ } @@ -980,34 +985,36 @@ void cmExportFileGenerator::GenerateExpectedTargetsCode( /* clang-format off */ os << "# Protect against multiple inclusion, which would fail when already " "imported targets are added once more.\n" - "set(_targetsDefined)\n" - "set(_targetsNotDefined)\n" - "set(_expectedTargets)\n" - "foreach(_expectedTarget " << expectedTargets << ")\n" - " list(APPEND _expectedTargets ${_expectedTarget})\n" - " if(NOT TARGET ${_expectedTarget})\n" - " list(APPEND _targetsNotDefined ${_expectedTarget})\n" - " endif()\n" - " if(TARGET ${_expectedTarget})\n" - " list(APPEND _targetsDefined ${_expectedTarget})\n" + "set(_cmake_targets_defined \"\")\n" + "set(_cmake_targets_not_defined \"\")\n" + "set(_cmake_expected_targets \"\")\n" + "foreach(_cmake_expected_target IN ITEMS " << expectedTargets << ")\n" + " list(APPEND _cmake_expected_targets \"${_cmake_expected_target}\")\n" + " if(TARGET \"${_cmake_expected_target}\")\n" + " list(APPEND _cmake_targets_defined \"${_cmake_expected_target}\")\n" + " else()\n" + " list(APPEND _cmake_targets_not_defined \"${_cmake_expected_target}\")\n" " endif()\n" "endforeach()\n" - "if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" - " unset(_targetsDefined)\n" - " unset(_targetsNotDefined)\n" - " unset(_expectedTargets)\n" - " set(CMAKE_IMPORT_FILE_VERSION)\n" + "unset(_cmake_expected_target)\n" + "if(_cmake_targets_defined STREQUAL _cmake_expected_targets)\n" + " unset(_cmake_targets_defined)\n" + " unset(_cmake_targets_not_defined)\n" + " unset(_cmake_expected_targets)\n" + " unset(CMAKE_IMPORT_FILE_VERSION)\n" " cmake_policy(POP)\n" " return()\n" "endif()\n" - "if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n" + "if(NOT _cmake_targets_defined STREQUAL \"\")\n" + " string(REPLACE \";\" \", \" _cmake_targets_defined_text \"${_cmake_targets_defined}\")\n" + " string(REPLACE \";\" \", \" _cmake_targets_not_defined_text \"${_cmake_targets_not_defined}\")\n" " message(FATAL_ERROR \"Some (but not all) targets in this export " - "set were already defined.\\nTargets Defined: ${_targetsDefined}\\n" - "Targets not yet defined: ${_targetsNotDefined}\\n\")\n" + "set were already defined.\\nTargets Defined: ${_cmake_targets_defined_text}\\n" + "Targets not yet defined: ${_cmake_targets_not_defined_text}\\n\")\n" "endif()\n" - "unset(_targetsDefined)\n" - "unset(_targetsNotDefined)\n" - "unset(_expectedTargets)\n" + "unset(_cmake_targets_defined)\n" + "unset(_cmake_targets_not_defined)\n" + "unset(_cmake_expected_targets)\n" "\n\n"; /* clang-format on */ } @@ -1113,10 +1120,9 @@ void cmExportFileGenerator::GenerateImportPropertyCode( << "\n"; } -void cmExportFileGenerator::GenerateMissingTargetsCheckCode( - std::ostream& os, const std::vector<std::string>& missingTargets) +void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os) { - if (missingTargets.empty()) { + if (this->MissingTargets.empty()) { /* clang-format off */ os << "# This file does not depend on other imported targets which have\n" "# been exported from the same project but in a separate " @@ -1131,7 +1137,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode( "foreach(_target "; /* clang-format on */ std::set<std::string> emitted; - for (std::string const& missingTarget : missingTargets) { + for (std::string const& missingTarget : this->MissingTargets) { if (emitted.insert(missingTarget).second) { os << "\"" << missingTarget << "\" "; } @@ -1174,12 +1180,12 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) // but the development package was not installed.). /* clang-format off */ os << "# Loop over all imported files and verify that they actually exist\n" - "foreach(target ${_IMPORT_CHECK_TARGETS} )\n" - " foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n" - " if(NOT EXISTS \"${file}\" )\n" - " message(FATAL_ERROR \"The imported target \\\"${target}\\\"" + "foreach(_cmake_target IN LISTS _cmake_import_check_targets)\n" + " foreach(_cmake_file IN LISTS \"_cmake_import_check_files_for_${_cmake_target}\")\n" + " if(NOT EXISTS \"${_cmake_file}\")\n" + " message(FATAL_ERROR \"The imported target \\\"${_cmake_target}\\\"" " references the file\n" - " \\\"${file}\\\"\n" + " \\\"${_cmake_file}\\\"\n" "but this file does not exist. Possible reasons include:\n" "* The file was deleted, renamed, or moved to another location.\n" "* An install or uninstall procedure did not complete successfully.\n" @@ -1189,9 +1195,11 @@ void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) "\")\n" " endif()\n" " endforeach()\n" - " unset(_IMPORT_CHECK_FILES_FOR_${target})\n" + " unset(_cmake_file)\n" + " unset(\"_cmake_import_check_files_for_${_cmake_target}\")\n" "endforeach()\n" - "unset(_IMPORT_CHECK_TARGETS)\n" + "unset(_cmake_target)\n" + "unset(_cmake_import_check_targets)\n" "\n"; /* clang-format on */ } @@ -1204,9 +1212,9 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode( // Construct the imported target name. std::string targetName = cmStrCat(this->Namespace, target->GetExportName()); - os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName + os << "list(APPEND _cmake_import_check_targets " << targetName << " )\n" - "list(APPEND _IMPORT_CHECK_FILES_FOR_" + "list(APPEND _cmake_import_check_files_for_" << targetName << " "; for (std::string const& li : importedLocations) { |