Commit a02f3d2d authored by Nils Gladitz's avatar Nils Gladitz Committed by Brad King
Browse files

Add policy CMP0040 to disallow custom commands on missing targets

parent a6102513
......@@ -73,3 +73,4 @@ All Policies
/policy/CMP0037
/policy/CMP0038
/policy/CMP0039
/policy/CMP0040
CMP0040
-------
The target in the TARGET signature of add_custom_command() must exist.
CMake 2.8.12 and lower silently ignored a custom command created with
the TARGET signature of :command:`add_custom_command`
if the target is unknown.
The OLD behavior for this policy is to ignore custom commands
for unknown targets. The NEW behavior for this policy is to report and error
if the target referenced in :command:`add_custom_command` is unknown.
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.
......@@ -884,34 +884,61 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
{
// Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target);
if(ti != this->Targets.end())
if(ti == this->Targets.end())
{
if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
bool issueMessage = false;
switch(this->GetPolicyStatus(cmPolicies::CMP0040))
{
cmOStringStream e;
e << "Target \"" << target << "\" is an OBJECT library "
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
this->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
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;
}
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output;
cmCustomCommand cc(this, no_output, depends,
commandLines, comment, workingDir);
cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true);
switch(type)
if(issueMessage)
{
case cmTarget::PRE_BUILD:
ti->second.AddPreBuildCommand(cc);
break;
case cmTarget::PRE_LINK:
ti->second.AddPreLinkCommand(cc);
break;
case cmTarget::POST_BUILD:
ti->second.AddPostBuildCommand(cc);
break;
cmOStringStream e;
e << (this->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0040)) << "\n";
e << "The target name \"" << target << "\" is unknown in this context.";
IssueMessage(messageType, e.str().c_str());
}
return;
}
if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
{
cmOStringStream e;
e << "Target \"" << target << "\" is an OBJECT library "
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
this->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output;
cmCustomCommand cc(this, no_output, depends,
commandLines, comment, workingDir);
cc.SetEscapeOldStyle(escapeOldStyle);
cc.SetEscapeAllowMakeVars(true);
switch(type)
{
case cmTarget::PRE_BUILD:
ti->second.AddPreBuildCommand(cc);
break;
case cmTarget::PRE_LINK:
ti->second.AddPreLinkCommand(cc);
break;
case cmTarget::POST_BUILD:
ti->second.AddPostBuildCommand(cc);
break;
}
}
......
......@@ -301,6 +301,11 @@ cmPolicies::cmPolicies()
CMP0039, "CMP0039",
"Utility targets may not have link dependencies.",
3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0040, "CMP0040",
"The target in the TARGET signature of add_custom_command() must exist.",
3,0,0,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
......
......@@ -92,6 +92,8 @@ public:
/// should match a validity pattern.
CMP0038, ///< Targets may not link directly to themselves
CMP0039, ///< Utility targets may not have link dependencies
CMP0040, ///< The target in the TARGET signature of
/// add_custom_command() must exist.
/** \brief Always the last entry.
*
......
cmake_policy(SET CMP0040 NEW)
add_library(foobar empty.cpp)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E echo hello world"
)
CMake Error at CMP0040-NEW-missing-target.cmake:3 \(add_custom_command\):
Policy CMP0040 is not set: The target in the TARGET signature of
add_custom_command\(\) must exist. Run "cmake --help-policy CMP0040" for
policy details. Use the cmake_policy command to set the policy and
suppress this warning.
+
The target name "foobar" is unknown in this context.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
cmake_policy(SET CMP0040 NEW)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E hello world"
)
cmake_policy(SET CMP0040 OLD)
add_library(foobar empty.cpp)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E echo hello world"
)
cmake_policy(SET CMP0040 OLD)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E echo hello world"
)
CMake Warning \(dev\) at CMP0040-WARN-missing-target.cmake:2 \(add_custom_command\):
Policy CMP0040 is not set: The target in the TARGET signature of
add_custom_command\(\) must exist. Run "cmake --help-policy CMP0040" for
policy details. Use the cmake_policy command to set the policy and
suppress this warning.
+
The target name "foobar" is unknown in this context.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E hello world"
)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment