summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2013-03-24 20:18:17 (GMT)
committerBrad King <brad.king@kitware.com>2013-03-26 14:45:07 (GMT)
commitaf81a3c31b206633742eb13d41c54a9bc807ffea (patch)
treeb309b37bc371f153819eeffb909b586eb89b74dc
parentddbe2e1d7da460684e4d81fc8b3f69510f87b78e (diff)
downloadCMake-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.
-rw-r--r--Source/cmExportFileGenerator.cxx111
-rw-r--r--Source/cmExportFileGenerator.h5
-rw-r--r--Source/cmExportInstallFileGenerator.cxx3
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt18
-rw-r--r--Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt1
-rw-r--r--Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt6
-rw-r--r--Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake11
-rw-r--r--Tests/RunCMake/include_directories/RelativePathInInterface-result.txt1
-rw-r--r--Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt5
-rw-r--r--Tests/RunCMake/include_directories/RelativePathInInterface.cmake11
-rw-r--r--Tests/RunCMake/include_directories/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt1
-rw-r--r--Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt6
-rw-r--r--Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake11
-rw-r--r--Tests/RunCMake/include_directories/empty.cpp0
15 files changed, 189 insertions, 4 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/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index cdf67c2..be48483 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -174,9 +174,14 @@ set_property(TARGET testSharedLibRequired
set_property(TARGET testSharedLibRequired APPEND PROPERTY
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
)
+install(FILES
+ "${CMAKE_CURRENT_SOURCE_DIR}/testSharedLibRequired.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/testsharedlibrequired_export.h"
+ DESTINATION include/testSharedLibRequired
+)
set_property(TARGET testSharedLibRequired APPEND PROPERTY
- INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}"
+ INTERFACE_INCLUDE_DIRECTORIES "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/testSharedLibRequired>"
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>"
)
set_property(TARGET testSharedLibRequired
APPEND PROPERTY
@@ -205,6 +210,15 @@ set_property(TARGET testSharedLibDepends APPEND PROPERTY
INTERFACE_INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:testSharedLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
)
+install(FILES
+ "${CMAKE_CURRENT_SOURCE_DIR}/testSharedLibDepends.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/testsharedlibdepends_export.h"
+ DESTINATION include/testSharedLibDepends
+)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/testSharedLibDepends>"
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>"
+)
set_property(TARGET testSharedLibDepends APPEND PROPERTY
LINK_INTERFACE_LIBRARIES
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt
new file mode 100644
index 0000000..0d4379e
--- /dev/null
+++ b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*RunCMake/include_directories/BinaryDirectoryInInterface-build/foo"
+
+ which is prefixed in the build directory.
diff --git a/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake
new file mode 100644
index 0000000..8754540
--- /dev/null
+++ b/Tests/RunCMake/include_directories/BinaryDirectoryInInterface.cmake
@@ -0,0 +1,11 @@
+
+project(BinaryDirectoryInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/foo")
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt b/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/include_directories/RelativePathInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt b/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt
new file mode 100644
index 0000000..f6cdb53
--- /dev/null
+++ b/Tests/RunCMake/include_directories/RelativePathInInterface-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains
+ relative path:
+
+ "foo"
diff --git a/Tests/RunCMake/include_directories/RelativePathInInterface.cmake b/Tests/RunCMake/include_directories/RelativePathInInterface.cmake
new file mode 100644
index 0000000..f2ce54a
--- /dev/null
+++ b/Tests/RunCMake/include_directories/RelativePathInInterface.cmake
@@ -0,0 +1,11 @@
+
+project(RelativePathInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "foo")
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
index ddf268c..bd299fc 100644
--- a/Tests/RunCMake/include_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake
@@ -3,3 +3,6 @@ include(RunCMake)
run_cmake(NotFoundContent)
run_cmake(DebugIncludes)
run_cmake(TID-bad-target)
+run_cmake(SourceDirectoryInInterface)
+run_cmake(BinaryDirectoryInInterface)
+run_cmake(RelativePathInInterface)
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt
new file mode 100644
index 0000000..9346b99
--- /dev/null
+++ b/Tests/RunCMake/include_directories/SourceDirectoryInInterface-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error in CMakeLists.txt:
+ Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains path:
+
+ ".*RunCMake/include_directories/foo"
+
+ which is prefixed in the source directory.
diff --git a/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake b/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake
new file mode 100644
index 0000000..c9a9c45
--- /dev/null
+++ b/Tests/RunCMake/include_directories/SourceDirectoryInInterface.cmake
@@ -0,0 +1,11 @@
+
+project(SourceDirectoryInInterface)
+
+add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
+target_include_directories(testTarget INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/foo")
+
+install(TARGETS testTarget EXPORT testTargets
+ DESTINATION lib
+)
+
+install(EXPORT testTargets DESTINATION lib/cmake)
diff --git a/Tests/RunCMake/include_directories/empty.cpp b/Tests/RunCMake/include_directories/empty.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/include_directories/empty.cpp