Add policy CMP0040 to disallow custom commands on missing targets

This commit is contained in:
Nils Gladitz 2013-11-20 09:53:06 +01:00 committed by Brad King
parent a61025135b
commit a02f3d2de0
24 changed files with 149 additions and 24 deletions

View File

@ -73,3 +73,4 @@ All Policies
/policy/CMP0037 /policy/CMP0037
/policy/CMP0038 /policy/CMP0038
/policy/CMP0039 /policy/CMP0039
/policy/CMP0040

16
Help/policy/CMP0040.rst Normal file
View File

@ -0,0 +1,16 @@
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.

View File

@ -884,34 +884,61 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
{ {
// Find the target to which to add the custom command. // Find the target to which to add the custom command.
cmTargets::iterator ti = this->Targets.find(target); 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))
{
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)
{ {
cmOStringStream e; cmOStringStream e;
e << "Target \"" << target << "\" is an OBJECT library " e << (this->GetPolicies()
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands."; ->GetPolicyWarning(cmPolicies::CMP0040)) << "\n";
this->IssueMessage(cmake::FATAL_ERROR, e.str()); e << "The target name \"" << target << "\" is unknown in this context.";
IssueMessage(messageType, e.str().c_str());
}
return; return;
} }
// Add the command to the appropriate build step for the target.
std::vector<std::string> no_output; if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
cmCustomCommand cc(this, no_output, depends, {
commandLines, comment, workingDir); cmOStringStream e;
cc.SetEscapeOldStyle(escapeOldStyle); e << "Target \"" << target << "\" is an OBJECT library "
cc.SetEscapeAllowMakeVars(true); "that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
switch(type) this->IssueMessage(cmake::FATAL_ERROR, e.str());
{ return;
case cmTarget::PRE_BUILD: }
ti->second.AddPreBuildCommand(cc); // Add the command to the appropriate build step for the target.
break; std::vector<std::string> no_output;
case cmTarget::PRE_LINK: cmCustomCommand cc(this, no_output, depends,
ti->second.AddPreLinkCommand(cc); commandLines, comment, workingDir);
break; cc.SetEscapeOldStyle(escapeOldStyle);
case cmTarget::POST_BUILD: cc.SetEscapeAllowMakeVars(true);
ti->second.AddPostBuildCommand(cc); switch(type)
break; {
} 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;
} }
} }

View File

@ -301,6 +301,11 @@ cmPolicies::cmPolicies()
CMP0039, "CMP0039", CMP0039, "CMP0039",
"Utility targets may not have link dependencies.", "Utility targets may not have link dependencies.",
3,0,0,0, cmPolicies::WARN); 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() cmPolicies::~cmPolicies()

View File

@ -92,6 +92,8 @@ public:
/// should match a validity pattern. /// should match a validity pattern.
CMP0038, ///< Targets may not link directly to themselves CMP0038, ///< Targets may not link directly to themselves
CMP0039, ///< Utility targets may not have link dependencies 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. /** \brief Always the last entry.
* *

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,7 @@
cmake_policy(SET CMP0040 NEW)
add_library(foobar empty.cpp)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E echo hello world"
)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,9 @@
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\)

View File

@ -0,0 +1,5 @@
cmake_policy(SET CMP0040 NEW)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E hello world"
)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,7 @@
cmake_policy(SET CMP0040 OLD)
add_library(foobar empty.cpp)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E echo hello world"
)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,5 @@
cmake_policy(SET CMP0040 OLD)
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E echo hello world"
)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,10 @@
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.

View File

@ -0,0 +1,4 @@
add_custom_command(TARGET foobar PRE_BUILD
COMMAND "${CMAKE_COMMAND} -E hello world"
)

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(CMP0040-OLD-missing-target)
run_cmake(CMP0040-NEW-missing-target)
run_cmake(CMP0040-WARN-missing-target)
run_cmake(CMP0040-OLD-existing-target)
run_cmake(CMP0040-NEW-existing-target)

View File

@ -0,0 +1,7 @@
#ifdef _WIN32
__declspec(dllexport)
#endif
int empty()
{
return 0;
}

View File

@ -59,6 +59,7 @@ add_RunCMake_test(CMP0028)
add_RunCMake_test(CMP0037) add_RunCMake_test(CMP0037)
add_RunCMake_test(CMP0038) add_RunCMake_test(CMP0038)
add_RunCMake_test(CMP0039) add_RunCMake_test(CMP0039)
add_RunCMake_test(CMP0040)
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)