From e4e5b28c27dc2e6f0073e11fb64c4ea62022a051 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 28 Jun 2013 16:37:39 +0200 Subject: 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. --- Source/cmPolicies.cxx | 22 ++++++++++ Source/cmPolicies.h | 1 + Source/cmTarget.cxx | 50 ++++++++++++++++++++++ Source/cmTarget.h | 2 + Tests/FindPackageModeMakefileTest/CMakeLists.txt | 12 +++++- Tests/FindPackageModeMakefileTest/Makefile.in | 4 +- Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt | 1 + Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt | 1 + Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake | 6 +++ Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt | 1 + Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt | 11 +++++ Tests/RunCMake/CMP0026/CMP0026-NEW.cmake | 7 +++ Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt | 1 + Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt | 12 ++++++ Tests/RunCMake/CMP0026/CMP0026-WARN.cmake | 5 +++ Tests/RunCMake/CMP0026/CMakeLists.txt | 3 ++ Tests/RunCMake/CMP0026/RunCMakeTest.cmake | 5 +++ Tests/RunCMake/CMP0026/empty.cpp | 7 +++ Tests/RunCMake/CMakeLists.txt | 1 + Utilities/CMakeLists.txt | 9 ++-- 20 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt create mode 100644 Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt create mode 100644 Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake create mode 100644 Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt create mode 100644 Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt create mode 100644 Tests/RunCMake/CMP0026/CMP0026-NEW.cmake create mode 100644 Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt create mode 100644 Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt create mode 100644 Tests/RunCMake/CMP0026/CMP0026-WARN.cmake create mode 100644 Tests/RunCMake/CMP0026/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0026/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/CMP0026/empty.cpp diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 1d3469f..d07645c 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -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 $ 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 " + "$ 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() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index ec8959d..e33171b 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -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. * diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1c04e4e..43d9ed1 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4130,6 +4130,43 @@ const char *cmTarget::GetProperty(const char* prop) } //---------------------------------------------------------------------------- +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 $, " + "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_". 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())); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index a88c5ec..3c36da7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -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 SystemIncludeDirectories; diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt index 3674f0e..5d1b376 100644 --- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt +++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt @@ -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 = \"$\"\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) diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in index f647901..c91d8a0 100644 --- a/Tests/FindPackageModeMakefileTest/Makefile.in +++ b/Tests/FindPackageModeMakefileTest/Makefile.in @@ -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@" diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt new file mode 100644 index 0000000..10f3293 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake new file mode 100644 index 0000000..650c8a5 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-IMPORTED.cmake @@ -0,0 +1,6 @@ + +enable_language(CXX) + +add_library(someimportedlib SHARED IMPORTED) + +get_target_property(_loc someimportedlib LOCATION) diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt b/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-NEW-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt new file mode 100644 index 0000000..2a05a4d --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-NEW-stderr.txt @@ -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 \$, as appropriate. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake b/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake new file mode 100644 index 0000000..1659ffc --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-NEW.cmake @@ -0,0 +1,7 @@ + +enable_language(CXX) + +cmake_policy(SET CMP0026 NEW) + +add_library(somelib empty.cpp) +get_target_property(_loc somelib LOCATION) diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt b/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt new file mode 100644 index 0000000..9b88194 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-WARN-stderr.txt @@ -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 \$, as appropriate. + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake b/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake new file mode 100644 index 0000000..89c5a8a --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMP0026-WARN.cmake @@ -0,0 +1,5 @@ + +enable_language(CXX) + +add_library(somelib empty.cpp) +get_target_property(_loc somelib LOCATION) diff --git a/Tests/RunCMake/CMP0026/CMakeLists.txt b/Tests/RunCMake/CMP0026/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/CMP0026/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake new file mode 100644 index 0000000..68000a6 --- /dev/null +++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0026-WARN) +run_cmake(CMP0026-NEW) +run_cmake(CMP0026-IMPORTED) diff --git a/Tests/RunCMake/CMP0026/empty.cpp b/Tests/RunCMake/CMP0026/empty.cpp new file mode 100644 index 0000000..bfbbdde --- /dev/null +++ b/Tests/RunCMake/CMP0026/empty.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif +int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 4fbc3b0..6d5b07b 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -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) diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index bad8d63..31807ee 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -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 $ 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 $ ARGS --copyright ${CMake_BINARY_DIR}/Docs/Copyright.txt --help-full ${CMake_BINARY_DIR}/Docs/cmake.txt --help-full ${CMake_BINARY_DIR}/Docs/cmake.html -- cgit v0.12