diff options
Diffstat (limited to 'Source/cmExportFileGenerator.cxx')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 1174 |
1 files changed, 603 insertions, 571 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 14be5cd47..972f4b9d1 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -1,101 +1,94 @@ -/*============================================================================ - CMake - Cross Platform Makefile Generator - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmExportFileGenerator.h" -#include "cmExportSet.h" +#include "cmAlgorithms.h" +#include "cmComputeLinkInformation.h" #include "cmGeneratedFileStream.h" -#include "cmGlobalGenerator.h" -#include "cmInstallExportGenerator.h" +#include "cmGeneratorTarget.h" +#include "cmLinkItem.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmOutputConverter.h" +#include "cmPolicies.h" +#include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmTargetExport.h" -#include "cmVersion.h" -#include "cmComputeLinkInformation.h" +#include "cmake.h" -#include <cmsys/auto_ptr.hxx> +#include "cm_auto_ptr.hxx" +#include "cmsys/FStream.hxx" #include <assert.h> +#include <sstream> +#include <string.h> +#include <utility> + +static std::string cmExportFileGeneratorEscape(std::string const& str) +{ + // Escape a property value for writing into a .cmake file. + std::string result = cmOutputConverter::EscapeForCMake(str); + // Un-escape variable references generated by our own export code. + cmSystemTools::ReplaceString(result, "\\${_IMPORT_PREFIX}", + "${_IMPORT_PREFIX}"); + cmSystemTools::ReplaceString(result, "\\${CMAKE_IMPORT_LIBRARY_SUFFIX}", + "${CMAKE_IMPORT_LIBRARY_SUFFIX}"); + return result; +} -//---------------------------------------------------------------------------- cmExportFileGenerator::cmExportFileGenerator() { this->AppendMode = false; this->ExportOld = false; } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::AddConfiguration(const char* config) +void cmExportFileGenerator::AddConfiguration(const std::string& config) { this->Configurations.push_back(config); } -//---------------------------------------------------------------------------- void cmExportFileGenerator::SetExportFile(const char* mainFile) { this->MainImportFile = mainFile; - this->FileDir = - cmSystemTools::GetFilenamePath(this->MainImportFile); + this->FileDir = cmSystemTools::GetFilenamePath(this->MainImportFile); this->FileBase = cmSystemTools::GetFilenameWithoutLastExtension(this->MainImportFile); this->FileExt = cmSystemTools::GetFilenameLastExtension(this->MainImportFile); } -//---------------------------------------------------------------------------- +const char* cmExportFileGenerator::GetMainExportFileName() const +{ + return this->MainImportFile.c_str(); +} + bool cmExportFileGenerator::GenerateImportFile() { // Open the output file to generate it. - cmsys::auto_ptr<std::ofstream> foutPtr; - if(this->AppendMode) - { + CM_AUTO_PTR<cmsys::ofstream> foutPtr; + if (this->AppendMode) { // Open for append. - cmsys::auto_ptr<std::ofstream> - ap(new std::ofstream(this->MainImportFile.c_str(), std::ios::app)); + CM_AUTO_PTR<cmsys::ofstream> ap( + new cmsys::ofstream(this->MainImportFile.c_str(), std::ios::app)); foutPtr = ap; - } - else - { + } else { // Generate atomically and with copy-if-different. - cmsys::auto_ptr<cmGeneratedFileStream> - ap(new cmGeneratedFileStream(this->MainImportFile.c_str(), true)); + CM_AUTO_PTR<cmGeneratedFileStream> ap( + new cmGeneratedFileStream(this->MainImportFile.c_str(), true)); ap->SetCopyIfDifferent(true); foutPtr = ap; - } - if(!foutPtr.get() || !*foutPtr) - { + } + if (!foutPtr.get() || !*foutPtr) { std::string se = cmSystemTools::GetLastSystemError(); - cmOStringStream e; - e << "cannot write to file \"" << this->MainImportFile - << "\": " << se; + std::ostringstream e; + e << "cannot write to file \"" << this->MainImportFile << "\": " << se; cmSystemTools::Error(e.str().c_str()); return false; - } + } std::ostream& os = *foutPtr; - // Protect that file against use with older CMake versions. - os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n"; - os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n" - << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n" - << "endif()\n"; - - // Isolate the file policy level. - // We use 2.6 here instead of the current version because newer - // versions of CMake should be able to export files imported by 2.6 - // until the import format changes. - os << "cmake_policy(PUSH)\n" - << "cmake_policy(VERSION 2.6)\n"; - // Start with the import file header. + this->GeneratePolicyHeaderCode(os); this->GenerateImportHeaderCode(os); // Create all the imported targets. @@ -103,737 +96,785 @@ bool cmExportFileGenerator::GenerateImportFile() // End with the import file footer. this->GenerateImportFooterCode(os); - os << "cmake_policy(POP)\n"; + this->GeneratePolicyFooterCode(os); return result; } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, - const char* config, - std::vector<std::string> &missingTargets) +void cmExportFileGenerator::GenerateImportConfig( + std::ostream& os, const std::string& config, + std::vector<std::string>& missingTargets) { // Construct the property configuration suffix. std::string suffix = "_"; - if(config && *config) - { + if (!config.empty()) { suffix += cmSystemTools::UpperCase(config); - } - else - { + } else { suffix += "NOCONFIG"; - } + } // Generate the per-config target information. this->GenerateImportTargetsConfig(os, config, suffix, missingTargets); } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, - cmTarget *target, - ImportPropertyMap &properties) +void cmExportFileGenerator::PopulateInterfaceProperty( + const std::string& propName, cmGeneratorTarget* target, + ImportPropertyMap& properties) { - const char *input = target->GetProperty(propName); - if (input) - { + const char* input = target->GetProperty(propName); + if (input) { properties[propName] = input; - } + } } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, - const char *outputName, - cmTarget *target, - cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap &properties, - std::vector<std::string> &missingTargets) +void cmExportFileGenerator::PopulateInterfaceProperty( + const std::string& propName, const std::string& outputName, + cmGeneratorTarget* target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - const char *input = target->GetProperty(propName); - if (input) - { - if (!*input) - { + const char* input = target->GetProperty(propName); + if (input) { + if (!*input) { // Set to empty properties[outputName] = ""; return; - } + } - std::string prepro = cmGeneratorExpression::Preprocess(input, - preprocessRule); - if (!prepro.empty()) - { + std::string prepro = + cmGeneratorExpression::Preprocess(input, preprocessRule); + if (!prepro.empty()) { this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets); properties[outputName] = prepro; - } } + } } -void cmExportFileGenerator::GenerateRequiredCMakeVersion(std::ostream& os, - const char *versionString) +void cmExportFileGenerator::GenerateRequiredCMakeVersion( + std::ostream& os, const char* versionString) { + /* clang-format off */ os << "if(CMAKE_VERSION VERSION_LESS " << versionString << ")\n" " message(FATAL_ERROR \"This file relies on consumers using " "CMake " << versionString << " or greater.\")\n" "endif()\n\n"; + /* clang-format on */ } -//---------------------------------------------------------------------------- bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty( - cmTarget *target, - cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap &properties, - std::vector<std::string> &missingTargets) + cmGeneratorTarget* target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - if(!target->IsLinkable()) - { + if (!target->IsLinkable()) { return false; - } - const char *input = target->GetProperty("INTERFACE_LINK_LIBRARIES"); - if (input) - { - std::string prepro = cmGeneratorExpression::Preprocess(input, - preprocessRule); - if (!prepro.empty()) - { - this->ResolveTargetsInGeneratorExpressions(prepro, target, - missingTargets, - ReplaceFreeTargets); + } + const char* 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; - } } + } return false; } -//---------------------------------------------------------------------------- static bool isSubDirectory(const char* a, const char* b) { return (cmSystemTools::ComparePath(a, b) || cmSystemTools::IsSubDirectory(a, b)); } -//---------------------------------------------------------------------------- -static bool checkInterfaceDirs(const std::string &prepro, - cmTarget *target) +static bool checkInterfaceDirs(const std::string& prepro, + cmGeneratorTarget* target, + const std::string& prop) { const char* installDir = - target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); - const char* topSourceDir = target->GetMakefile()->GetHomeDirectory(); - const char* topBinaryDir = target->GetMakefile()->GetHomeOutputDirectory(); + target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); + const char* topSourceDir = target->GetLocalGenerator()->GetSourceDirectory(); + const char* topBinaryDir = target->GetLocalGenerator()->GetBinaryDirectory(); std::vector<std::string> parts; cmGeneratorExpression::Split(prepro, parts); const bool inSourceBuild = strcmp(topSourceDir, topBinaryDir) == 0; - for(std::vector<std::string>::iterator li = parts.begin(); - li != parts.end(); ++li) - { - if (cmGeneratorExpression::Find(*li) != std::string::npos) - { + bool hadFatalError = false; + + for (std::vector<std::string>::iterator li = parts.begin(); + li != parts.end(); ++li) { + size_t genexPos = cmGeneratorExpression::Find(*li); + if (genexPos == 0) { continue; + } + cmake::MessageType messageType = cmake::FATAL_ERROR; + std::ostringstream e; + if (genexPos != std::string::npos) { + if (prop == "INTERFACE_INCLUDE_DIRECTORIES") { + switch (target->GetPolicyStatusCMP0041()) { + case cmPolicies::WARN: + messageType = cmake::WARNING; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0041) << "\n"; + break; + case cmPolicies::OLD: + continue; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + hadFatalError = true; + break; // Issue fatal message. + } + } else { + hadFatalError = true; } - if (strncmp(li->c_str(), "${_IMPORT_PREFIX}", 17) == 0) - { + } + if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}")) { continue; - } - if (!cmSystemTools::FileIsFullPath(li->c_str())) - { - cmOStringStream e; - e << "Target \"" << target->GetName() << "\" " - "INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n" + } + if (!cmSystemTools::FileIsFullPath(li->c_str())) { + /* clang-format off */ + e << "Target \"" << target->GetName() << "\" " << prop << + " property contains relative path:\n" " \"" << *li << "\""; - target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, - e.str().c_str()); - return false; + /* clang-format on */ + target->GetLocalGenerator()->IssueMessage(messageType, e.str()); + } + bool inBinary = isSubDirectory(li->c_str(), topBinaryDir); + bool inSource = isSubDirectory(li->c_str(), topSourceDir); + if (isSubDirectory(li->c_str(), installDir)) { + // The include directory is inside the install tree. If the + // install tree is not inside the source tree or build tree then + // fall through to the checks below that the include directory is not + // also inside the source tree or build tree. + bool shouldContinue = + (!inBinary || isSubDirectory(installDir, topBinaryDir)) && + (!inSource || isSubDirectory(installDir, topSourceDir)); + + if (prop == "INTERFACE_INCLUDE_DIRECTORIES") { + if (!shouldContinue) { + switch (target->GetPolicyStatusCMP0052()) { + case cmPolicies::WARN: { + std::ostringstream s; + s << cmPolicies::GetPolicyWarning(cmPolicies::CMP0052) << "\n"; + s << "Directory:\n \"" << *li + << "\"\nin " + "INTERFACE_INCLUDE_DIRECTORIES of target \"" + << target->GetName() << "\" is a subdirectory of the install " + "directory:\n \"" + << installDir << "\"\nhowever it is also " + "a subdirectory of the " + << (inBinary ? "build" : "source") << " tree:\n \"" + << (inBinary ? topBinaryDir : topSourceDir) << "\"" + << std::endl; + target->GetLocalGenerator()->IssueMessage(cmake::AUTHOR_WARNING, + s.str()); + CM_FALLTHROUGH; + } + case cmPolicies::OLD: + shouldContinue = true; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + break; + } + } } - if (isSubDirectory(li->c_str(), installDir)) - { - continue; + if (shouldContinue) { + continue; } - if (isSubDirectory(li->c_str(), topBinaryDir)) - { - cmOStringStream e; - e << "Target \"" << target->GetName() << "\" " - "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n" + } + if (inBinary) { + /* clang-format off */ + e << "Target \"" << target->GetName() << "\" " << prop << + " property contains path:\n" " \"" << *li << "\"\nwhich is prefixed in the build directory."; - target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, - e.str().c_str()); - return false; - } - if (!inSourceBuild) - { - if (isSubDirectory(li->c_str(), topSourceDir)) - { - cmOStringStream e; - e << "Target \"" << target->GetName() << "\" " - "INTERFACE_INCLUDE_DIRECTORIES property contains path:\n" - " \"" << *li << "\"\nwhich is prefixed in the source directory."; - target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, - e.str().c_str()); - return false; - } + /* clang-format on */ + target->GetLocalGenerator()->IssueMessage(messageType, e.str()); + } + if (!inSourceBuild) { + if (inSource) { + e << "Target \"" << target->GetName() << "\" " << prop + << " property contains path:\n" + " \"" + << *li << "\"\nwhich is prefixed in the source directory."; + target->GetLocalGenerator()->IssueMessage(messageType, e.str()); } } - return true; + } + return !hadFatalError; +} + +static void prefixItems(std::string& exportDirs) +{ + std::vector<std::string> entries; + cmGeneratorExpression::Split(exportDirs, entries); + exportDirs = ""; + const char* sep = ""; + for (std::vector<std::string>::const_iterator ei = entries.begin(); + ei != entries.end(); ++ei) { + exportDirs += sep; + sep = ";"; + if (!cmSystemTools::FileIsFullPath(ei->c_str()) && + ei->find("${_IMPORT_PREFIX}") == std::string::npos) { + exportDirs += "${_IMPORT_PREFIX}/"; + } + exportDirs += *ei; + } +} + +void cmExportFileGenerator::PopulateSourcesInterface( + cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector<std::string>& missingTargets) +{ + cmGeneratorTarget* gt = tei->Target; + assert(preprocessRule == cmGeneratorExpression::InstallInterface); + + const char* propName = "INTERFACE_SOURCES"; + const char* input = gt->GetProperty(propName); + + if (!input) { + return; + } + + if (!*input) { + properties[propName] = ""; + return; + } + + std::string prepro = + cmGeneratorExpression::Preprocess(input, preprocessRule, true); + if (!prepro.empty()) { + this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets); + + if (!checkInterfaceDirs(prepro, gt, propName)) { + return; + } + properties[propName] = prepro; + } } -//---------------------------------------------------------------------------- void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( - cmTargetExport *tei, - cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap &properties, - std::vector<std::string> &missingTargets) + cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - cmTarget *target = tei->Target; + cmGeneratorTarget* target = tei->Target; assert(preprocessRule == cmGeneratorExpression::InstallInterface); - const char *propName = "INTERFACE_INCLUDE_DIRECTORIES"; - const char *input = target->GetProperty(propName); + const char* propName = "INTERFACE_INCLUDE_DIRECTORIES"; + const char* input = target->GetProperty(propName); - cmListFileBacktrace lfbt; - cmGeneratorExpression ge(lfbt); + cmGeneratorExpression ge; - std::string dirs = tei->InterfaceIncludeDirectories; + std::string dirs = cmGeneratorExpression::Preprocess( + tei->InterfaceIncludeDirectories, preprocessRule, true); this->ReplaceInstallPrefix(dirs); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs); - std::string exportDirs = cge->Evaluate(target->GetMakefile(), 0, - false, target); - - if (cge->GetHadContextSensitiveCondition()) - { - cmMakefile* mf = target->GetMakefile(); - cmOStringStream e; - e << "Target \"" << target->GetName() << "\" is installed with " - "INCLUDES DESTINATION set to a context sensitive path. Paths which " - "depend on the configuration, policy values or the link interface are " - "not supported. Consider using target_include_directories instead."; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + CM_AUTO_PTR<cmCompiledGeneratorExpression> cge = ge.Parse(dirs); + std::string exportDirs = + cge->Evaluate(target->GetLocalGenerator(), "", false, target); + + if (cge->GetHadContextSensitiveCondition()) { + cmLocalGenerator* lg = target->GetLocalGenerator(); + std::ostringstream e; + e << "Target \"" << target->GetName() + << "\" is installed with " + "INCLUDES DESTINATION set to a context sensitive path. Paths which " + "depend on the configuration, policy values or the link interface " + "are " + "not supported. Consider using target_include_directories instead."; + lg->IssueMessage(cmake::FATAL_ERROR, e.str()); return; - } + } - if (!input && exportDirs.empty()) - { + if (!input && exportDirs.empty()) { return; - } - if ((input && !*input) && exportDirs.empty()) - { + } + if ((input && !*input) && exportDirs.empty()) { // Set to empty properties[propName] = ""; return; - } + } + + prefixItems(exportDirs); - std::string includes = (input?input:""); + std::string includes = (input ? input : ""); const char* sep = input ? ";" : ""; includes += sep + exportDirs; - std::string prepro = cmGeneratorExpression::Preprocess(includes, - preprocessRule, - true); - if (!prepro.empty()) - { - this->ResolveTargetsInGeneratorExpressions(prepro, target, - missingTargets); + std::string prepro = + cmGeneratorExpression::Preprocess(includes, preprocessRule, true); + if (!prepro.empty()) { + this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets); - if (!checkInterfaceDirs(prepro, target)) - { + if (!checkInterfaceDirs(prepro, target, propName)) { return; - } - properties[propName] = prepro; } + properties[propName] = prepro; + } } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, - cmTarget *target, - cmGeneratorExpression::PreprocessContext preprocessRule, - ImportPropertyMap &properties, - std::vector<std::string> &missingTargets) +void cmExportFileGenerator::PopulateInterfaceProperty( + const std::string& propName, cmGeneratorTarget* target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { this->PopulateInterfaceProperty(propName, propName, target, preprocessRule, - properties, missingTargets); + properties, missingTargets); } - -//---------------------------------------------------------------------------- -void getPropertyContents(cmTarget *tgt, const char *prop, - std::set<std::string> &ifaceProperties) +void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop, + std::set<std::string>& ifaceProperties) { - const char *p = tgt->GetProperty(prop); - if (!p) - { + const char* p = tgt->GetProperty(prop); + if (!p) { return; - } + } std::vector<std::string> content; cmSystemTools::ExpandListArgument(p, content); - for (std::vector<std::string>::const_iterator ci = content.begin(); - ci != content.end(); ++ci) - { - ifaceProperties.insert(*ci); - } + ifaceProperties.insert(content.begin(), content.end()); } -//---------------------------------------------------------------------------- -void getCompatibleInterfaceProperties(cmTarget *target, - std::set<std::string> &ifaceProperties, - const char *config) +void getCompatibleInterfaceProperties(cmGeneratorTarget* target, + std::set<std::string>& ifaceProperties, + const std::string& config) { - cmComputeLinkInformation *info = target->GetLinkInformation(config); + if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) { + // object libraries have no link information, so nothing to compute + return; + } - if (!info) - { - cmMakefile* mf = target->GetMakefile(); - cmOStringStream e; - e << "Exporting the target \"" << target->GetName() << "\" is not " + cmComputeLinkInformation* info = target->GetLinkInformation(config); + + if (!info) { + cmLocalGenerator* lg = target->GetLocalGenerator(); + std::ostringstream e; + e << "Exporting the target \"" << target->GetName() + << "\" is not " "allowed since its linker language cannot be determined"; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + lg->IssueMessage(cmake::FATAL_ERROR, e.str()); return; - } + } - const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); + const cmComputeLinkInformation::ItemVector& deps = info->GetItems(); - for(cmComputeLinkInformation::ItemVector::const_iterator li = - deps.begin(); - li != deps.end(); ++li) - { - if (!li->Target) - { + for (cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); + li != deps.end(); ++li) { + if (!li->Target) { continue; - } - getPropertyContents(li->Target, - "COMPATIBLE_INTERFACE_BOOL", + } + getPropertyContents(li->Target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); - getPropertyContents(li->Target, - "COMPATIBLE_INTERFACE_STRING", + getPropertyContents(li->Target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); - } + getPropertyContents(li->Target, "COMPATIBLE_INTERFACE_NUMBER_MIN", + ifaceProperties); + getPropertyContents(li->Target, "COMPATIBLE_INTERFACE_NUMBER_MAX", + ifaceProperties); + } } -//---------------------------------------------------------------------------- void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( - cmTarget *target, - ImportPropertyMap &properties) + cmGeneratorTarget* gtarget, ImportPropertyMap& properties) { - this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL", - target, properties); - this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING", - target, properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL", gtarget, + properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING", gtarget, + properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MIN", gtarget, + properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MAX", gtarget, + properties); std::set<std::string> ifaceProperties; - getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); - getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); + getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); + getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); + getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_NUMBER_MIN", + ifaceProperties); + getPropertyContents(gtarget, "COMPATIBLE_INTERFACE_NUMBER_MAX", + ifaceProperties); - getCompatibleInterfaceProperties(target, ifaceProperties, 0); + if (gtarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + getCompatibleInterfaceProperties(gtarget, ifaceProperties, ""); - std::vector<std::string> configNames; - target->GetMakefile()->GetConfigurations(configNames); + std::vector<std::string> configNames; + gtarget->Target->GetMakefile()->GetConfigurations(configNames); - for (std::vector<std::string>::const_iterator ci = configNames.begin(); - ci != configNames.end(); ++ci) - { - getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str()); + for (std::vector<std::string>::const_iterator ci = configNames.begin(); + ci != configNames.end(); ++ci) { + getCompatibleInterfaceProperties(gtarget, ifaceProperties, *ci); } + } for (std::set<std::string>::const_iterator it = ifaceProperties.begin(); - it != ifaceProperties.end(); ++it) - { - this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(), - target, properties); - } + it != ifaceProperties.end(); ++it) { + this->PopulateInterfaceProperty("INTERFACE_" + *it, gtarget, properties); + } } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target, - std::ostream& os, - const ImportPropertyMap &properties) +void cmExportFileGenerator::GenerateInterfaceProperties( + const cmGeneratorTarget* target, std::ostream& os, + const ImportPropertyMap& properties) { - if (!properties.empty()) - { + if (!properties.empty()) { std::string targetName = this->Namespace; targetName += target->GetExportName(); os << "set_target_properties(" << targetName << " PROPERTIES\n"; - for(ImportPropertyMap::const_iterator pi = properties.begin(); - pi != properties.end(); ++pi) - { - os << " " << pi->first << " \"" << pi->second << "\"\n"; - } - os << ")\n\n"; + for (ImportPropertyMap::const_iterator pi = properties.begin(); + pi != properties.end(); ++pi) { + os << " " << pi->first << " " << cmExportFileGeneratorEscape(pi->second) + << "\n"; } + os << ")\n\n"; + } } -//---------------------------------------------------------------------------- -bool -cmExportFileGenerator::AddTargetNamespace(std::string &input, - cmTarget* target, - std::vector<std::string> &missingTargets) +bool cmExportFileGenerator::AddTargetNamespace( + std::string& input, cmGeneratorTarget* target, + std::vector<std::string>& missingTargets) { - cmMakefile *mf = target->GetMakefile(); + cmLocalGenerator* lg = target->GetLocalGenerator(); - cmTarget *tgt = mf->FindTargetToUse(input.c_str()); - if (!tgt) - { + cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(input); + if (!tgt) { return false; - } + } - if(tgt->IsImported()) - { + if (tgt->IsImported()) { return true; - } - if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end()) - { + } + if (this->ExportedTargets.find(tgt) != this->ExportedTargets.end()) { input = this->Namespace + tgt->GetExportName(); - } - else - { + } else { std::string namespacedTarget; - this->HandleMissingTarget(namespacedTarget, missingTargets, - mf, target, tgt); - if (!namespacedTarget.empty()) - { + this->HandleMissingTarget(namespacedTarget, missingTargets, target, tgt); + if (!namespacedTarget.empty()) { input = namespacedTarget; - } } + } return true; } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( - std::string &input, - cmTarget* target, - std::vector<std::string> &missingTargets, - FreeTargetsReplace replace) +void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( + std::string& input, cmGeneratorTarget* target, + std::vector<std::string>& missingTargets, FreeTargetsReplace replace) { - if (replace == NoReplaceFreeTargets) - { + if (replace == NoReplaceFreeTargets) { this->ResolveTargetsInGeneratorExpression(input, target, missingTargets); return; - } + } std::vector<std::string> parts; cmGeneratorExpression::Split(input, parts); std::string sep; input = ""; - for(std::vector<std::string>::iterator li = parts.begin(); - li != parts.end(); ++li) - { - if (cmGeneratorExpression::Find(*li) == std::string::npos) - { + for (std::vector<std::string>::iterator li = parts.begin(); + li != parts.end(); ++li) { + if (cmGeneratorExpression::Find(*li) == std::string::npos) { this->AddTargetNamespace(*li, target, missingTargets); - } - else - { - this->ResolveTargetsInGeneratorExpression( - *li, - target, - missingTargets); - } + } else { + this->ResolveTargetsInGeneratorExpression(*li, target, missingTargets); + } input += sep + *li; sep = ";"; - } + } } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator::ResolveTargetsInGeneratorExpression( - std::string &input, - cmTarget* target, - std::vector<std::string> &missingTargets) +void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( + std::string& input, cmGeneratorTarget* target, + std::vector<std::string>& missingTargets) { std::string::size_type pos = 0; std::string::size_type lastPos = pos; - cmMakefile *mf = target->GetMakefile(); - - while((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != input.npos) - { - std::string::size_type nameStartPos = pos + - sizeof("$<TARGET_PROPERTY:") - 1; - std::string::size_type closePos = input.find(">", nameStartPos); - std::string::size_type commaPos = input.find(",", nameStartPos); + while ((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != + std::string::npos) { + std::string::size_type nameStartPos = + pos + sizeof("$<TARGET_PROPERTY:") - 1; + std::string::size_type closePos = input.find('>', nameStartPos); + std::string::size_type commaPos = input.find(',', nameStartPos); std::string::size_type nextOpenPos = input.find("$<", nameStartPos); - if (commaPos == input.npos // Implied 'this' target - || closePos == input.npos // Imcomplete expression. - || closePos < commaPos // Implied 'this' target - || nextOpenPos < commaPos) // Non-literal - { + if (commaPos == std::string::npos // Implied 'this' target + || closePos == std::string::npos // Imcomplete expression. + || closePos < commaPos // Implied 'this' target + || nextOpenPos < commaPos) // Non-literal + { lastPos = nameStartPos; continue; - } + } - std::string targetName = input.substr(nameStartPos, - commaPos - nameStartPos); + std::string targetName = + input.substr(nameStartPos, commaPos - nameStartPos); - if (this->AddTargetNamespace(targetName, target, missingTargets)) - { + if (this->AddTargetNamespace(targetName, target, missingTargets)) { input.replace(nameStartPos, commaPos - nameStartPos, targetName); - } - lastPos = nameStartPos + targetName.size() + 1; } + lastPos = nameStartPos + targetName.size() + 1; + } std::string errorString; pos = 0; lastPos = pos; - while((pos = input.find("$<TARGET_NAME:", lastPos)) != input.npos) - { + while ((pos = input.find("$<TARGET_NAME:", lastPos)) != std::string::npos) { std::string::size_type nameStartPos = pos + sizeof("$<TARGET_NAME:") - 1; - std::string::size_type endPos = input.find(">", nameStartPos); - if (endPos == input.npos) - { + std::string::size_type endPos = input.find('>', nameStartPos); + if (endPos == std::string::npos) { errorString = "$<TARGET_NAME:...> expression incomplete"; break; - } - std::string targetName = input.substr(nameStartPos, - endPos - nameStartPos); - if(targetName.find("$<") != input.npos) - { + } + std::string targetName = input.substr(nameStartPos, endPos - nameStartPos); + if (targetName.find("$<") != std::string::npos) { errorString = "$<TARGET_NAME:...> requires its parameter to be a " "literal."; break; - } - if (!this->AddTargetNamespace(targetName, target, missingTargets)) - { + } + if (!this->AddTargetNamespace(targetName, target, missingTargets)) { errorString = "$<TARGET_NAME:...> requires its parameter to be a " "reachable target."; break; - } + } input.replace(pos, endPos - pos + 1, targetName); lastPos = endPos; + } + + pos = 0; + lastPos = pos; + while (errorString.empty() && + (pos = input.find("$<LINK_ONLY:", lastPos)) != std::string::npos) { + std::string::size_type nameStartPos = pos + sizeof("$<LINK_ONLY:") - 1; + std::string::size_type endPos = input.find('>', nameStartPos); + if (endPos == std::string::npos) { + errorString = "$<LINK_ONLY:...> expression incomplete"; + break; } + std::string libName = input.substr(nameStartPos, endPos - nameStartPos); + if (cmGeneratorExpression::IsValidTargetName(libName) && + this->AddTargetNamespace(libName, target, missingTargets)) { + input.replace(nameStartPos, endPos - nameStartPos, libName); + } + lastPos = nameStartPos + libName.size() + 1; + } this->ReplaceInstallPrefix(input); - if (!errorString.empty()) - { - mf->IssueMessage(cmake::FATAL_ERROR, errorString); - } + if (!errorString.empty()) { + target->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, errorString); + } } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator::ReplaceInstallPrefix(std::string &) +void cmExportFileGenerator::ReplaceInstallPrefix(std::string& /*unused*/) { // Do nothing } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::SetImportLinkInterface(const char* config, std::string const& suffix, - cmGeneratorExpression::PreprocessContext preprocessRule, - cmTarget* target, ImportPropertyMap& properties, - std::vector<std::string>& missingTargets) +void cmExportFileGenerator::SetImportLinkInterface( + const std::string& config, std::string const& suffix, + cmGeneratorExpression::PreprocessContext preprocessRule, + cmGeneratorTarget* target, ImportPropertyMap& properties, + std::vector<std::string>& missingTargets) { // Add the transitive link dependencies for this configuration. - cmTarget::LinkInterface const* iface = target->GetLinkInterface(config, - target); - if (!iface) - { + cmLinkInterface const* iface = target->GetLinkInterface(config, target); + if (!iface) { return; - } + } - if (iface->ImplementationIsInterface) - { + if (iface->ImplementationIsInterface) { // Policy CMP0022 must not be NEW. this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", iface->Libraries, properties, missingTargets); return; - } + } - const char *propContent; + const char* propContent; - if (const char *prop_suffixed = target->GetProperty( - ("LINK_INTERFACE_LIBRARIES" + suffix).c_str())) - { + if (const char* prop_suffixed = + target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) { propContent = prop_suffixed; - } - else if (const char *prop = target->GetProperty( - "LINK_INTERFACE_LIBRARIES")) - { + } else if (const char* prop = + target->GetProperty("LINK_INTERFACE_LIBRARIES")) { propContent = prop; - } - else - { + } else { return; - } + } const bool newCMP0022Behavior = - target->GetPolicyStatusCMP0022() != cmPolicies::WARN - && target->GetPolicyStatusCMP0022() != cmPolicies::OLD; - - if(newCMP0022Behavior && !this->ExportOld) - { - cmMakefile *mf = target->GetMakefile(); - cmOStringStream e; - e << "Target \"" << target->GetName() << "\" has policy CMP0022 enabled, " + target->GetPolicyStatusCMP0022() != cmPolicies::WARN && + target->GetPolicyStatusCMP0022() != cmPolicies::OLD; + + if (newCMP0022Behavior && !this->ExportOld) { + cmLocalGenerator* lg = target->GetLocalGenerator(); + std::ostringstream e; + e << "Target \"" << target->GetName() + << "\" has policy CMP0022 enabled, " "but also has old-style LINK_INTERFACE_LIBRARIES properties " "populated, but it was exported without the " "EXPORT_LINK_INTERFACE_LIBRARIES to export the old-style properties"; - mf->IssueMessage(cmake::FATAL_ERROR, e.str()); + lg->IssueMessage(cmake::FATAL_ERROR, e.str()); return; - } + } - if (!*propContent) - { + if (!*propContent) { properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = ""; return; - } + } - std::string prepro = cmGeneratorExpression::Preprocess(propContent, - preprocessRule); - if (!prepro.empty()) - { - this->ResolveTargetsInGeneratorExpressions(prepro, target, - missingTargets, + std::string prepro = + cmGeneratorExpression::Preprocess(propContent, preprocessRule); + if (!prepro.empty()) { + this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets, ReplaceFreeTargets); properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro; - } + } } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::SetImportDetailProperties(const char* config, std::string const& suffix, - cmTarget* target, ImportPropertyMap& properties, - std::vector<std::string>& missingTargets - ) +void cmExportFileGenerator::SetImportDetailProperties( + const std::string& config, std::string const& suffix, + cmGeneratorTarget* target, ImportPropertyMap& properties, + std::vector<std::string>& missingTargets) { // Get the makefile in which to lookup target information. - cmMakefile* mf = target->GetMakefile(); + cmMakefile* mf = target->Makefile; // Add the soname for unix shared libraries. - if(target->GetType() == cmTarget::SHARED_LIBRARY || - target->GetType() == cmTarget::MODULE_LIBRARY) - { - // Check whether this is a DLL platform. - bool dll_platform = - (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW")); - if(!dll_platform) - { + if (target->GetType() == cmStateEnums::SHARED_LIBRARY || + target->GetType() == cmStateEnums::MODULE_LIBRARY) { + if (!target->IsDLLPlatform()) { std::string prop; std::string value; - if(target->HasSOName(config)) - { - if(mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) - { + if (target->HasSOName(config)) { + if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { value = this->InstallNameDir(target, config); - } + } prop = "IMPORTED_SONAME"; value += target->GetSOName(config); - } - else - { + } else { prop = "IMPORTED_NO_SONAME"; value = "TRUE"; - } + } prop += suffix; properties[prop] = value; - } } + } // Add the transitive link dependencies for this configuration. - if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config, - target)) - { + if (cmLinkInterface const* iface = + target->GetLinkInterface(config, target)) { this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", iface->Languages, properties, missingTargets); + std::vector<std::string> dummy; this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_DEPENDENT_LIBRARIES", - iface->SharedDeps, properties, missingTargets); - if(iface->Multiplicity > 0) - { + iface->SharedDeps, properties, dummy); + if (iface->Multiplicity > 0) { std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; prop += suffix; - cmOStringStream m; + std::ostringstream m; m << iface->Multiplicity; properties[prop] = m.str(); - } } + } } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::SetImportLinkProperty(std::string const& suffix, - cmTarget* target, - const char* propName, - std::vector<std::string> const& libs, - ImportPropertyMap& properties, - std::vector<std::string>& missingTargets - ) +template <typename T> +void cmExportFileGenerator::SetImportLinkProperty( + std::string const& suffix, cmGeneratorTarget* target, + const std::string& propName, std::vector<T> const& entries, + ImportPropertyMap& properties, std::vector<std::string>& missingTargets) { - // Skip the property if there are no libraries. - if(libs.empty()) - { + // Skip the property if there are no entries. + if (entries.empty()) { return; - } + } // Construct the property value. - std::string link_libs; + std::string link_entries; const char* sep = ""; - for(std::vector<std::string>::const_iterator li = libs.begin(); - li != libs.end(); ++li) - { + for (typename std::vector<T>::const_iterator li = entries.begin(); + li != entries.end(); ++li) { // Separate this from the previous entry. - link_libs += sep; + link_entries += sep; sep = ";"; std::string temp = *li; this->AddTargetNamespace(temp, target, missingTargets); - link_libs += temp; - } + link_entries += temp; + } // Store the property. std::string prop = propName; prop += suffix; - properties[prop] = link_libs; + properties[prop] = link_entries; } +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.5)\n" + << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n" + << "endif()\n"; + /* clang-format on */ + + // Isolate the file policy level. + // We use 2.6 here instead of the current version because newer + // versions of CMake should be able to export files imported by 2.6 + // until the import format changes. + /* clang-format off */ + os << "cmake_policy(PUSH)\n" + << "cmake_policy(VERSION 2.6)\n"; + /* clang-format on */ +} + +void cmExportFileGenerator::GeneratePolicyFooterCode(std::ostream& os) +{ + os << "cmake_policy(POP)\n"; +} -//---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os, - const char* config) + const std::string& config) { os << "#----------------------------------------------------------------\n" << "# Generated CMake target import file"; - if(config) - { + if (!config.empty()) { os << " for configuration \"" << config << "\".\n"; - } - else - { + } else { os << ".\n"; - } + } os << "#----------------------------------------------------------------\n" << "\n"; this->GenerateImportVersionCode(os); } -//---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os) { os << "# Commands beyond this point should not need to know the version.\n" << "set(CMAKE_IMPORT_FILE_VERSION)\n"; } -//---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os) { // Store an import file format version. This will let us change the // format later while still allowing old import files to work. + /* clang-format off */ os << "# Commands may need to know the format version.\n" << "set(CMAKE_IMPORT_FILE_VERSION 1)\n" << "\n"; + /* clang-format on */ } -//---------------------------------------------------------------------------- -void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os, - const std::string &expectedTargets) +void cmExportFileGenerator::GenerateExpectedTargetsCode( + std::ostream& os, const std::string& expectedTargets) { + /* clang-format off */ os << "# Protect against multiple inclusion, which would fail when already " "imported targets are added once more.\n" "set(_targetsDefined)\n" @@ -849,6 +890,9 @@ void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os, " endif()\n" "endforeach()\n" "if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" + " unset(_targetsDefined)\n" + " unset(_targetsNotDefined)\n" + " unset(_expectedTargets)\n" " set(CMAKE_IMPORT_FILE_VERSION)\n" " cmake_policy(POP)\n" " return()\n" @@ -862,11 +906,10 @@ void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os, "unset(_targetsNotDefined)\n" "unset(_expectedTargets)\n" "\n\n"; + /* clang-format on */ } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::GenerateImportTargetCode(std::ostream& os, cmTarget* target) +void cmExportFileGenerator::GenerateImportTargetCode( + std::ostream& os, const cmGeneratorTarget* target) { // Construct the imported target name. std::string targetName = this->Namespace; @@ -875,62 +918,58 @@ cmExportFileGenerator // Create the imported target. os << "# Create imported target " << targetName << "\n"; - switch(target->GetType()) - { - case cmTarget::EXECUTABLE: + switch (target->GetType()) { + case cmStateEnums::EXECUTABLE: os << "add_executable(" << targetName << " IMPORTED)\n"; break; - case cmTarget::STATIC_LIBRARY: + case cmStateEnums::STATIC_LIBRARY: os << "add_library(" << targetName << " STATIC IMPORTED)\n"; break; - case cmTarget::SHARED_LIBRARY: + case cmStateEnums::SHARED_LIBRARY: os << "add_library(" << targetName << " SHARED IMPORTED)\n"; break; - case cmTarget::MODULE_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: os << "add_library(" << targetName << " MODULE IMPORTED)\n"; break; - case cmTarget::UNKNOWN_LIBRARY: + case cmStateEnums::UNKNOWN_LIBRARY: os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n"; break; - default: // should never happen + case cmStateEnums::OBJECT_LIBRARY: + os << "add_library(" << targetName << " OBJECT IMPORTED)\n"; break; - } + case cmStateEnums::INTERFACE_LIBRARY: + os << "add_library(" << targetName << " INTERFACE IMPORTED)\n"; + break; + default: // should never happen + break; + } // Mark the imported executable if it has exports. - if(target->IsExecutableWithExports()) - { + if (target->IsExecutableWithExports()) { os << "set_property(TARGET " << targetName << " PROPERTY ENABLE_EXPORTS 1)\n"; - } + } // Mark the imported library if it is a framework. - if(target->IsFrameworkOnApple()) - { - os << "set_property(TARGET " << targetName - << " PROPERTY FRAMEWORK 1)\n"; - } + if (target->IsFrameworkOnApple()) { + os << "set_property(TARGET " << targetName << " PROPERTY FRAMEWORK 1)\n"; + } // Mark the imported executable if it is an application bundle. - if(target->IsAppBundleOnApple()) - { + if (target->IsAppBundleOnApple()) { os << "set_property(TARGET " << targetName << " PROPERTY MACOSX_BUNDLE 1)\n"; - } + } - if (target->IsCFBundleOnApple()) - { - os << "set_property(TARGET " << targetName - << " PROPERTY BUNDLE 1)\n"; - } + if (target->IsCFBundleOnApple()) { + os << "set_property(TARGET " << targetName << " PROPERTY BUNDLE 1)\n"; + } os << "\n"; } -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::GenerateImportPropertyCode(std::ostream& os, const char* config, - cmTarget* target, - ImportPropertyMap const& properties) +void cmExportFileGenerator::GenerateImportPropertyCode( + std::ostream& os, const std::string& config, cmGeneratorTarget const* target, + ImportPropertyMap const& properties) { // Construct the imported target name. std::string targetName = this->Namespace; @@ -942,49 +981,46 @@ cmExportFileGenerator << config << "\"\n"; os << "set_property(TARGET " << targetName << " APPEND PROPERTY IMPORTED_CONFIGURATIONS "; - if(config && *config) - { + if (!config.empty()) { os << cmSystemTools::UpperCase(config); - } - else - { + } else { os << "NOCONFIG"; - } + } os << ")\n"; os << "set_target_properties(" << targetName << " PROPERTIES\n"; - for(ImportPropertyMap::const_iterator pi = properties.begin(); - pi != properties.end(); ++pi) - { - os << " " << pi->first << " \"" << pi->second << "\"\n"; - } + for (ImportPropertyMap::const_iterator pi = properties.begin(); + pi != properties.end(); ++pi) { + os << " " << pi->first << " " << cmExportFileGeneratorEscape(pi->second) + << "\n"; + } os << " )\n" << "\n"; } - -//---------------------------------------------------------------------------- -void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, - const std::vector<std::string>& missingTargets) +void cmExportFileGenerator::GenerateMissingTargetsCheckCode( + std::ostream& os, const std::vector<std::string>& missingTargets) { - if (missingTargets.empty()) - { + if (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 " "export set.\n\n"; + /* clang-format on */ return; - } + } + /* clang-format off */ os << "# Make sure the targets which have been exported in some other \n" "# export set exist.\n" "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" "foreach(_target "; + /* clang-format on */ std::set<std::string> emitted; - for(unsigned int i=0; i<missingTargets.size(); ++i) - { - if (emitted.insert(missingTargets[i]).second) - { - os << "\"" << missingTargets[i] << "\" "; - } + for (unsigned int i = 0; i < missingTargets.size(); ++i) { + if (emitted.insert(missingTargets[i]).second) { + os << "\"" << missingTargets[i] << "\" "; } + } + /* clang-format off */ os << ")\n" " if(NOT TARGET \"${_target}\" )\n" " set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets \"" @@ -1008,12 +1044,10 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, "endif()\n" "unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n" "\n"; + /* clang-format on */ } - -//---------------------------------------------------------------------------- -void -cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) +void cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) { // Add code which verifies at cmake time that the file which is being // imported actually exists on disk. This should in theory always be theory @@ -1022,6 +1056,7 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) // the non-development package, something similar happened to me without // on SUSE with a mysql pkg-config file, which claimed everything is fine, // 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" @@ -1042,33 +1077,30 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) "endforeach()\n" "unset(_IMPORT_CHECK_TARGETS)\n" "\n"; + /* clang-format on */ } - -//---------------------------------------------------------------------------- -void -cmExportFileGenerator -::GenerateImportedFileChecksCode(std::ostream& os, cmTarget* target, - ImportPropertyMap const& properties, - const std::set<std::string>& importedLocations) +void cmExportFileGenerator::GenerateImportedFileChecksCode( + std::ostream& os, cmGeneratorTarget* target, + ImportPropertyMap const& properties, + const std::set<std::string>& importedLocations) { // Construct the imported target name. std::string targetName = this->Namespace; targetName += target->GetExportName(); - os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n" - "list(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " "; + os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName + << " )\n" + "list(APPEND _IMPORT_CHECK_FILES_FOR_" + << targetName << " "; - for(std::set<std::string>::const_iterator li = importedLocations.begin(); - li != importedLocations.end(); - ++li) - { + for (std::set<std::string>::const_iterator li = importedLocations.begin(); + li != importedLocations.end(); ++li) { ImportPropertyMap::const_iterator pi = properties.find(*li); - if (pi != properties.end()) - { - os << "\"" << pi->second << "\" "; - } + if (pi != properties.end()) { + os << cmExportFileGeneratorEscape(pi->second) << " "; } + } os << ")\n\n"; } |