Commit 301bb5cd authored by Stephen Kelly's avatar Stephen Kelly
Browse files

Disallow link-to-self (#13947).

parent 05f5fde0
......@@ -71,3 +71,4 @@ All Policies
/policy/CMP0035
/policy/CMP0036
/policy/CMP0037
/policy/CMP0038
CMP0038
-------
Targets may not link directly to themselves
CMake 2.8.12 and lower allowed a build target to link to itself directly with
a :command:`target_link_libraries` call. This is an indicator of a bug in
user code.
The OLD behavior for this policy is to ignore targets which list themselves
in their own link implementation. The NEW behavior for this policy is to
report an error if a target attempts to link to itself.
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.
......@@ -291,6 +291,11 @@ cmPolicies::cmPolicies()
CMP0037, "CMP0037",
"Target names should match a validity pattern.",
3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
CMP0038, "CMP0038",
"Targets may not link directly to themselves.",
3,0,0,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
......
......@@ -89,6 +89,7 @@ public:
CMP0035, ///< Disallow command: variable_requires
CMP0036, ///< Disallow command: build_name
CMP0037, ///< Target names should match a validity pattern.
CMP0038, ///< Targets may not link directly to themselves
/** \brief Always the last entry.
*
......
......@@ -932,12 +932,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt)
{
// Never add a self dependency, even if the user asks for it.
if(strcmp( target, lib ) == 0)
{
return;
}
cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
{
const bool isNonImportedTarget = tgt && !tgt->IsImported();
......@@ -951,7 +945,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
}
if (cmGeneratorExpression::Find(lib) != std::string::npos
|| (tgt && tgt->GetType() == INTERFACE_LIBRARY))
|| (tgt && tgt->GetType() == INTERFACE_LIBRARY)
|| (strcmp( target, lib ) == 0))
{
return;
}
......@@ -5293,6 +5288,41 @@ void cmTarget::ComputeLinkImplementation(const char* config,
std::string item = this->CheckCMP0004(*li);
if(item == this->GetName() || item.empty())
{
if(item == this->GetName())
{
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
cmOStringStream e;
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0038))
{
case cmPolicies::WARN:
{
e << (this->Makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0038)) << "\n";
messageType = cmake::AUTHOR_WARNING;
}
break;
case cmPolicies::OLD:
noMessage = true;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
// Issue the fatal message.
break;
}
if(!noMessage)
{
e << "Target \"" << this->GetName() << "\" links to itself.";
this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
e.str(),
this->GetBacktrace());
if (messageType == cmake::FATAL_ERROR)
{
return;
}
}
}
continue;
}
cmTarget *tgt = this->Makefile->FindTargetToUse(li->c_str());
......@@ -5335,6 +5365,7 @@ void cmTarget::ComputeLinkImplementation(const char* config,
}
}
}
// The entry is meant for this configuration.
impl.Libraries.push_back(item);
}
......
CMake Error at CMP0038-NEW.cmake:3 \(add_library\):
Target "self_link" links to itself.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
cmake_policy(SET CMP0038 NEW)
add_library(self_link empty.cpp)
target_link_libraries(self_link self_link)
cmake_policy(SET CMP0038 OLD)
add_library(self_link empty.cpp)
target_link_libraries(self_link self_link)
CMake Warning \(dev\) at CMP0038-WARN.cmake:2 \(add_library\):
Policy CMP0038 is not set: Targets may not link directly to themselves.
Run "cmake --help-policy CMP0038" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
Target "self_link" links to itself.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
add_library(self_link empty.cpp)
target_link_libraries(self_link self_link)
cmake_minimum_required(VERSION 2.8.12)
project(${RunCMake_TEST} CXX)
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
include(RunCMake)
run_cmake(CMP0038-WARN)
run_cmake(CMP0038-NEW)
run_cmake(CMP0038-OLD)
#ifdef _WIN32
__declspec(dllexport)
#endif
int empty()
{
return 0;
}
......@@ -59,6 +59,7 @@ add_RunCMake_test(CMP0028)
if (NOT "${CMAKE_TEST_GENERATOR}" MATCHES "(MSYS|MinGW|NMake|Borland) Makefiles")
add_RunCMake_test(CMP0037)
endif()
add_RunCMake_test(CMP0038)
add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange)
......
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