diff options
author | Brad King <brad.king@kitware.com> | 2013-03-26 18:36:45 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2013-03-26 18:36:45 (GMT) |
commit | b9e4a5abb45055b310032977a9542acff3c14c9b (patch) | |
tree | 21d1ca377f1c2274635647b0a8092bebb602ba07 /Source | |
parent | 169bba41f29169126673b801c8b535a62b0f634d (diff) | |
parent | 28051f1150923804796b4e63e41f6906308788e0 (diff) | |
download | CMake-b9e4a5abb45055b310032977a9542acff3c14c9b.zip CMake-b9e4a5abb45055b310032977a9542acff3c14c9b.tar.gz CMake-b9e4a5abb45055b310032977a9542acff3c14c9b.tar.bz2 |
Merge topic 'error-on-exported-missing-include-dir'
28051f1 Report an error on IMPORTED targets with a faulty INTERFACE
af81a3c install(EXPORT): Ensure clean INTERFACE_INCLUDE_DIRECTORIES
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 111 | ||||
-rw-r--r-- | Source/cmExportFileGenerator.h | 5 | ||||
-rw-r--r-- | Source/cmExportInstallFileGenerator.cxx | 3 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 31 |
4 files changed, 145 insertions, 5 deletions
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 7fd0380..27ec56b 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -24,6 +24,7 @@ #include "cmComputeLinkInformation.h" #include <cmsys/auto_ptr.hxx> +#include <assert.h> //---------------------------------------------------------------------------- cmExportFileGenerator::cmExportFileGenerator() @@ -168,6 +169,116 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, } //---------------------------------------------------------------------------- +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) +{ + const char* installDir = + target->GetMakefile()->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); + const char* topSourceDir = target->GetMakefile()->GetHomeDirectory(); + const char* topBinaryDir = target->GetMakefile()->GetHomeOutputDirectory(); + + 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) + { + continue; + } + if (strncmp(li->c_str(), "${_IMPORT_PREFIX}", 17) == 0) + { + continue; + } + if (!cmSystemTools::FileIsFullPath(li->c_str())) + { + cmOStringStream e; + e << "Target \"" << target->GetName() << "\" " + "INTERFACE_INCLUDE_DIRECTORIES property contains relative path:\n" + " \"" << *li << "\""; + target->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, + e.str().c_str()); + return false; + } + if (isSubDirectory(li->c_str(), installDir)) + { + continue; + } + if (isSubDirectory(li->c_str(), topBinaryDir)) + { + cmOStringStream e; + e << "Target \"" << target->GetName() << "\" " + "INTERFACE_INCLUDE_DIRECTORIES 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; + } + } + } + return true; +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateIncludeDirectoriesInterface( + cmTarget *target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector<std::string> &missingTargets) +{ + assert(preprocessRule == cmGeneratorExpression::InstallInterface); + + const char *propName = "INTERFACE_INCLUDE_DIRECTORIES"; + const char *input = target->GetProperty(propName); + if (!input) + { + return; + } + if (!*input) + { + // Set to empty + properties[propName] = ""; + return; + } + + std::string prepro = cmGeneratorExpression::Preprocess(input, + preprocessRule); + if (!prepro.empty()) + { + this->ResolveTargetsInGeneratorExpressions(prepro, target, + missingTargets); + + if (!checkInterfaceDirs(prepro, target)) + { + return; + } + properties[propName] = prepro; + } +} + +//---------------------------------------------------------------------------- void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, cmTarget *target, cmGeneratorExpression::PreprocessContext preprocessRule, diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 776be61..9f958a2 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -107,6 +107,11 @@ protected: ImportPropertyMap &properties); void GenerateInterfaceProperties(cmTarget *target, std::ostream& os, const ImportPropertyMap &properties); + void PopulateIncludeDirectoriesInterface( + cmTarget *target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector<std::string> &missingTargets); void SetImportLinkInterface(const char* config, std::string const& suffix, cmGeneratorExpression::PreprocessContext preprocessRule, diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 8b8b846..746b0c8 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -120,8 +120,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) ImportPropertyMap properties; - this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", - te, + this->PopulateIncludeDirectoriesInterface(te, cmGeneratorExpression::InstallInterface, properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 53e3cfa..52a2732 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -131,11 +131,13 @@ public: SourceEntriesType SourceEntries; struct IncludeDirectoriesEntry { - IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge) - : ge(cge) + IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, + const std::string &targetName = std::string()) + : ge(cge), TargetName(targetName) {} const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge; std::vector<std::string> CachedIncludes; + const std::string TargetName; }; std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries; std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries; @@ -2818,6 +2820,28 @@ static void processIncludeDirectories(cmTarget *tgt, for(std::vector<std::string>::iterator li = entryIncludes.begin(); li != entryIncludes.end(); ++li) { + cmTarget *dependentTarget = + mf->FindTargetToUse((*it)->TargetName.c_str()); + + const bool fromImported = dependentTarget + && dependentTarget->IsImported(); + + if (fromImported && !cmSystemTools::FileExists(li->c_str())) + { + cmOStringStream e; + e << "Imported target \"" << (*it)->TargetName << "\" includes " + "non-existent path\n \"" << *li << "\"\nin its " + "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n" + "* The path was deleted, renamed, or moved to another " + "location.\n" + "* An install or uninstall procedure did not complete " + "successfully.\n" + "* The installation package was faulty and references files it " + "does not provide.\n"; + tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); + return; + } + if (testIsOff && !cmSystemTools::IsOff(li->c_str())) { cmSystemTools::ConvertToUnixSlashes(*li); @@ -2913,7 +2937,8 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config) it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"); this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back( - new cmTargetInternals::IncludeDirectoriesEntry(cge)); + new cmTargetInternals::IncludeDirectoriesEntry(cge, + it->Value)); } } |