diff options
author | Stephen Kelly <steveire@gmail.com> | 2013-03-24 20:18:17 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2013-03-26 14:45:07 (GMT) |
commit | af81a3c31b206633742eb13d41c54a9bc807ffea (patch) | |
tree | b309b37bc371f153819eeffb909b586eb89b74dc /Source/cmExportFileGenerator.cxx | |
parent | ddbe2e1d7da460684e4d81fc8b3f69510f87b78e (diff) | |
download | CMake-af81a3c31b206633742eb13d41c54a9bc807ffea.zip CMake-af81a3c31b206633742eb13d41c54a9bc807ffea.tar.gz CMake-af81a3c31b206633742eb13d41c54a9bc807ffea.tar.bz2 |
install(EXPORT): Ensure clean INTERFACE_INCLUDE_DIRECTORIES
Check that source and binary directories are not part of the
INTERFACE_INCLUDE_DIRECTORIES for installed IMPORTED targets.
This is limited to directories which do not contain generator
expressions to evaluate. Such paths can only be checked at time
of use of the imported target, which will be done in a follow up
patch.
Diffstat (limited to 'Source/cmExportFileGenerator.cxx')
-rw-r--r-- | Source/cmExportFileGenerator.cxx | 111 |
1 files changed, 111 insertions, 0 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, |