cmTarget: Deprecate the LOCATION target property with a policy.
The final location and name of a build-target is not determined until generate-time. However, reading the LOCATION property from a target is currently allowed at configure time. Apart from creating possibly-erroneous results, this has an impact on the implementation of cmake itself, and prevents some major cleanups from being made. Disallow reading LOCATION from build-targets with a policy. Port some existing uses of it in CMake itself to use the TARGET_FILE generator expression.
This commit is contained in:
parent
7e4910fe47
commit
e4e5b28c27
|
@ -637,6 +637,28 @@ cmPolicies::cmPolicies()
|
||||||
"The OLD behavior for this policy is to use compiler id \"Clang\". "
|
"The OLD behavior for this policy is to use compiler id \"Clang\". "
|
||||||
"The NEW behavior for this policy is to use compiler id \"AppleClang\".",
|
"The NEW behavior for this policy is to use compiler id \"AppleClang\".",
|
||||||
2,8,13,0, cmPolicies::WARN);
|
2,8,13,0, cmPolicies::WARN);
|
||||||
|
|
||||||
|
this->DefinePolicy(
|
||||||
|
CMP0026, "CMP0026",
|
||||||
|
"Disallow use of the LOCATION target property.",
|
||||||
|
"CMake 2.8.12 and lower allowed reading the LOCATION target property to "
|
||||||
|
"determine the eventual location of build targets. This relies on the "
|
||||||
|
"assumption that all necessary information is available at "
|
||||||
|
"configure-time to determine the final location and filename of the "
|
||||||
|
"target. However, this property is not fully determined until later at "
|
||||||
|
"generate-time. At generate time, the $<TARGET_FILE> generator "
|
||||||
|
"expression can be used to determine the eventual LOCATION of a target "
|
||||||
|
"output."
|
||||||
|
"\n"
|
||||||
|
"Code which reads the LOCATION target property can be ported to use the "
|
||||||
|
"$<TARGET_FILE> generator expression together with the file(GENERATE) "
|
||||||
|
"subcommand to generate a file containing the target location."
|
||||||
|
"\n"
|
||||||
|
"The OLD behavior for this policy is to allow reading the LOCATION "
|
||||||
|
"property from build-targets. "
|
||||||
|
"The NEW behavior for this policy is to not to allow reading the "
|
||||||
|
"LOCATION property from build-targets.",
|
||||||
|
2,8,13,0, cmPolicies::WARN);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmPolicies::~cmPolicies()
|
cmPolicies::~cmPolicies()
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
CMP0023, ///< Disallow mixing keyword and plain tll signatures
|
CMP0023, ///< Disallow mixing keyword and plain tll signatures
|
||||||
CMP0024, ///< Disallow including export() result.
|
CMP0024, ///< Disallow including export() result.
|
||||||
CMP0025, ///< Compiler id for Apple Clang is now AppleClang
|
CMP0025, ///< Compiler id for Apple Clang is now AppleClang
|
||||||
|
CMP0026, ///< Disallow use of the LOCATION target property.
|
||||||
|
|
||||||
/** \brief Always the last entry.
|
/** \brief Always the last entry.
|
||||||
*
|
*
|
||||||
|
|
|
@ -4129,6 +4129,43 @@ const char *cmTarget::GetProperty(const char* prop)
|
||||||
return this->GetProperty(prop, cmProperty::TARGET);
|
return this->GetProperty(prop, cmProperty::TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::HandleLocationPropertyPolicy()
|
||||||
|
{
|
||||||
|
if (this->IsImported())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const char *modal = 0;
|
||||||
|
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
|
||||||
|
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0026))
|
||||||
|
{
|
||||||
|
case cmPolicies::WARN:
|
||||||
|
modal = "should";
|
||||||
|
case cmPolicies::OLD:
|
||||||
|
break;
|
||||||
|
case cmPolicies::REQUIRED_ALWAYS:
|
||||||
|
case cmPolicies::REQUIRED_IF_USED:
|
||||||
|
case cmPolicies::NEW:
|
||||||
|
modal = "may";
|
||||||
|
messageType = cmake::FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modal)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << (this->Makefile->GetPolicies()
|
||||||
|
->GetPolicyWarning(cmPolicies::CMP0026)) << "\n";
|
||||||
|
e << "The LOCATION property " << modal << " not be read from target \""
|
||||||
|
<< this->GetName() << "\". Use the target name directly with "
|
||||||
|
"add_custom_command, or use the generator expression $<TARGET_FILE>, "
|
||||||
|
"as appropriate.\n";
|
||||||
|
this->Makefile->IssueMessage(messageType, e.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageType != cmake::FATAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const char *cmTarget::GetProperty(const char* prop,
|
const char *cmTarget::GetProperty(const char* prop,
|
||||||
cmProperty::ScopeType scope)
|
cmProperty::ScopeType scope)
|
||||||
|
@ -4154,6 +4191,11 @@ const char *cmTarget::GetProperty(const char* prop,
|
||||||
{
|
{
|
||||||
if(strcmp(prop,"LOCATION") == 0)
|
if(strcmp(prop,"LOCATION") == 0)
|
||||||
{
|
{
|
||||||
|
if (!this->HandleLocationPropertyPolicy())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Set the LOCATION property of the target.
|
// Set the LOCATION property of the target.
|
||||||
//
|
//
|
||||||
// For an imported target this is the location of an arbitrary
|
// For an imported target this is the location of an arbitrary
|
||||||
|
@ -4169,6 +4211,10 @@ const char *cmTarget::GetProperty(const char* prop,
|
||||||
// Support "LOCATION_<CONFIG>".
|
// Support "LOCATION_<CONFIG>".
|
||||||
if(strncmp(prop, "LOCATION_", 9) == 0)
|
if(strncmp(prop, "LOCATION_", 9) == 0)
|
||||||
{
|
{
|
||||||
|
if (!this->HandleLocationPropertyPolicy())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
std::string configName = prop+9;
|
std::string configName = prop+9;
|
||||||
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
||||||
}
|
}
|
||||||
|
@ -4181,6 +4227,10 @@ const char *cmTarget::GetProperty(const char* prop,
|
||||||
std::string configName(prop, len-9);
|
std::string configName(prop, len-9);
|
||||||
if(configName != "IMPORTED")
|
if(configName != "IMPORTED")
|
||||||
{
|
{
|
||||||
|
if (!this->HandleLocationPropertyPolicy())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -554,6 +554,8 @@ public:
|
||||||
{ return this->TargetTypeValue == STATIC_LIBRARY; }
|
{ return this->TargetTypeValue == STATIC_LIBRARY; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool HandleLocationPropertyPolicy();
|
||||||
|
|
||||||
// The set of include directories that are marked as system include
|
// The set of include directories that are marked as system include
|
||||||
// directories.
|
// directories.
|
||||||
std::set<cmStdString> SystemIncludeDirectories;
|
std::set<cmStdString> SystemIncludeDirectories;
|
||||||
|
|
|
@ -19,8 +19,16 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile")
|
||||||
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
|
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
|
||||||
|
|
||||||
# now set up the test:
|
# now set up the test:
|
||||||
get_target_property(cmakeExecutable cmake LOCATION)
|
if (NOT CMAKE_VERSION VERSION_LESS 2.8.12)
|
||||||
|
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
|
||||||
|
CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
get_target_property(cmakeLocation cmake LOCATION)
|
||||||
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
|
||||||
|
"CMAKE = \"${cmakeLocation}\"\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY)
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY)
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY)
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
CMAKE = "@cmakeExecutable@"
|
|
||||||
|
include cmakeExecutable.mk
|
||||||
|
|
||||||
CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
|
CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
|
||||||
CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
|
CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
|
||||||
CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
|
CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -0,0 +1 @@
|
||||||
|
^$
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(someimportedlib SHARED IMPORTED)
|
||||||
|
|
||||||
|
get_target_property(_loc someimportedlib LOCATION)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,11 @@
|
||||||
|
CMake Error at CMP0026-NEW.cmake:7 \(get_target_property\):
|
||||||
|
Policy CMP0026 is not set: Disallow use of the LOCATION target property.
|
||||||
|
Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
|
||||||
|
command to set the policy and suppress this warning.
|
||||||
|
|
||||||
|
The LOCATION property may not be read from target "somelib". Use the
|
||||||
|
target name directly with add_custom_command, or use the generator
|
||||||
|
expression \$<TARGET_FILE>, as appropriate.
|
||||||
|
|
||||||
|
Call Stack \(most recent call first\):
|
||||||
|
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0026 NEW)
|
||||||
|
|
||||||
|
add_library(somelib empty.cpp)
|
||||||
|
get_target_property(_loc somelib LOCATION)
|
|
@ -0,0 +1 @@
|
||||||
|
0
|
|
@ -0,0 +1,12 @@
|
||||||
|
CMake Warning \(dev\) at CMP0026-WARN.cmake:5 \(get_target_property\):
|
||||||
|
Policy CMP0026 is not set: Disallow use of the LOCATION target property.
|
||||||
|
Run "cmake --help-policy CMP0026" for policy details. Use the cmake_policy
|
||||||
|
command to set the policy and suppress this warning.
|
||||||
|
|
||||||
|
The LOCATION property should not be read from target "somelib". Use the
|
||||||
|
target name directly with add_custom_command, or use the generator
|
||||||
|
expression \$<TARGET_FILE>, as appropriate.
|
||||||
|
|
||||||
|
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,5 @@
|
||||||
|
|
||||||
|
enable_language(CXX)
|
||||||
|
|
||||||
|
add_library(somelib empty.cpp)
|
||||||
|
get_target_property(_loc somelib LOCATION)
|
|
@ -0,0 +1,3 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(${RunCMake_TEST} NONE)
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,5 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(CMP0026-WARN)
|
||||||
|
run_cmake(CMP0026-NEW)
|
||||||
|
run_cmake(CMP0026-IMPORTED)
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int empty()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -53,6 +53,7 @@ endif()
|
||||||
|
|
||||||
add_RunCMake_test(CMP0019)
|
add_RunCMake_test(CMP0019)
|
||||||
add_RunCMake_test(CMP0022)
|
add_RunCMake_test(CMP0022)
|
||||||
|
add_RunCMake_test(CMP0026)
|
||||||
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)
|
||||||
|
|
|
@ -48,14 +48,12 @@ set(DOCBOOK_FILES
|
||||||
)
|
)
|
||||||
|
|
||||||
macro(ADD_DOCS target dependency)
|
macro(ADD_DOCS target dependency)
|
||||||
# Generate documentation for "ctest" executable.
|
|
||||||
get_target_property(CMD ${target} LOCATION)
|
|
||||||
# only generate the documentation if the target is actually built
|
# only generate the documentation if the target is actually built
|
||||||
if(CMD)
|
if(${target})
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMake_BINARY_DIR}/Docs/${target}.txt
|
OUTPUT ${CMake_BINARY_DIR}/Docs/${target}.txt
|
||||||
${${target}-PATH} # Possibly set PATH, see below.
|
${${target}-PATH} # Possibly set PATH, see below.
|
||||||
COMMAND ${CMD}
|
COMMAND $<TARGET_FILE:${target}>
|
||||||
ARGS --help-full ${CMake_BINARY_DIR}/Docs/${target}.txt
|
ARGS --help-full ${CMake_BINARY_DIR}/Docs/${target}.txt
|
||||||
--help-full ${CMake_BINARY_DIR}/Docs/${target}.html
|
--help-full ${CMake_BINARY_DIR}/Docs/${target}.html
|
||||||
--help-full ${CMake_BINARY_DIR}/Docs/${target}.1
|
--help-full ${CMake_BINARY_DIR}/Docs/${target}.1
|
||||||
|
@ -92,10 +90,9 @@ ADD_DOCS(cmake-gui ${CMake_SOURCE_DIR}/Utilities/Doxygen/doxyfile.in)
|
||||||
|
|
||||||
# add the documentation for cmake itself
|
# add the documentation for cmake itself
|
||||||
|
|
||||||
get_target_property(CMD cmake LOCATION)
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${CMake_BINARY_DIR}/Docs/cmake.txt
|
OUTPUT ${CMake_BINARY_DIR}/Docs/cmake.txt
|
||||||
COMMAND ${CMD}
|
COMMAND $<TARGET_FILE:cmake>
|
||||||
ARGS --copyright ${CMake_BINARY_DIR}/Docs/Copyright.txt
|
ARGS --copyright ${CMake_BINARY_DIR}/Docs/Copyright.txt
|
||||||
--help-full ${CMake_BINARY_DIR}/Docs/cmake.txt
|
--help-full ${CMake_BINARY_DIR}/Docs/cmake.txt
|
||||||
--help-full ${CMake_BINARY_DIR}/Docs/cmake.html
|
--help-full ${CMake_BINARY_DIR}/Docs/cmake.html
|
||||||
|
|
Loading…
Reference in New Issue