summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2013-03-26 18:36:45 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2013-03-26 18:36:45 (GMT)
commitb9e4a5abb45055b310032977a9542acff3c14c9b (patch)
tree21d1ca377f1c2274635647b0a8092bebb602ba07 /Source
parent169bba41f29169126673b801c8b535a62b0f634d (diff)
parent28051f1150923804796b4e63e41f6906308788e0 (diff)
downloadCMake-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.cxx111
-rw-r--r--Source/cmExportFileGenerator.h5
-rw-r--r--Source/cmExportInstallFileGenerator.cxx3
-rw-r--r--Source/cmTarget.cxx31
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));
}
}