From b8af20116854b51923da9ebef668fba0072b06c4 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 13 Apr 2014 10:07:16 +0200 Subject: [PATCH] cmTarget: Fix listing of source files at configure-time. Since commit e5da9e51 (cmTarget: Allow any generator expression in SOURCES property., 2014-03-18), source files are computed by true evaluation of generator expressions, including TARGET_OBJECTS. This evaluation requires the presence of cmGeneratorTarget objects since commit bf98cc25 (Genex: Evaluate TARGET_OBJECTS as a normal expression., 2014-02-26). Ensure that we don't attempt to evaluate the TARGET_OBJECTS generator expression at configure-time, as can happen if CMP0024 or CMP0026 are OLD. Use old-style parsing of the source item to extract object target names in that case. Avoid calling GetProperty("SOURCES") to bypass warnings from CMP0051. Refactor existing logic in GetLanguages which is similar in intent to the new GetSourceFiles code. --- Source/cmTarget.cxx | 92 +++++++++++++++---- Source/cmTarget.h | 2 + .../TargetSources/CMP0026-LOCATION-result.txt | 1 + .../TargetSources/CMP0026-LOCATION-stderr.txt | 1 + .../TargetSources/CMP0026-LOCATION.cmake | 13 +++ Tests/RunCMake/TargetSources/CMakeLists.txt | 2 +- .../RunCMake/TargetSources/RunCMakeTest.cmake | 2 + 7 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt create mode 100644 Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt create mode 100644 Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1f8cddb1a..6a87342b8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -647,6 +647,38 @@ void cmTarget::GetSourceFiles(std::vector &files, { assert(this->GetType() != INTERFACE_LIBRARY); + if (this->Makefile->GetGeneratorTargets().empty()) + { + // At configure-time, this method can be called as part of getting the + // LOCATION property or to export() a file to be include()d. However + // there is no cmGeneratorTarget at configure-time, so search the SOURCES + // for TARGET_OBJECTS instead for backwards compatibility with OLD + // behavior of CMP0024 and CMP0026 only. + + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for(std::vector::const_iterator + i = this->Internal->SourceEntries.begin(); + i != this->Internal->SourceEntries.end(); ++i) + { + std::string entry = (*i)->ge->GetInput(); + + std::vector items; + cmSystemTools::ExpandListArgument(entry, items); + for (std::vector::const_iterator + li = items.begin(); li != items.end(); ++li) + { + if(cmHasLiteralPrefix(*li, "$size() - 1] == '>') + { + continue; + } + files.push_back(*li); + } + } + return; + } + std::vector debugProperties; const char *debugProp = this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); @@ -5342,6 +5374,45 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, config); } +//---------------------------------------------------------------------------- +void +cmTarget::GetObjectLibrariesCMP0026(std::vector& objlibs) const +{ + // At configure-time, this method can be called as part of getting the + // LOCATION property or to export() a file to be include()d. However + // there is no cmGeneratorTarget at configure-time, so search the SOURCES + // for TARGET_OBJECTS instead for backwards compatibility with OLD + // behavior of CMP0024 and CMP0026 only. + typedef cmTargetInternals::TargetPropertyEntry + TargetPropertyEntry; + for(std::vector::const_iterator + i = this->Internal->SourceEntries.begin(); + i != this->Internal->SourceEntries.end(); ++i) + { + std::string entry = (*i)->ge->GetInput(); + + std::vector files; + cmSystemTools::ExpandListArgument(entry, files); + for (std::vector::const_iterator + li = files.begin(); li != files.end(); ++li) + { + if(cmHasLiteralPrefix(*li, "$size() - 1] == '>') + { + std::string objLibName = li->substr(17, li->size()-18); + + if (cmGeneratorExpression::Find(objLibName) != std::string::npos) + { + continue; + } + cmTarget *objLib = this->Makefile->FindTargetToUse(objLibName.c_str()); + assert(objLib); + objlibs.push_back(objLib); + } + } + } +} + //---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set& languages, const std::string& config, @@ -5363,26 +5434,7 @@ void cmTarget::GetLanguages(std::set& languages, std::vector externalObjects; if (this->Makefile->GetGeneratorTargets().empty()) { - // At configure-time, this method can be called as part of getting the - // LOCATION property or to export() a file to be include()d. However - // there is no cmGeneratorTarget at configure-time, so search the SOURCES - // for TARGET_OBJECTS instead for backwards compatibility with OLD - // behavior of CMP0024 and CMP0026 only. - std::vector srcs; - cmSystemTools::ExpandListArgument(this->GetProperty("SOURCES"), srcs); - for(std::vector::const_iterator it = srcs.begin(); - it != srcs.end(); ++it) - { - if (cmHasLiteralPrefix(*it, "$")) - { - std::string objLibName = it->substr(17, it->size()-18); - if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLibName)) - { - objectLibraries.push_back(tgt); - } - } - } + this->GetObjectLibrariesCMP0026(objectLibraries); } else { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 92b5201b4..0a086cb99 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -241,6 +241,8 @@ public: bool IsImported() const {return this->IsImportedTarget;} + void GetObjectLibrariesCMP0026(std::vector& objlibs) const; + /** The link interface specifies transitive library dependencies and other information needed by targets that link to this target. */ struct LinkInterface diff --git a/Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt new file mode 100644 index 000000000..10f32932e --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0026-LOCATION-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake b/Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake new file mode 100644 index 000000000..464df3682 --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0026-LOCATION.cmake @@ -0,0 +1,13 @@ + +cmake_policy(SET CMP0026 OLD) + +add_library(objlib OBJECT + empty_1.cpp +) + +add_executable(my_exe + empty_2.cpp + $ +) + +get_target_property( loc my_exe LOCATION) diff --git a/Tests/RunCMake/TargetSources/CMakeLists.txt b/Tests/RunCMake/TargetSources/CMakeLists.txt index 12cd3c775..f452db177 100644 --- a/Tests/RunCMake/TargetSources/CMakeLists.txt +++ b/Tests/RunCMake/TargetSources/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 2.8.4) -project(${RunCMake_TEST} NONE) +project(${RunCMake_TEST} CXX) include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake index b9095f9b5..01e505c82 100644 --- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake +++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake @@ -7,3 +7,5 @@ if(RunCMake_GENERATOR MATCHES Xcode else() run_cmake(OriginDebug) endif() + +run_cmake(CMP0026-LOCATION)