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
This commit is contained in:
commit
b9e4a5abb4
@ -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",
|
||||||
|
@ -131,11 +131,13 @@ public:
|
|||||||
SourceEntriesType SourceEntries;
|
SourceEntriesType SourceEntries;
|
||||||
|
|
||||||
struct IncludeDirectoriesEntry {
|
struct IncludeDirectoriesEntry {
|
||||||
IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge)
|
IncludeDirectoriesEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge,
|
||||||
: ge(cge)
|
const std::string &targetName = std::string())
|
||||||
|
: ge(cge), TargetName(targetName)
|
||||||
{}
|
{}
|
||||||
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
|
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
|
||||||
std::vector<std::string> CachedIncludes;
|
std::vector<std::string> CachedIncludes;
|
||||||
|
const std::string TargetName;
|
||||||
};
|
};
|
||||||
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
|
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
|
||||||
std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries;
|
std::vector<cmValueWithOrigin> LinkInterfaceIncludeDirectoriesEntries;
|
||||||
@ -2818,6 +2820,28 @@ static void processIncludeDirectories(cmTarget *tgt,
|
|||||||
for(std::vector<std::string>::iterator
|
for(std::vector<std::string>::iterator
|
||||||
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
|
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()))
|
if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
|
||||||
{
|
{
|
||||||
cmSystemTools::ConvertToUnixSlashes(*li);
|
cmSystemTools::ConvertToUnixSlashes(*li);
|
||||||
@ -2913,7 +2937,8 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
|
|||||||
it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>");
|
it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>");
|
||||||
|
|
||||||
this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back(
|
this->Internal->CachedLinkInterfaceIncludeDirectoriesEntries.push_back(
|
||||||
new cmTargetInternals::IncludeDirectoriesEntry(cge));
|
new cmTargetInternals::IncludeDirectoriesEntry(cge,
|
||||||
|
it->Value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>>
|
||||||
|
@ -3,8 +3,6 @@ add_library(foo UNKNOWN IMPORTED)
|
|||||||
add_library(bar UNKNOWN IMPORTED)
|
add_library(bar UNKNOWN IMPORTED)
|
||||||
|
|
||||||
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
|
set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
|
||||||
set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES foo_inc)
|
|
||||||
set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES bar_inc)
|
|
||||||
|
|
||||||
add_executable(user main.cpp)
|
add_executable(user main.cpp)
|
||||||
set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
|
set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
|
||||||
|
@ -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
|
13
Tests/RunCMake/include_directories/ImportedTarget-stderr.txt
Normal file
13
Tests/RunCMake/include_directories/ImportedTarget-stderr.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
CMake Error in CMakeLists.txt:
|
||||||
|
Imported target "imported" includes non-existent path
|
||||||
|
|
||||||
|
"/does/not/exist"
|
||||||
|
|
||||||
|
in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
|
||||||
|
|
||||||
|
\* The path was deleted, renamed, or moved to another location.
|
||||||
|
|
||||||
|
\* An install or uninstall procedure did not complete successfully.
|
||||||
|
|
||||||
|
\* The installation package was faulty and references files it does not
|
||||||
|
provide.
|
9
Tests/RunCMake/include_directories/ImportedTarget.cmake
Normal file
9
Tests/RunCMake/include_directories/ImportedTarget.cmake
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
project(ImportedTarget)
|
||||||
|
|
||||||
|
add_library(testTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
|
||||||
|
|
||||||
|
add_library(imported UNKNOWN IMPORTED)
|
||||||
|
set_property(TARGET imported PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
|
||||||
|
|
||||||
|
target_link_libraries(testTarget imported)
|
@ -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,7 @@ 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)
|
||||||
|
run_cmake(ImportedTarget)
|
||||||
|
@ -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)
|
0
Tests/RunCMake/include_directories/empty.cpp
Normal file
0
Tests/RunCMake/include_directories/empty.cpp
Normal file
Loading…
x
Reference in New Issue
Block a user