Handle genexes when evaluating INTERFACE_INCLUDE_DIRECTORIES errors.

This commit is contained in:
Stephen Kelly 2013-06-18 16:33:33 +02:00 committed by Brad King
parent 36d8d987c7
commit 70ae6dfd92
18 changed files with 161 additions and 7 deletions

View File

@ -36,3 +36,4 @@ All Policies
/policy/CMP0024 /policy/CMP0024
/policy/CMP0025 /policy/CMP0025
/policy/CMP0026 /policy/CMP0026
/policy/CMP0027

25
Help/policy/CMP0027.rst Normal file
View File

@ -0,0 +1,25 @@
CMP0027
-------
Conditionally linked imported targets with missing include directories.
CMake 2.8.11 introduced introduced the concept of
INTERFACE_INCLUDE_DIRECTORIES, and a check at cmake time that the
entries in the INTERFACE_INCLUDE_DIRECTORIES of an IMPORTED target
actually exist. CMake 2.8.11 also introduced generator expression
support in the target_link_libraries command. However, if an imported
target is linked as a result of a generator expression evaluation, the
entries in the INTERFACE_INCLUDE_DIRECTORIES of that target were not
checked for existence as they should be.
The OLD behavior of this policy is to report a warning if an entry in
the INTERFACE_INCLUDE_DIRECTORIES of a generator-expression
conditionally linked IMPORTED target does not exist.
The NEW behavior of this policy is to report an error if an entry in
the INTERFACE_INCLUDE_DIRECTORIES of a generator-expression
conditionally linked IMPORTED target does not exist.
This policy was introduced in CMake version 3.0.0. CMake version
|release| warns when the policy is not set and uses OLD behavior. Use
the cmake_policy command to set it to OLD or NEW explicitly.

View File

@ -236,6 +236,11 @@ cmPolicies::cmPolicies()
CMP0026, "CMP0026", CMP0026, "CMP0026",
"Disallow use of the LOCATION target property.", "Disallow use of the LOCATION target property.",
3,0,0,0, cmPolicies::WARN); 3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0027, "CMP0027",
"Conditionally linked imported targets with missing include directories.",
3,0,0,0, cmPolicies::WARN);
} }
cmPolicies::~cmPolicies() cmPolicies::~cmPolicies()

View File

@ -77,6 +77,8 @@ public:
CMP0024, ///< Disallow including export() result. CMP0024, ///< Disallow including export() result.
CMP0025, ///< Compiler id for Apple Clang is now AppleClang CMP0025, ///< Compiler id for Apple Clang is now AppleClang
CMP0026, ///< Disallow use of the LOCATION target property. CMP0026, ///< Disallow use of the LOCATION target property.
CMP0027, ///< Conditionally linked imported targets with missing include
/// directories.
/** \brief Always the last entry. /** \brief Always the last entry.
* *

View File

@ -1911,19 +1911,56 @@ static void processIncludeDirectories(cmTarget *tgt,
} }
} }
std::string usedIncludes; std::string usedIncludes;
cmListFileBacktrace lfbt;
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 = std::string targetName = (*it)->TargetName;
mf->FindTargetToUse((*it)->TargetName.c_str()); std::string evaluatedTargetName;
{
cmGeneratorExpression ge(lfbt);
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(targetName);
evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0);
}
cmTarget *dependentTarget = mf->FindTargetToUse(targetName.c_str());
const bool fromImported = dependentTarget const bool fromImported = dependentTarget
&& dependentTarget->IsImported(); && dependentTarget->IsImported();
if (fromImported && !cmSystemTools::FileExists(li->c_str())) cmTarget *evaluatedDependentTarget =
(targetName != evaluatedTargetName)
? mf->FindTargetToUse(evaluatedTargetName.c_str())
: 0;
targetName = evaluatedTargetName;
const bool fromEvaluatedImported = evaluatedDependentTarget
&& evaluatedDependentTarget->IsImported();
if ((fromImported || fromEvaluatedImported)
&& !cmSystemTools::FileExists(li->c_str()))
{ {
cmOStringStream e; cmOStringStream e;
e << "Imported target \"" << (*it)->TargetName << "\" includes " cmake::MessageType messageType = cmake::FATAL_ERROR;
if (fromEvaluatedImported)
{
switch(mf->GetPolicyStatus(cmPolicies::CMP0027))
{
case cmPolicies::WARN:
e << (mf->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0027)) << "\n";
case cmPolicies::OLD:
messageType = cmake::AUTHOR_WARNING;
break;
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
break;
}
}
e << "Imported target \"" << targetName << "\" includes "
"non-existent path\n \"" << *li << "\"\nin its " "non-existent path\n \"" << *li << "\"\nin its "
"INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n" "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n"
"* The path was deleted, renamed, or moved to another " "* The path was deleted, renamed, or moved to another "
@ -1932,7 +1969,7 @@ static void processIncludeDirectories(cmTarget *tgt,
"successfully.\n" "successfully.\n"
"* The installation package was faulty and references files it " "* The installation package was faulty and references files it "
"does not provide.\n"; "does not provide.\n";
tgt->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); tgt->GetMakefile()->IssueMessage(messageType, e.str().c_str());
return; return;
} }
@ -1941,9 +1978,9 @@ static void processIncludeDirectories(cmTarget *tgt,
cmOStringStream e; cmOStringStream e;
bool noMessage = false; bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR; cmake::MessageType messageType = cmake::FATAL_ERROR;
if (!(*it)->TargetName.empty()) if (!targetName.empty())
{ {
e << "Target \"" << (*it)->TargetName << "\" contains relative " e << "Target \"" << targetName << "\" contains relative "
"path in its INTERFACE_INCLUDE_DIRECTORIES:\n" "path in its INTERFACE_INCLUDE_DIRECTORIES:\n"
" \"" << *li << "\""; " \"" << *li << "\"";
} }

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,13 @@
CMake Error in CMakeLists.txt:
Imported target "testTarget" 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.

View File

@ -0,0 +1,10 @@
enable_language(CXX)
cmake_policy(SET CMP0027 NEW)
add_library(testTarget UNKNOWN IMPORTED)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
target_link_libraries(userTarget PRIVATE $<1:testTarget>)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,13 @@
CMake Warning \(dev\) in CMakeLists.txt:
Imported target "testTarget" 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.

View File

@ -0,0 +1,10 @@
enable_language(CXX)
cmake_policy(SET CMP0027 OLD)
add_library(testTarget UNKNOWN IMPORTED)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
target_link_libraries(userTarget PRIVATE $<1:testTarget>)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,18 @@
CMake Warning \(dev\) in CMakeLists.txt:
Policy CMP0027 is not set: Conditionally linked imported targets with
missing include directories. Run "cmake --help-policy CMP0027" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
Imported target "testTarget" 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.

View File

@ -0,0 +1,8 @@
enable_language(CXX)
add_library(testTarget UNKNOWN IMPORTED)
set_property(TARGET testTarget PROPERTY INTERFACE_INCLUDE_DIRECTORIES "/does/not/exist")
add_library(userTarget "${CMAKE_CURRENT_SOURCE_DIR}/empty.cpp")
target_link_libraries(userTarget PRIVATE $<1:testTarget>)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 2.8.4)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)

View File

@ -0,0 +1,5 @@
include(RunCMake)
run_cmake(CMP0027-NEW)
run_cmake(CMP0027-OLD)
run_cmake(CMP0027-WARN)

View File

View File

@ -54,6 +54,7 @@ endif()
add_RunCMake_test(CMP0019) add_RunCMake_test(CMP0019)
add_RunCMake_test(CMP0022) add_RunCMake_test(CMP0022)
add_RunCMake_test(CMP0026) add_RunCMake_test(CMP0026)
add_RunCMake_test(CMP0027)
add_RunCMake_test(CTest) add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange) add_RunCMake_test(CompilerChange)