From 70ae6dfd922e53e759ec6a58424dfdbb9c12dee1 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 18 Jun 2013 16:33:33 +0200 Subject: [PATCH] Handle genexes when evaluating INTERFACE_INCLUDE_DIRECTORIES errors. --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0027.rst | 25 +++++++++ Source/cmPolicies.cxx | 5 ++ Source/cmPolicies.h | 2 + Source/cmTarget.cxx | 51 ++++++++++++++++--- Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt | 1 + Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt | 13 +++++ Tests/RunCMake/CMP0027/CMP0027-NEW.cmake | 10 ++++ Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt | 1 + Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt | 13 +++++ Tests/RunCMake/CMP0027/CMP0027-OLD.cmake | 10 ++++ .../RunCMake/CMP0027/CMP0027-WARN-result.txt | 1 + .../RunCMake/CMP0027/CMP0027-WARN-stderr.txt | 18 +++++++ Tests/RunCMake/CMP0027/CMP0027-WARN.cmake | 8 +++ Tests/RunCMake/CMP0027/CMakeLists.txt | 3 ++ Tests/RunCMake/CMP0027/RunCMakeTest.cmake | 5 ++ Tests/RunCMake/CMP0027/empty.cpp | 0 Tests/RunCMake/CMakeLists.txt | 1 + 18 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 Help/policy/CMP0027.rst create mode 100644 Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt create mode 100644 Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt create mode 100644 Tests/RunCMake/CMP0027/CMP0027-NEW.cmake create mode 100644 Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt create mode 100644 Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt create mode 100644 Tests/RunCMake/CMP0027/CMP0027-OLD.cmake create mode 100644 Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt create mode 100644 Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt create mode 100644 Tests/RunCMake/CMP0027/CMP0027-WARN.cmake create mode 100644 Tests/RunCMake/CMP0027/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0027/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/CMP0027/empty.cpp diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index cd91c917e..658620f8e 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -36,3 +36,4 @@ All Policies /policy/CMP0024 /policy/CMP0025 /policy/CMP0026 + /policy/CMP0027 diff --git a/Help/policy/CMP0027.rst b/Help/policy/CMP0027.rst new file mode 100644 index 000000000..352f7b84b --- /dev/null +++ b/Help/policy/CMP0027.rst @@ -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. diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 2ecdb42e5..ffab8e5b4 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -236,6 +236,11 @@ cmPolicies::cmPolicies() CMP0026, "CMP0026", "Disallow use of the LOCATION target property.", 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() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 81a4d99a8..39c2afbca 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -77,6 +77,8 @@ public: CMP0024, ///< Disallow including export() result. CMP0025, ///< Compiler id for Apple Clang is now AppleClang CMP0026, ///< Disallow use of the LOCATION target property. + CMP0027, ///< Conditionally linked imported targets with missing include + /// directories. /** \brief Always the last entry. * diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 5e10e25a1..b6182abfd 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1911,19 +1911,56 @@ static void processIncludeDirectories(cmTarget *tgt, } } std::string usedIncludes; + cmListFileBacktrace lfbt; for(std::vector::iterator li = entryIncludes.begin(); li != entryIncludes.end(); ++li) { - cmTarget *dependentTarget = - mf->FindTargetToUse((*it)->TargetName.c_str()); + std::string targetName = (*it)->TargetName; + std::string evaluatedTargetName; + { + cmGeneratorExpression ge(lfbt); + cmsys::auto_ptr cge = + ge.Parse(targetName); + evaluatedTargetName = cge->Evaluate(mf, config, false, tgt, 0, 0); + } + + cmTarget *dependentTarget = mf->FindTargetToUse(targetName.c_str()); const bool fromImported = dependentTarget && 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; - 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 " "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n" "* The path was deleted, renamed, or moved to another " @@ -1932,7 +1969,7 @@ static void processIncludeDirectories(cmTarget *tgt, "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()); + tgt->GetMakefile()->IssueMessage(messageType, e.str().c_str()); return; } @@ -1941,9 +1978,9 @@ static void processIncludeDirectories(cmTarget *tgt, cmOStringStream e; bool noMessage = false; 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" " \"" << *li << "\""; } diff --git a/Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt b/Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt b/Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt new file mode 100644 index 000000000..5948ec837 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-NEW-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CMP0027/CMP0027-NEW.cmake b/Tests/RunCMake/CMP0027/CMP0027-NEW.cmake new file mode 100644 index 000000000..824508549 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-NEW.cmake @@ -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>) diff --git a/Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt b/Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-OLD-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt b/Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt new file mode 100644 index 000000000..4c2b300b4 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-OLD-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CMP0027/CMP0027-OLD.cmake b/Tests/RunCMake/CMP0027/CMP0027-OLD.cmake new file mode 100644 index 000000000..404217de7 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-OLD.cmake @@ -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>) diff --git a/Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt b/Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-WARN-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt b/Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt new file mode 100644 index 000000000..9bcec3c44 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-WARN-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CMP0027/CMP0027-WARN.cmake b/Tests/RunCMake/CMP0027/CMP0027-WARN.cmake new file mode 100644 index 000000000..8e5f9b518 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMP0027-WARN.cmake @@ -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>) diff --git a/Tests/RunCMake/CMP0027/CMakeLists.txt b/Tests/RunCMake/CMP0027/CMakeLists.txt new file mode 100644 index 000000000..8f85fbf54 --- /dev/null +++ b/Tests/RunCMake/CMP0027/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.4) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/CMP0027/RunCMakeTest.cmake b/Tests/RunCMake/CMP0027/RunCMakeTest.cmake new file mode 100644 index 000000000..1017f01f4 --- /dev/null +++ b/Tests/RunCMake/CMP0027/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0027-NEW) +run_cmake(CMP0027-OLD) +run_cmake(CMP0027-WARN) diff --git a/Tests/RunCMake/CMP0027/empty.cpp b/Tests/RunCMake/CMP0027/empty.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 6d5b07b49..52c86677d 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -54,6 +54,7 @@ endif() add_RunCMake_test(CMP0019) add_RunCMake_test(CMP0022) add_RunCMake_test(CMP0026) +add_RunCMake_test(CMP0027) add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange)