From e5da9e51d02ba912bba4f556ecd6453dd187c8d8 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 18 Mar 2014 16:40:46 +0100 Subject: [PATCH] cmTarget: Allow any generator expression in SOURCES property. Remove use of UseObjectLibraries from Makefile and Ninja generators. It is not needed now because those generators use GetExternalObjects which already contains the objects from object libraries. The VS10 generator calls both the UseObjectLibraries and the GetExternalObjects methods. Ensure that duplicates are not created by skipping objects from object libraries in handling of GetExternalObjects. Similarly, fix VS6, VS7 and Xcode object handling by skipping external objects from OBJECT_LIBRARY usage as appropriate. The error message in the BadSourceExpression1 test is now reported by the generator expression evaluator, so it has different text. --- Help/command/add_executable.rst | 7 ++- Help/command/add_library.rst | 6 +- Help/release/dev/target-SOURCES-genex.rst | 5 ++ Source/cmGlobalXCodeGenerator.cxx | 5 +- Source/cmLocalVisualStudio6Generator.cxx | 10 ++++ Source/cmLocalVisualStudio7Generator.cxx | 4 ++ Source/cmMakefileTargetGenerator.cxx | 3 - Source/cmNinjaTargetGenerator.cxx | 11 ---- Source/cmTarget.cxx | 59 ++++++++++--------- Source/cmVisualStudio10TargetGenerator.cxx | 13 ++++ Tests/GeneratorExpression/CMakeLists.txt | 2 +- .../BadSourceExpression1-stderr.txt | 4 +- 12 files changed, 81 insertions(+), 48 deletions(-) diff --git a/Help/command/add_executable.rst b/Help/command/add_executable.rst index 231eeedb1..4ed10e1cf 100644 --- a/Help/command/add_executable.rst +++ b/Help/command/add_executable.rst @@ -35,8 +35,11 @@ If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL` target property for details. -See the :manual:`cmake-buildsystem(7)` manual for more on defining -buildsystem properties. +Source arguments to ``add_executable`` may use "generator expressions" with +the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. See the :manual:`cmake-buildsystem(7)` +manual for more on defining buildsystem properties. + -------------------------------------------------------------------------- diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst index 094426971..e93ef53cc 100644 --- a/Help/command/add_library.rst +++ b/Help/command/add_library.rst @@ -39,8 +39,10 @@ If ``EXCLUDE_FROM_ALL`` is given the corresponding property will be set on the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL` target property for details. -See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem -properties. +Source arguments to ``add_library`` may use "generator expressions" with +the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. See the :manual:`cmake-buildsystem(7)` +manual for more on defining buildsystem properties. -------------------------------------------------------------------------- diff --git a/Help/release/dev/target-SOURCES-genex.rst b/Help/release/dev/target-SOURCES-genex.rst index 1ca6f6682..9a6510110 100644 --- a/Help/release/dev/target-SOURCES-genex.rst +++ b/Help/release/dev/target-SOURCES-genex.rst @@ -5,3 +5,8 @@ target-SOURCES-genex :manual:`generator expression ` such as ``TARGET_OBJECTS`` when read at configure time, if policy :policy:`CMP0051` is ``NEW``. + +* The :prop_tgt:`SOURCES` target property now generally supports + :manual:`generator expression `. The + generator expressions may be used in the :command:`add_library` and + :command:`add_executable` commands. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index fdf73d675..2a6e522f6 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1007,7 +1007,10 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, if(filetype && filetype->GetString() == "compiled.mach-o.objfile") { - externalObjFiles.push_back(xsf); + if ((*i)->GetObjectLibrary().empty()) + { + externalObjFiles.push_back(xsf); + } } else if(this->IsHeaderFile(*i) || (tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) || diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index e99f3a4ad..11e967949 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -324,6 +324,11 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, for(std::vector::const_iterator i = classes.begin(); i != classes.end(); i++) { + if (!(*i)->GetObjectLibrary().empty()) + { + continue; + } + // Add the file to the list of sources. std::string source = (*i)->GetFullPath(); cmSourceGroup* sourceGroup = @@ -398,6 +403,11 @@ void cmLocalVisualStudio6Generator for(std::vector::const_iterator sf = sourceFiles.begin(); sf != sourceFiles.end(); ++sf) { + if (!(*sf)->GetObjectLibrary().empty()) + { + continue; + } + std::string source = (*sf)->GetFullPath(); const cmCustomCommand *command = (*sf)->GetCustomCommand(); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e8562ca92..8bac10d74 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1401,6 +1401,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, for(std::vector::const_iterator i = classes.begin(); i != classes.end(); i++) { + if (!(*i)->GetObjectLibrary().empty()) + { + continue; + } // Add the file to the list of sources. std::string source = (*i)->GetFullPath(); if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF") diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 6759d050e..c520f9e52 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -202,9 +202,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() // Generate this object file's rule file. this->WriteObjectRuleFiles(**si); } - - // Add object library contents as external objects. - this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects); } //---------------------------------------------------------------------------- diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 8865b3d2d..b7eab7d79 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -525,17 +525,6 @@ cmNinjaTargetGenerator this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str()); } - { - // Add object library contents as external objects. - std::vector objs; - this->GeneratorTarget->UseObjectLibraries(objs); - for(std::vector::iterator oi = objs.begin(); - oi != objs.end(); ++oi) - { - this->Objects.push_back(ConvertToNinjaPath(oi->c_str())); - } - } - this->GetBuildFileStream() << "\n"; } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 04ae5af88..aea644624 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -551,15 +551,16 @@ void cmTarget::GetSourceFiles(std::vector &files) const si != this->Internal->SourceEntries.end(); ++si) { std::vector srcs; - cmSystemTools::ExpandListArgument((*si)->ge->GetInput(), srcs); + cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile, + "", + false, + this), + srcs); + for(std::vector::const_iterator i = srcs.begin(); i != srcs.end(); ++i) { std::string src = *i; - if (cmGeneratorExpression::Find(src) != std::string::npos) - { - continue; - } cmSourceFile* sf = this->Makefile->GetOrCreateSource(src); std::string e; src = sf->GetFullPath(&e); @@ -606,7 +607,14 @@ void cmTarget::AddSources(std::vector const& srcs) const char* src = i->c_str(); if(src[0] == '$' && src[1] == '<') { - this->ProcessSourceExpression(*i); + this->AddSource(src); + + if(cmHasLiteralPrefix(i->c_str(), "$size()-1] == '>') + { + std::string objLibName = i->substr(17, i->size()-18); + this->ObjectLibraries.push_back(objLibName); + } } else { @@ -734,30 +742,13 @@ cmSourceFile* cmTarget::AddSource(const std::string& src) this->Internal->SourceEntries.push_back( new cmTargetInternals::TargetPropertyEntry(cge)); } + if (cmGeneratorExpression::Find(src) != std::string::npos) + { + return 0; + } return this->Makefile->GetOrCreateSource(src); } - - -//---------------------------------------------------------------------------- -void cmTarget::ProcessSourceExpression(std::string const& expr) -{ - if(cmHasLiteralPrefix(expr.c_str(), "$') - { - std::string objLibName = expr.substr(17, expr.size()-18); - this->ObjectLibraries.push_back(objLibName); - this->AddSource(expr); - } - else - { - cmOStringStream e; - e << "Unrecognized generator expression:\n" - << " " << expr; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - } -} - //---------------------------------------------------------------------------- void cmTarget::MergeLinkLibraries( cmMakefile& mf, const std::string& selfname, @@ -2886,6 +2877,14 @@ const char *cmTarget::GetProperty(const std::string& prop, { std::string objLibName = li->substr(17, li->size()-18); + if (cmGeneratorExpression::Find(objLibName) != std::string::npos) + { + ss << sep; + sep = ";"; + ss << *li; + continue; + } + bool addContent = false; bool noMessage = true; cmOStringStream e; @@ -2920,6 +2919,12 @@ const char *cmTarget::GetProperty(const std::string& prop, ss << *li; } } + else if (cmGeneratorExpression::Find(*li) == std::string::npos) + { + ss << sep; + sep = ";"; + ss << *li; + } else { cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index bb76b7f8a..8d10e7c66 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1054,6 +1054,19 @@ void cmVisualStudio10TargetGenerator::WriteAllSources() std::vector externalObjects; this->GeneratorTarget->GetExternalObjects(externalObjects); + for(std::vector::iterator + si = externalObjects.begin(); + si != externalObjects.end(); ) + { + if (!(*si)->GetObjectLibrary().empty()) + { + si = externalObjects.erase(si); + } + else + { + ++si; + } + } if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10) { // For VS >= 11 we use LinkObjects to avoid linking custom command diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 66b175a95..b5068536c 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -166,7 +166,7 @@ add_library(imported4 SHARED IMPORTED) set_property(TARGET imported4 APPEND PROPERTY INCLUDE_DIRECTORIES $) -add_executable(someexe empty.cpp) +add_executable(someexe $<1:empty.cpp> $<0:does_not_exist>) add_executable(Alias::SomeExe ALIAS someexe) add_library(Alias::SomeLib ALIAS empty1) diff --git a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt index a1cac36fa..859dc3f8c 100644 --- a/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt +++ b/Tests/RunCMake/ObjectLibrary/BadSourceExpression1-stderr.txt @@ -1,6 +1,8 @@ CMake Error at BadSourceExpression1.cmake:1 \(add_library\): - Unrecognized generator expression: + Error evaluating generator expression: \$ + + Expression did not evaluate to a known generator expression Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\)