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 NEW behavior for this policy is to use compiler id \"AppleClang\".",
|
||||
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()
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
CMP0023, ///< Disallow mixing keyword and plain tll signatures
|
||||
CMP0024, ///< Disallow including export() result.
|
||||
CMP0025, ///< Compiler id for Apple Clang is now AppleClang
|
||||
CMP0026, ///< Disallow use of the LOCATION target property.
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -4129,6 +4129,43 @@ const char *cmTarget::GetProperty(const char* prop)
|
|||
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,
|
||||
cmProperty::ScopeType scope)
|
||||
|
@ -4154,6 +4191,11 @@ const char *cmTarget::GetProperty(const char* prop,
|
|||
{
|
||||
if(strcmp(prop,"LOCATION") == 0)
|
||||
{
|
||||
if (!this->HandleLocationPropertyPolicy())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the LOCATION property of the target.
|
||||
//
|
||||
// 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>".
|
||||
if(strncmp(prop, "LOCATION_", 9) == 0)
|
||||
{
|
||||
if (!this->HandleLocationPropertyPolicy())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
std::string configName = prop+9;
|
||||
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);
|
||||
if(configName != "IMPORTED")
|
||||
{
|
||||
if (!this->HandleLocationPropertyPolicy())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
this->SetProperty(prop, this->GetLocation(configName.c_str()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -554,6 +554,8 @@ public:
|
|||
{ return this->TargetTypeValue == STATIC_LIBRARY; }
|
||||
|
||||
private:
|
||||
bool HandleLocationPropertyPolicy();
|
||||
|
||||
// The set of include directories that are marked as system include
|
||||
// directories.
|
||||
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)
|
||||
|
||||
# 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}/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_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
|
||||
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(CMP0022)
|
||||
add_RunCMake_test(CMP0026)
|
||||
add_RunCMake_test(CTest)
|
||||
if(UNIX AND "${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
add_RunCMake_test(CompilerChange)
|
||||
|
|
|
@ -48,14 +48,12 @@ set(DOCBOOK_FILES
|
|||
)
|
||||
|
||||
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
|
||||
if(CMD)
|
||||
if(${target})
|
||||
add_custom_command(
|
||||
OUTPUT ${CMake_BINARY_DIR}/Docs/${target}.txt
|
||||
${${target}-PATH} # Possibly set PATH, see below.
|
||||
COMMAND ${CMD}
|
||||
COMMAND $<TARGET_FILE:${target}>
|
||||
ARGS --help-full ${CMake_BINARY_DIR}/Docs/${target}.txt
|
||||
--help-full ${CMake_BINARY_DIR}/Docs/${target}.html
|
||||
--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
|
||||
|
||||
get_target_property(CMD cmake LOCATION)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMake_BINARY_DIR}/Docs/cmake.txt
|
||||
COMMAND ${CMD}
|
||||
COMMAND $<TARGET_FILE:cmake>
|
||||
ARGS --copyright ${CMake_BINARY_DIR}/Docs/Copyright.txt
|
||||
--help-full ${CMake_BINARY_DIR}/Docs/cmake.txt
|
||||
--help-full ${CMake_BINARY_DIR}/Docs/cmake.html
|
||||
|
|
Loading…
Reference in New Issue