Consider targets with double colons to be IMPORTED or ALIAS targets.
Introduce a policy to control the behavior. The AliasTargets unit test already tests that using a double-semicolon in the name is not an error. Change the ExportImport test to use a namespace with a double-semicolon too.
This commit is contained in:
parent
919e1e8453
commit
f063c45589
|
@ -37,3 +37,4 @@ All Policies
|
||||||
/policy/CMP0025
|
/policy/CMP0025
|
||||||
/policy/CMP0026
|
/policy/CMP0026
|
||||||
/policy/CMP0027
|
/policy/CMP0027
|
||||||
|
/policy/CMP0028
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
CMP0028
|
||||||
|
-------
|
||||||
|
|
||||||
|
Double colon in target name means ALIAS or IMPORTED target.
|
||||||
|
|
||||||
|
CMake 2.8.12 and lower allowed the use of targets and files with double
|
||||||
|
colons in target_link_libraries, with some buildsystem generators.
|
||||||
|
|
||||||
|
The use of double-colons is a common pattern used to namespace IMPORTED
|
||||||
|
targets and ALIAS targets. When computing the link dependencies of a target,
|
||||||
|
the name of each dependency could either be a target, or a file on disk.
|
||||||
|
Previously, if a target was not found with a matching name, the name was
|
||||||
|
considered to refer to a file on disk. This can lead to confusing error
|
||||||
|
messages if there is a typo in what should be a target name.
|
||||||
|
|
||||||
|
The OLD behavior for this policy is to search for targets, then files on disk,
|
||||||
|
even if the search term contains double-colons. The NEW behavior for this
|
||||||
|
policy is to issue a FATAL_ERROR if a link dependency contains
|
||||||
|
double-colons but is not an IMPORTED target or an ALIAS 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.
|
|
@ -241,6 +241,11 @@ cmPolicies::cmPolicies()
|
||||||
CMP0027, "CMP0027",
|
CMP0027, "CMP0027",
|
||||||
"Conditionally linked imported targets with missing include directories.",
|
"Conditionally linked imported targets with missing include directories.",
|
||||||
3,0,0,0, cmPolicies::WARN);
|
3,0,0,0, cmPolicies::WARN);
|
||||||
|
|
||||||
|
this->DefinePolicy(
|
||||||
|
CMP0028, "CMP0028",
|
||||||
|
"Double colon in target name means ALIAS or IMPORTED target.",
|
||||||
|
3,0,0,0, cmPolicies::WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmPolicies::~cmPolicies()
|
cmPolicies::~cmPolicies()
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
CMP0026, ///< Disallow use of the LOCATION target property.
|
CMP0026, ///< Disallow use of the LOCATION target property.
|
||||||
CMP0027, ///< Conditionally linked imported targets with missing include
|
CMP0027, ///< Conditionally linked imported targets with missing include
|
||||||
/// directories.
|
/// directories.
|
||||||
|
CMP0028, ///< Double colon in target name means ALIAS or IMPORTED target.
|
||||||
|
|
||||||
/** \brief Always the last entry.
|
/** \brief Always the last entry.
|
||||||
*
|
*
|
||||||
|
|
|
@ -5483,6 +5483,46 @@ void cmTarget::ComputeLinkImplementation(const char* config,
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
cmTarget *tgt = this->Makefile->FindTargetToUse(li->c_str());
|
||||||
|
|
||||||
|
if(!tgt && std::string(item).find("::") != std::string::npos)
|
||||||
|
{
|
||||||
|
bool noMessage = false;
|
||||||
|
cmake::MessageType messageType = cmake::FATAL_ERROR;
|
||||||
|
cmOStringStream e;
|
||||||
|
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
|
||||||
|
{
|
||||||
|
case cmPolicies::WARN:
|
||||||
|
{
|
||||||
|
e << (this->Makefile->GetPolicies()
|
||||||
|
->GetPolicyWarning(cmPolicies::CMP0028)) << "\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 target \"" << item
|
||||||
|
<< "\" but the target was not found. Perhaps a find_package() "
|
||||||
|
"call is missing for an IMPORTED target, or a ALIAS target is "
|
||||||
|
"missing?";
|
||||||
|
this->Makefile->GetCMakeInstance()->IssueMessage(messageType,
|
||||||
|
e.str(),
|
||||||
|
this->GetBacktrace());
|
||||||
|
if (messageType == cmake::FATAL_ERROR)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// The entry is meant for this configuration.
|
// The entry is meant for this configuration.
|
||||||
impl.Libraries.push_back(item);
|
impl.Libraries.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ add_library(sharediface INTERFACE)
|
||||||
target_link_libraries(sharediface INTERFACE sharedlib)
|
target_link_libraries(sharediface INTERFACE sharedlib)
|
||||||
|
|
||||||
export(TARGETS sharediface sharedlib headeronly
|
export(TARGETS sharediface sharedlib headeronly
|
||||||
NAMESPACE bld_
|
NAMESPACE bld::
|
||||||
FILE ../ExportInterfaceBuildTree.cmake
|
FILE ../ExportInterfaceBuildTree.cmake
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,4 +46,4 @@ install(FILES
|
||||||
DESTINATION include/sharedlib
|
DESTINATION include/sharedlib
|
||||||
)
|
)
|
||||||
|
|
||||||
install(EXPORT expInterface NAMESPACE exp_ DESTINATION lib/exp)
|
install(EXPORT expInterface NAMESPACE exp:: DESTINATION lib/exp)
|
||||||
|
|
|
@ -10,18 +10,18 @@ set_property(TARGET define_iface PROPERTY
|
||||||
INTERFACE_COMPILE_DEFINITIONS DEFINE_IFACE_DEFINE)
|
INTERFACE_COMPILE_DEFINITIONS DEFINE_IFACE_DEFINE)
|
||||||
|
|
||||||
add_executable(headeronlytest_bld headeronlytest.cpp)
|
add_executable(headeronlytest_bld headeronlytest.cpp)
|
||||||
target_link_libraries(headeronlytest_bld bld_headeronly)
|
target_link_libraries(headeronlytest_bld bld::headeronly)
|
||||||
|
|
||||||
set_property(TARGET bld_sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
|
set_property(TARGET bld::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
|
||||||
|
|
||||||
add_executable(interfacetest_bld interfacetest.cpp)
|
add_executable(interfacetest_bld interfacetest.cpp)
|
||||||
target_link_libraries(interfacetest_bld bld_sharediface)
|
target_link_libraries(interfacetest_bld bld::sharediface)
|
||||||
|
|
||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
macro(do_try_compile prefix)
|
macro(do_try_compile prefix)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${prefix}headeronly)
|
set(CMAKE_REQUIRED_LIBRARIES ${prefix}::headeronly)
|
||||||
check_cxx_source_compiles(
|
check_cxx_source_compiles(
|
||||||
"
|
"
|
||||||
#include \"headeronly.h\"
|
#include \"headeronly.h\"
|
||||||
|
@ -42,14 +42,14 @@ macro(do_try_compile prefix)
|
||||||
endif()
|
endif()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
do_try_compile(bld_)
|
do_try_compile(bld)
|
||||||
|
|
||||||
add_executable(headeronlytest_exp headeronlytest.cpp)
|
add_executable(headeronlytest_exp headeronlytest.cpp)
|
||||||
target_link_libraries(headeronlytest_exp exp_headeronly)
|
target_link_libraries(headeronlytest_exp exp::headeronly)
|
||||||
|
|
||||||
set_property(TARGET exp_sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
|
set_property(TARGET exp::sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
|
||||||
|
|
||||||
add_executable(interfacetest_exp interfacetest.cpp)
|
add_executable(interfacetest_exp interfacetest.cpp)
|
||||||
target_link_libraries(interfacetest_exp exp_sharediface)
|
target_link_libraries(interfacetest_exp exp::sharediface)
|
||||||
|
|
||||||
do_try_compile(exp_)
|
do_try_compile(exp)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,6 @@
|
||||||
|
CMake Error at CMP0028-NEW.cmake:4 \(add_library\):
|
||||||
|
Target "foo" links to target "External::Library" but the target was not
|
||||||
|
found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or
|
||||||
|
a ALIAS target is missing\?
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0028 NEW)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
target_link_libraries(foo PRIVATE External::Library)
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -0,0 +1 @@
|
||||||
|
^$
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0028 OLD)
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
target_link_libraries(foo PRIVATE External::Library)
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -0,0 +1,11 @@
|
||||||
|
CMake Warning \(dev\) at CMP0028-WARN.cmake:2 \(add_library\):
|
||||||
|
Policy CMP0028 is not set: Double colon in target name means ALIAS or
|
||||||
|
IMPORTED target. Run "cmake --help-policy CMP0028" for policy details.
|
||||||
|
Use the cmake_policy command to set the policy and suppress this warning.
|
||||||
|
|
||||||
|
Target "foo" links to target "External::Library" but the target was not
|
||||||
|
found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or
|
||||||
|
a ALIAS target is missing\?
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
||||||
|
This warning is for project developers. Use -Wno-dev to suppress it.
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
add_library(foo empty.cpp)
|
||||||
|
target_link_libraries(foo PRIVATE External::Library)
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8.4)
|
||||||
|
project(${RunCMake_TEST} CXX)
|
||||||
|
include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE)
|
|
@ -0,0 +1,5 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(CMP0028-NEW)
|
||||||
|
run_cmake(CMP0028-OLD)
|
||||||
|
run_cmake(CMP0028-WARN)
|
|
@ -55,6 +55,7 @@ add_RunCMake_test(CMP0019)
|
||||||
add_RunCMake_test(CMP0022)
|
add_RunCMake_test(CMP0022)
|
||||||
add_RunCMake_test(CMP0026)
|
add_RunCMake_test(CMP0026)
|
||||||
add_RunCMake_test(CMP0027)
|
add_RunCMake_test(CMP0027)
|
||||||
|
add_RunCMake_test(CMP0028)
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue