AddDependencies: new policy requires dependencies to exist

Added new policy CMP0046 which requires dependencies added by
add_dependencies() to actually exist.
This commit is contained in:
Nils Gladitz 2014-01-12 12:58:04 +01:00
parent cb7af7af44
commit 0bf6f13b1d
22 changed files with 140 additions and 2 deletions

View File

@ -97,3 +97,4 @@ All Policies
/policy/CMP0043
/policy/CMP0044
/policy/CMP0045
/policy/CMP0046

17
Help/policy/CMP0046.rst Normal file
View File

@ -0,0 +1,17 @@
CMP0046
-------
Error on non-existent dependency in add_dependencies.
CMake 2.8.12 and lower silently ignored non-existent dependencies
listed in the :command:`add_dependencies` command.
The OLD behavior for this policy is to silently ignore non-existent
dependencies. The NEW behavior for this policy is to report an error
if non-existent dependencies are listed in the :command:`add_dependencies`
command.
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

@ -46,7 +46,7 @@ bool cmAddDependenciesCommand
++s; // skip over target_name
for (; s != args.end(); ++s)
{
target->AddUtility(s->c_str());
target->AddUtility(s->c_str(), this->Makefile);
}
}
else

View File

@ -343,6 +343,45 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
cmTarget const* dependee =
depender->GetMakefile()->FindTargetToUse(dependee_name);
if(!dependee && !linking &&
(depender->GetType() != cmTarget::GLOBAL_TARGET))
{
cmMakefile *makefile = depender->GetMakefile();
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
bool issueMessage = false;
switch(makefile->GetPolicyStatus(cmPolicies::CMP0046))
{
case cmPolicies::WARN:
issueMessage = true;
case cmPolicies::OLD:
break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
issueMessage = true;
messageType = cmake::FATAL_ERROR;
}
if(issueMessage)
{
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
cmOStringStream e;
e << (makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0046)) << "\n";
e << "The dependency target \"" << dependee_name
<< "\" of target \"" << depender->GetName() << "\" does not exist.";
cmListFileBacktrace nullBacktrace;
cmListFileBacktrace const* backtrace =
depender->GetUtilityBacktrace(dependee_name);
if(!backtrace)
{
backtrace = &nullBacktrace;
}
cm->IssueMessage(messageType, e.str(), *backtrace);
}
}
// Skip targets that will not really be linked. This is probably a
// name conflict between an external library and an executable
// within the project.

View File

@ -331,6 +331,11 @@ cmPolicies::cmPolicies()
CMP0045, "CMP0045",
"Error on non-existent target in get_target_property.",
3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0046, "CMP0046",
"Error on non-existent dependency in add_dependencies.",
3,0,0,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()

View File

@ -99,6 +99,7 @@ public:
CMP0043, ///< Ignore COMPILE_DEFINITIONS_<Config> properties
CMP0044, ///< Case sensitive <LANG>_COMPILER_ID generator expressions
CMP0045, ///< Error on non-existent target in get_target_property
CMP0046, ///< Error on non-existent dependency in add_dependencies
/** \brief Always the last entry.
*

View File

@ -401,6 +401,26 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->SetPropertyDefault("JOB_POOL_LINK", 0);
}
//----------------------------------------------------------------------------
void cmTarget::AddUtility(const char *u, cmMakefile *makefile)
{
this->Utilities.insert(u);
if(makefile)
{
makefile->GetBacktrace(UtilityBacktraces[u]);
}
}
//----------------------------------------------------------------------------
cmListFileBacktrace const* cmTarget::GetUtilityBacktrace(const char *u) const
{
std::map<cmStdString, cmListFileBacktrace>::const_iterator i =
this->UtilityBacktraces.find(u);
if(i == this->UtilityBacktraces.end()) return 0;
return &i->second;
}
//----------------------------------------------------------------------------
void cmTarget::FinishConfigure()
{

View File

@ -242,9 +242,10 @@ public:
* name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
* commands. It is not a full path nor does it have an extension.
*/
void AddUtility(const char* u) { this->Utilities.insert(u);}
void AddUtility(const char* u, cmMakefile *makefile = 0);
///! Get the utilities used by this target
std::set<cmStdString>const& GetUtilities() const { return this->Utilities; }
cmListFileBacktrace const* GetUtilityBacktrace(const char* u) const;
/** Finalize the target at the end of the Configure step. */
void FinishConfigure();
@ -691,6 +692,7 @@ private:
std::string RuntimeInstallPath;
mutable std::string ExportMacro;
std::set<cmStdString> Utilities;
std::map<cmStdString, cmListFileBacktrace> UtilityBacktraces;
bool RecordDependencies;
mutable cmPropertyMap Properties;
LinkLibraryVectorType OriginalLinkLibraries;

View File

@ -0,0 +1,5 @@
cmake_policy(SET CMP0046 NEW)
add_custom_target(foo)
add_custom_target(bar)
add_dependencies(foo bar)

View File

@ -0,0 +1,8 @@
CMake Error at CMP0046-NEW-missing-dependency.cmake:4 \(add_dependencies\):
Policy CMP0046 is not set: Error on non-existent dependency in
add_dependencies. Run "cmake --help-policy CMP0046" for policy details.
Use the cmake_policy command to set the policy and suppress this warning.
+
The dependency target "bar" of target "foo" does not exist.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,4 @@
cmake_policy(SET CMP0046 NEW)
add_custom_target(foo)
add_dependencies(foo bar)

View File

@ -0,0 +1,5 @@
cmake_policy(SET CMP0046 OLD)
add_custom_target(foo)
add_custom_target(bar)
add_dependencies(foo bar)

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,4 @@
cmake_policy(SET CMP0046 OLD)
add_custom_target(foo)
add_dependencies(foo bar)

View File

@ -0,0 +1,9 @@
CMake Warning \(dev\) at CMP0046-WARN-missing-dependency.cmake:2 \(add_dependencies\):
Policy CMP0046 is not set: Error on non-existent dependency in
add_dependencies. Run "cmake --help-policy CMP0046" for policy details.
Use the cmake_policy command to set the policy and suppress this warning.
+
The dependency target "bar" of target "foo" does not exist.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@ -0,0 +1,2 @@
add_custom_target(foo)
add_dependencies(foo bar)

View File

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

View File

@ -0,0 +1,8 @@
include(RunCMake)
run_cmake(CMP0046-OLD-missing-dependency)
run_cmake(CMP0046-NEW-missing-dependency)
run_cmake(CMP0046-WARN-missing-dependency)
run_cmake(CMP0046-OLD-existing-dependency)
run_cmake(CMP0046-NEW-existing-dependency)

View File

@ -66,6 +66,7 @@ if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
endif()
add_RunCMake_test(CMP0043)
add_RunCMake_test(CMP0045)
add_RunCMake_test(CMP0046)
add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange)