Merge topic 'tll-target-policies'

596b2a8 Disallow linking to utility targets (#13902).
301bb5c Disallow link-to-self (#13947).
05f5fde Disallow invalid target names (#13140)
This commit is contained in:
Brad King 2013-11-08 10:33:14 -05:00 committed by CMake Topic Stage
commit 2053e0cd51
46 changed files with 437 additions and 7 deletions

View File

@ -70,3 +70,6 @@ All Policies
/policy/CMP0034
/policy/CMP0035
/policy/CMP0036
/policy/CMP0037
/policy/CMP0038
/policy/CMP0039

21
Help/policy/CMP0037.rst Normal file
View File

@ -0,0 +1,21 @@
CMP0037
-------
Target names should match a validity pattern.
CMake 2.8.12 and lower allowed creating targets using :command:`add_library` and
:command:`add_executable` with unrestricted choice for the target name. Newer
cmake features such as :manual:`cmake-generator-expressions(7)` and some
diagnostics expect target names to match a restricted pattern.
Target names may contain upper and lower case letters, numbers, the underscore
character (_), dot(.), plus(+) and minus(-). As a special case, ALIAS
targets and INTERFACE library targets may contain two consequtive colons.
The OLD behavior for this policy is to allow creating targets which do not match
the validity pattern. The NEW behavior for this policy is to report an error
if an add_* command is used with an invalid target name.
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.

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

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

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

@ -0,0 +1,17 @@
CMP0039
-------
Utility targets may not have link dependencies
CMake 2.8.12 and lower allowed using utility targets in the left hand side
position of the :command:`target_link_libraries` command. This is an indicator
of a bug in user code.
The OLD behavior for this policy is to ignore attempts to set the link
libraries of utility targets. The NEW behavior for this policy is to
report an error if an attempt is made to set the link libraries of a
utility target.
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

@ -69,6 +69,44 @@ bool cmAddExecutableCommand
}
}
bool nameOk = cmGeneratorExpression::IsValidTargetName(exename);
if (nameOk && !importTarget && !isAlias)
{
nameOk = exename.find(":") == std::string::npos;
}
if (!nameOk)
{
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
bool issueMessage = false;
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037))
{
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 << (this->Makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0037)) << "\n";
e << "The target name \"" << exename << "\" is not valid for certain "
"CMake features, such as generator expressions, and may result "
"in undefined behavior.";
this->Makefile->IssueMessage(messageType, e.str().c_str());
if (messageType == cmake::FATAL_ERROR)
{
return false;
}
}
}
// Special modifiers are not allowed with IMPORTED signature.
if(importTarget
&& (use_win32 || use_macbundle || excludeFromAll))

View File

@ -108,6 +108,45 @@ bool cmAddLibraryCommand
break;
}
}
bool nameOk = cmGeneratorExpression::IsValidTargetName(libName);
if (nameOk && !importTarget && !isAlias)
{
nameOk = libName.find(":") == std::string::npos;
}
if (!nameOk)
{
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
bool issueMessage = false;
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0037))
{
case cmPolicies::WARN:
issueMessage = type != cmTarget::INTERFACE_LIBRARY;
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 << (this->Makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0037)) << "\n";
e << "The target name \"" << libName << "\" is not valid for certain "
"CMake features, such as generator expressions, and may result "
"in undefined behavior.";
this->Makefile->IssueMessage(messageType, e.str().c_str());
if (messageType == cmake::FATAL_ERROR)
{
return false;
}
}
}
if (isAlias)
{
if(!cmGeneratorExpression::IsValidTargetName(libName.c_str()))

View File

@ -286,6 +286,21 @@ cmPolicies::cmPolicies()
CMP0036, "CMP0036",
"The build_name command should not be called.",
3,0,0,0, cmPolicies::WARN);
this->DefinePolicy(
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);
this->DefinePolicy(
CMP0039, "CMP0039",
"Utility targets may not have link dependencies",
3,0,0,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()

View File

@ -88,6 +88,9 @@ public:
CMP0034, ///< Disallow command: utility_source
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
CMP0039, ///< Utility targets may not have link dependencies
/** \brief Always the last entry.
*

View File

@ -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);
}

View File

@ -101,6 +101,37 @@ bool cmTargetLinkLibrariesCommand
return true;
}
if (this->Target->GetType() == cmTarget::UTILITY)
{
const char *modal = 0;
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0039))
{
case cmPolicies::WARN:
modal = "should";
case cmPolicies::OLD:
break;
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::NEW:
modal = "must";
messageType = cmake::FATAL_ERROR;
}
if (modal)
{
cmOStringStream e;
e << this->Makefile->GetPolicies()
->GetPolicyWarning(cmPolicies::CMP0039) << "\n"
"Utility target \"" << this->Target->GetName() << "\" " << modal
<< " not be used as the target of a target_link_libraries call.";
this->Makefile->IssueMessage(messageType, e.str().c_str());
if(messageType == cmake::FATAL_ERROR)
{
return false;
}
}
}
// but we might not have any libs after variable expansion
if(args.size() < 2)
{

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,39 @@
CMake Error at CMP0037-NEW.cmake:4 \(add_library\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "lib with spaces" is not valid for certain CMake features,
such as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at CMP0037-NEW.cmake:5 \(add_executable\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "exe with spaces" is not valid for certain CMake features,
such as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at CMP0037-NEW.cmake:6 \(add_library\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "lib:colon" is not valid for certain CMake features, such
as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
CMake Error at CMP0037-NEW.cmake:7 \(add_executable\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "exe:colon" is not valid for certain CMake features, such
as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,7 @@
cmake_policy(SET CMP0037 NEW)
add_library("lib with spaces" empty.cpp)
add_executable("exe with spaces" empty.cpp)
add_library("lib:colon" empty.cpp)
add_executable("exe:colon" empty.cpp)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,5 @@
cmake_policy(SET CMP0037 OLD)
add_library("lib with spaces" empty.cpp)
add_executable("exe with spaces" empty.cpp)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,43 @@
CMake Warning \(dev\) at CMP0037-WARN.cmake:2 \(add_library\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "lib with spaces" is not valid for certain CMake features,
such as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
+
CMake Warning \(dev\) at CMP0037-WARN.cmake:3 \(add_executable\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "exe with spaces" is not valid for certain CMake features,
such as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
+
CMake Warning \(dev\) at CMP0037-WARN.cmake:4 \(add_library\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "lib:colon" is not valid for certain CMake features, such
as generator expressions, and may result in undefined behavior.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
+
CMake Warning \(dev\) at CMP0037-WARN.cmake:5 \(add_executable\):
Policy CMP0037 is not set: Target names should match a validity pattern.
Run "cmake --help-policy CMP0037" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
The target name "exe:colon" is not valid for certain CMake features, such
as generator expressions, and may result in undefined behavior.
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,5 @@
add_library("lib with spaces" empty.cpp)
add_executable("exe with spaces" empty.cpp)
add_library("lib:colon" empty.cpp)
add_executable("exe:colon" empty.cpp)

View File

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

View File

@ -0,0 +1,5 @@
include(RunCMake)
run_cmake(CMP0037-NEW)
run_cmake(CMP0037-OLD)
run_cmake(CMP0037-WARN)

View File

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

View File

@ -0,0 +1 @@
1

View File

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

View File

@ -0,0 +1,4 @@
cmake_policy(SET CMP0038 NEW)
add_library(self_link empty.cpp)
target_link_libraries(self_link self_link)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,4 @@
cmake_policy(SET CMP0038 OLD)
add_library(self_link empty.cpp)
target_link_libraries(self_link self_link)

View File

@ -0,0 +1 @@
0

View File

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

View File

@ -0,0 +1,3 @@
add_library(self_link empty.cpp)
target_link_libraries(self_link self_link)

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,5 @@
include(RunCMake)
run_cmake(CMP0038-WARN)
run_cmake(CMP0038-NEW)
run_cmake(CMP0038-OLD)

View File

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

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,9 @@
CMake Error at CMP0039-NEW.cmake:7 \(target_link_libraries\):
Policy CMP0039 is not set: Utility targets may not have link dependencies
Run "cmake --help-policy CMP0039" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
Utility target "utility" must not be used as the target of a
target_link_libraries call.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,7 @@
cmake_policy(SET CMP0039 NEW)
add_custom_target(utility
COMMAND ${CMAKE_COMMAND} -E echo test
)
target_link_libraries(utility m)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1 @@
^$

View File

@ -0,0 +1,7 @@
cmake_policy(SET CMP0039 OLD)
add_custom_target(utility
COMMAND ${CMAKE_COMMAND} -E echo test
)
target_link_libraries(utility m)

View File

@ -0,0 +1 @@
0

View File

@ -0,0 +1,10 @@
CMake Warning \(dev\) at CMP0039-WARN.cmake:5 \(target_link_libraries\):
Policy CMP0039 is not set: Utility targets may not have link dependencies
Run "cmake --help-policy CMP0039" for policy details. Use the cmake_policy
command to set the policy and suppress this warning.
Utility target "utility" should not be used as the target of a
target_link_libraries call.
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,5 @@
add_custom_target(utility
COMMAND ${CMAKE_COMMAND} -E echo test
)
target_link_libraries(utility m)

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,5 @@
include(RunCMake)
run_cmake(CMP0039-WARN)
run_cmake(CMP0039-NEW)
run_cmake(CMP0039-OLD)

View File

@ -56,6 +56,11 @@ add_RunCMake_test(CMP0022)
add_RunCMake_test(CMP0026)
add_RunCMake_test(CMP0027)
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(CMP0039)
add_RunCMake_test(CTest)
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
add_RunCMake_test(CompilerChange)