From a02f3d2de00a16a68e8948db3c0de507e569f8a3 Mon Sep 17 00:00:00 2001 From: Nils Gladitz Date: Wed, 20 Nov 2013 09:53:06 +0100 Subject: [PATCH] Add policy CMP0040 to disallow custom commands on missing targets --- Help/manual/cmake-policies.7.rst | 1 + Help/policy/CMP0040.rst | 16 ++++ Source/cmMakefile.cxx | 75 +++++++++++++------ Source/cmPolicies.cxx | 5 ++ Source/cmPolicies.h | 2 + .../CMP0040-NEW-existing-target-result.txt | 1 + .../CMP0040-NEW-existing-target-stderr.txt | 1 + .../CMP0040/CMP0040-NEW-existing-target.cmake | 7 ++ .../CMP0040-NEW-missing-target-result.txt | 1 + .../CMP0040-NEW-missing-target-stderr.txt | 9 +++ .../CMP0040/CMP0040-NEW-missing-target.cmake | 5 ++ .../CMP0040-OLD-existing-target-result.txt | 1 + .../CMP0040-OLD-existing-target-stderr.txt | 1 + .../CMP0040/CMP0040-OLD-existing-target.cmake | 7 ++ .../CMP0040-OLD-missing-target-result.txt | 1 + .../CMP0040-OLD-missing-target-stderr.txt | 1 + .../CMP0040/CMP0040-OLD-missing-target.cmake | 5 ++ .../CMP0040-WARN-missing-target-result.txt | 1 + .../CMP0040-WARN-missing-target-stderr.txt | 10 +++ .../CMP0040/CMP0040-WARN-missing-target.cmake | 4 + Tests/RunCMake/CMP0040/CMakeLists.txt | 3 + Tests/RunCMake/CMP0040/RunCMakeTest.cmake | 8 ++ Tests/RunCMake/CMP0040/empty.cpp | 7 ++ Tests/RunCMake/CMakeLists.txt | 1 + 24 files changed, 149 insertions(+), 24 deletions(-) create mode 100644 Help/policy/CMP0040.rst create mode 100644 Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake create mode 100644 Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake create mode 100644 Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake create mode 100644 Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake create mode 100644 Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt create mode 100644 Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake create mode 100644 Tests/RunCMake/CMP0040/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0040/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/CMP0040/empty.cpp diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 2430ee9f4..e954a86fc 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -73,3 +73,4 @@ All Policies /policy/CMP0037 /policy/CMP0038 /policy/CMP0039 + /policy/CMP0040 diff --git a/Help/policy/CMP0040.rst b/Help/policy/CMP0040.rst new file mode 100644 index 000000000..99b54ff31 --- /dev/null +++ b/Help/policy/CMP0040.rst @@ -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. diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 6be1fddd9..e073f769a 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -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)) + { + 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; - 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()); + e << (this->GetPolicies() + ->GetPolicyWarning(cmPolicies::CMP0040)) << "\n"; + e << "The target name \"" << target << "\" is unknown in this context."; + IssueMessage(messageType, e.str().c_str()); + } + return; - } - // Add the command to the appropriate build step for the target. - std::vector 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; - } + } + + 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 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; } } diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index a18fc16a8..b9b469c56 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -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() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 361d820f9..683412169 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -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. * diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake new file mode 100644 index 000000000..f9c8afdf5 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-existing-target.cmake @@ -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" +) diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt new file mode 100644 index 000000000..03a0217f8 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake new file mode 100644 index 000000000..276863d7b --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-NEW-missing-target.cmake @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0040 NEW) + +add_custom_command(TARGET foobar PRE_BUILD + COMMAND "${CMAKE_COMMAND} -E hello world" +) diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake new file mode 100644 index 000000000..d7ec50daa --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-existing-target.cmake @@ -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" +) diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake new file mode 100644 index 000000000..ef7a0f731 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-OLD-missing-target.cmake @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0040 OLD) + +add_custom_command(TARGET foobar PRE_BUILD + COMMAND "${CMAKE_COMMAND} -E echo hello world" +) diff --git a/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt new file mode 100644 index 000000000..e791f0a72 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target-stderr.txt @@ -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. diff --git a/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake new file mode 100644 index 000000000..2c3e40149 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMP0040-WARN-missing-target.cmake @@ -0,0 +1,4 @@ + +add_custom_command(TARGET foobar PRE_BUILD + COMMAND "${CMAKE_COMMAND} -E hello world" +) diff --git a/Tests/RunCMake/CMP0040/CMakeLists.txt b/Tests/RunCMake/CMP0040/CMakeLists.txt new file mode 100644 index 000000000..2f10cb092 --- /dev/null +++ b/Tests/RunCMake/CMP0040/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8.12) +project(${RunCMake_TEST} CXX) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/CMP0040/RunCMakeTest.cmake b/Tests/RunCMake/CMP0040/RunCMakeTest.cmake new file mode 100644 index 000000000..13160e3a4 --- /dev/null +++ b/Tests/RunCMake/CMP0040/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/CMP0040/empty.cpp b/Tests/RunCMake/CMP0040/empty.cpp new file mode 100644 index 000000000..bfbbddeb9 --- /dev/null +++ b/Tests/RunCMake/CMP0040/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index bb1b90953..209b0b3b3 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -59,6 +59,7 @@ add_RunCMake_test(CMP0028) add_RunCMake_test(CMP0037) add_RunCMake_test(CMP0038) add_RunCMake_test(CMP0039) +add_RunCMake_test(CMP0040) add_RunCMake_test(CTest) if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles") add_RunCMake_test(CompilerChange)