From 23f3798c7b38ef7274f318ab90f1788b569dbc5d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 13 Jan 2015 00:35:52 +0100 Subject: [PATCH] cmTarget: Compute link language of TARGET_OBJECTS with CMP0026 OLD (#15338) Commit v3.1.0-rc1~297^2~5 (cmTarget: Drop 'head' argument from GetSourceFiles, 2014-07-10) exposed a dormant bug in source file computation, causing the test case to regress. After that commit, the source file computation and caching finds an existing container of source files. Prior to that patch, the GetSourceFiles method was called with either a null pointer for the head cmTarget, or it was called with the this pointer. The processSources method is eventually called, which normalizes the difference between the null pointer and the this pointer for the head target. However, the cache key depends on the actual pre-normalized pointer. The change in that commit caused the entry to be found in the cache where it was not before, which resulted in incorrect behavior. Prior to that commit, the test case also fails if the GetSourceFiles overload taking a vector is changed to normalize the head target at the beginning of the method: cmTarget const* head = head_ ? head_ : this; Such a construct was correctly used in other locations where similar caching was in place, before being removed in commit v3.1.0-rc1~310^2~25 (cmTarget: Remove 'head' argument from GetLinkInformation, 2014-06-12), but is not neccessary anymore. Commit v3.1.0-rc1~674^2~2 (cmTarget: Cache the cmSourceFiles in GetSourceFiles., 2014-04-05) introduced the caching, but fails the test case for an unrelated reason. That unrelated error was introduced in commit v3.1.0-rc1~688^2~5 (cmTarget: Allow any generator expression in SOURCES property., 2014-03-18) and fixed in commit v3.1.0-rc1~561^2~1 (cmTarget: Fix listing of source files at configure-time., 2014-04-13). All commits which fail the test case in the testable way do so when such a cached version of the source files is found and returned at generate time. In the test case, the cached content is populated at configure-time through the use of the deprecated LOCATION property with CMP0026 OLD. The cached content is an empty container for the bar target in the test case, because its source file 'foo.cpp.o' is not known until generate-time. That means that no source files are available to compute the link language and the reported error is issued. The actual problem is that the SourceFilesMap should be cleared after configure time by cmTarget::ClearLinkMaps. Clear it there now. --- Source/cmTarget.cxx | 1 + .../CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt | 1 + .../CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt | 12 ++++++++++++ .../CMP0026/LOCATION-and-TARGET_OBJECTS.cmake | 6 ++++++ Tests/RunCMake/CMP0026/RunCMakeTest.cmake | 1 + 5 files changed, 21 insertions(+) create mode 100644 Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt create mode 100644 Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt create mode 100644 Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ad1c83e57..4ebc1ce97 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -547,6 +547,7 @@ void cmTarget::ClearLinkMaps() this->Internal->LinkInterfaceMap.clear(); this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear(); this->Internal->LinkClosureMap.clear(); + this->Internal->SourceFilesMap.clear(); for (cmTargetLinkInformationMap::const_iterator it = this->LinkInformation.begin(); it != this->LinkInformation.end(); ++it) diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt new file mode 100644 index 000000000..0996cb6b4 --- /dev/null +++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS-stderr.txt @@ -0,0 +1,12 @@ +CMake Warning \(dev\) at LOCATION-and-TARGET_OBJECTS.cmake:[0-9]+ \(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 "bar". Use the target + name directly with add_custom_command, or use the generator expression + \$, as appropriate. + +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\) +This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake new file mode 100644 index 000000000..3d8eb73d2 --- /dev/null +++ b/Tests/RunCMake/CMP0026/LOCATION-and-TARGET_OBJECTS.cmake @@ -0,0 +1,6 @@ + +enable_language(CXX) + +add_library(foo OBJECT empty.cpp) +add_executable(bar $) +get_target_property(location bar LOCATION) diff --git a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake index 7c2582f7a..fc58ea522 100644 --- a/Tests/RunCMake/CMP0026/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0026/RunCMakeTest.cmake @@ -10,3 +10,4 @@ run_cmake(CMP0026-LOCATION-CONFIG-NEW) run_cmake(CMP0026-LOCATION-CONFIG-OLD) run_cmake(CMP0026-LOCATION-CONFIG-WARN) run_cmake(ObjlibNotDefined) +run_cmake(LOCATION-and-TARGET_OBJECTS)