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.
This commit is contained in:
parent
ddbe2e1d7d
commit
af81a3c31b
|
@ -24,6 +24,7 @@
|
||||||
#include "cmComputeLinkInformation.h"
|
#include "cmComputeLinkInformation.h"
|
||||||
|
|
||||||
#include <cmsys/auto_ptr.hxx>
|
#include <cmsys/auto_ptr.hxx>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmExportFileGenerator::cmExportFileGenerator()
|
cmExportFileGenerator::cmExportFileGenerator()
|
||||||
|
@ -167,6 +168,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,
|
void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
|
||||||
cmTarget *target,
|
cmTarget *target,
|
||||||
|
|
|
@ -107,6 +107,11 @@ protected:
|
||||||
ImportPropertyMap &properties);
|
ImportPropertyMap &properties);
|
||||||
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
|
||||||
const ImportPropertyMap &properties);
|
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,
|
void SetImportLinkInterface(const char* config, std::string const& suffix,
|
||||||
cmGeneratorExpression::PreprocessContext preprocessRule,
|
cmGeneratorExpression::PreprocessContext preprocessRule,
|
||||||
|
|
|
@ -120,8 +120,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||||
|
|
||||||
ImportPropertyMap properties;
|
ImportPropertyMap properties;
|
||||||
|
|
||||||
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES",
|
this->PopulateIncludeDirectoriesInterface(te,
|
||||||
te,
|
|
||||||
cmGeneratorExpression::InstallInterface,
|
cmGeneratorExpression::InstallInterface,
|
||||||
properties, missingTargets);
|
properties, missingTargets);
|
||||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
|
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS",
|
||||||
|
|
|
@ -174,9 +174,14 @@ set_property(TARGET testSharedLibRequired
|
||||||
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
||||||
INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
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
|
set_property(TARGET testSharedLibRequired APPEND PROPERTY
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
|
INTERFACE_INCLUDE_DIRECTORIES "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/testSharedLibRequired>"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_SOURCE_DIR}>"
|
||||||
)
|
)
|
||||||
set_property(TARGET testSharedLibRequired
|
set_property(TARGET testSharedLibRequired
|
||||||
APPEND PROPERTY
|
APPEND PROPERTY
|
||||||
|
@ -205,6 +210,15 @@ set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||||
INTERFACE_INCLUDE_DIRECTORIES
|
INTERFACE_INCLUDE_DIRECTORIES
|
||||||
$<TARGET_PROPERTY:testSharedLibRequired,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
|
set_property(TARGET testSharedLibDepends APPEND PROPERTY
|
||||||
LINK_INTERFACE_LIBRARIES
|
LINK_INTERFACE_LIBRARIES
|
||||||
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
|
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -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.
|
|
@ -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)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,5 @@
|
||||||
|
CMake Error in CMakeLists.txt:
|
||||||
|
Target "testTarget" INTERFACE_INCLUDE_DIRECTORIES property contains
|
||||||
|
relative path:
|
||||||
|
|
||||||
|
"foo"
|
|
@ -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)
|
|
@ -3,3 +3,6 @@ include(RunCMake)
|
||||||
run_cmake(NotFoundContent)
|
run_cmake(NotFoundContent)
|
||||||
run_cmake(DebugIncludes)
|
run_cmake(DebugIncludes)
|
||||||
run_cmake(TID-bad-target)
|
run_cmake(TID-bad-target)
|
||||||
|
run_cmake(SourceDirectoryInInterface)
|
||||||
|
run_cmake(BinaryDirectoryInInterface)
|
||||||
|
run_cmake(RelativePathInInterface)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -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.
|
|
@ -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)
|
Loading…
Reference in New Issue