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.
This commit is contained in:
Stephen Kelly 2014-03-18 16:40:46 +01:00
parent 5702e10677
commit e5da9e51d0
12 changed files with 81 additions and 48 deletions

View File

@ -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` the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
target property for details. target property for details.
See the :manual:`cmake-buildsystem(7)` manual for more on defining Source arguments to ``add_executable`` may use "generator expressions" with
buildsystem properties. 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.
-------------------------------------------------------------------------- --------------------------------------------------------------------------

View File

@ -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` the created target. See documentation of the :prop_tgt:`EXCLUDE_FROM_ALL`
target property for details. target property for details.
See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem Source arguments to ``add_library`` may use "generator expressions" with
properties. 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.
-------------------------------------------------------------------------- --------------------------------------------------------------------------

View File

@ -5,3 +5,8 @@ target-SOURCES-genex
:manual:`generator expression <cmake-generator-expressions(7)>` :manual:`generator expression <cmake-generator-expressions(7)>`
such as ``TARGET_OBJECTS`` when read at configure time, if such as ``TARGET_OBJECTS`` when read at configure time, if
policy :policy:`CMP0051` is ``NEW``. policy :policy:`CMP0051` is ``NEW``.
* The :prop_tgt:`SOURCES` target property now generally supports
:manual:`generator expression <cmake-generator-expressions(7)>`. The
generator expressions may be used in the :command:`add_library` and
:command:`add_executable` commands.

View File

@ -1007,7 +1007,10 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
if(filetype && if(filetype &&
filetype->GetString() == "compiled.mach-o.objfile") filetype->GetString() == "compiled.mach-o.objfile")
{ {
externalObjFiles.push_back(xsf); if ((*i)->GetObjectLibrary().empty())
{
externalObjFiles.push_back(xsf);
}
} }
else if(this->IsHeaderFile(*i) || else if(this->IsHeaderFile(*i) ||
(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) || (tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||

View File

@ -324,6 +324,11 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++) i != classes.end(); i++)
{ {
if (!(*i)->GetObjectLibrary().empty())
{
continue;
}
// Add the file to the list of sources. // Add the file to the list of sources.
std::string source = (*i)->GetFullPath(); std::string source = (*i)->GetFullPath();
cmSourceGroup* sourceGroup = cmSourceGroup* sourceGroup =
@ -398,6 +403,11 @@ void cmLocalVisualStudio6Generator
for(std::vector<const cmSourceFile *>::const_iterator sf = for(std::vector<const cmSourceFile *>::const_iterator sf =
sourceFiles.begin(); sf != sourceFiles.end(); ++sf) sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
{ {
if (!(*sf)->GetObjectLibrary().empty())
{
continue;
}
std::string source = (*sf)->GetFullPath(); std::string source = (*sf)->GetFullPath();
const cmCustomCommand *command = const cmCustomCommand *command =
(*sf)->GetCustomCommand(); (*sf)->GetCustomCommand();

View File

@ -1401,6 +1401,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
i != classes.end(); i++) i != classes.end(); i++)
{ {
if (!(*i)->GetObjectLibrary().empty())
{
continue;
}
// Add the file to the list of sources. // Add the file to the list of sources.
std::string source = (*i)->GetFullPath(); std::string source = (*i)->GetFullPath();
if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF") if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")

View File

@ -202,9 +202,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// Generate this object file's rule file. // Generate this object file's rule file.
this->WriteObjectRuleFiles(**si); this->WriteObjectRuleFiles(**si);
} }
// Add object library contents as external objects.
this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -525,17 +525,6 @@ cmNinjaTargetGenerator
this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str()); this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
} }
{
// Add object library contents as external objects.
std::vector<std::string> objs;
this->GeneratorTarget->UseObjectLibraries(objs);
for(std::vector<std::string>::iterator oi = objs.begin();
oi != objs.end(); ++oi)
{
this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
}
}
this->GetBuildFileStream() << "\n"; this->GetBuildFileStream() << "\n";
} }

View File

@ -551,15 +551,16 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
si != this->Internal->SourceEntries.end(); ++si) si != this->Internal->SourceEntries.end(); ++si)
{ {
std::vector<std::string> srcs; std::vector<std::string> srcs;
cmSystemTools::ExpandListArgument((*si)->ge->GetInput(), srcs); cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
"",
false,
this),
srcs);
for(std::vector<std::string>::const_iterator i = srcs.begin(); for(std::vector<std::string>::const_iterator i = srcs.begin();
i != srcs.end(); ++i) i != srcs.end(); ++i)
{ {
std::string src = *i; std::string src = *i;
if (cmGeneratorExpression::Find(src) != std::string::npos)
{
continue;
}
cmSourceFile* sf = this->Makefile->GetOrCreateSource(src); cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
std::string e; std::string e;
src = sf->GetFullPath(&e); src = sf->GetFullPath(&e);
@ -606,7 +607,14 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
const char* src = i->c_str(); const char* src = i->c_str();
if(src[0] == '$' && src[1] == '<') if(src[0] == '$' && src[1] == '<')
{ {
this->ProcessSourceExpression(*i); this->AddSource(src);
if(cmHasLiteralPrefix(i->c_str(), "$<TARGET_OBJECTS:") &&
(*i)[i->size()-1] == '>')
{
std::string objLibName = i->substr(17, i->size()-18);
this->ObjectLibraries.push_back(objLibName);
}
} }
else else
{ {
@ -734,30 +742,13 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
this->Internal->SourceEntries.push_back( this->Internal->SourceEntries.push_back(
new cmTargetInternals::TargetPropertyEntry(cge)); new cmTargetInternals::TargetPropertyEntry(cge));
} }
if (cmGeneratorExpression::Find(src) != std::string::npos)
{
return 0;
}
return this->Makefile->GetOrCreateSource(src); return this->Makefile->GetOrCreateSource(src);
} }
//----------------------------------------------------------------------------
void cmTarget::ProcessSourceExpression(std::string const& expr)
{
if(cmHasLiteralPrefix(expr.c_str(), "$<TARGET_OBJECTS:") &&
expr[expr.size()-1] == '>')
{
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, void cmTarget::MergeLinkLibraries( cmMakefile& mf,
const std::string& selfname, 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); 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 addContent = false;
bool noMessage = true; bool noMessage = true;
cmOStringStream e; cmOStringStream e;
@ -2920,6 +2919,12 @@ const char *cmTarget::GetProperty(const std::string& prop,
ss << *li; ss << *li;
} }
} }
else if (cmGeneratorExpression::Find(*li) == std::string::npos)
{
ss << sep;
sep = ";";
ss << *li;
}
else else
{ {
cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li); cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);

View File

@ -1054,6 +1054,19 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
std::vector<cmSourceFile const*> externalObjects; std::vector<cmSourceFile const*> externalObjects;
this->GeneratorTarget->GetExternalObjects(externalObjects); this->GeneratorTarget->GetExternalObjects(externalObjects);
for(std::vector<cmSourceFile const*>::iterator
si = externalObjects.begin();
si != externalObjects.end(); )
{
if (!(*si)->GetObjectLibrary().empty())
{
si = externalObjects.erase(si);
}
else
{
++si;
}
}
if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10) if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10)
{ {
// For VS >= 11 we use LinkObjects to avoid linking custom command // For VS >= 11 we use LinkObjects to avoid linking custom command

View File

@ -166,7 +166,7 @@ add_library(imported4 SHARED IMPORTED)
set_property(TARGET imported4 APPEND PROPERTY set_property(TARGET imported4 APPEND PROPERTY
INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>) INCLUDE_DIRECTORIES $<TARGET_PROPERTY:imported3,INTERFACE_INCLUDE_DIRECTORIES>)
add_executable(someexe empty.cpp) add_executable(someexe $<1:empty.cpp> $<0:does_not_exist>)
add_executable(Alias::SomeExe ALIAS someexe) add_executable(Alias::SomeExe ALIAS someexe)
add_library(Alias::SomeLib ALIAS empty1) add_library(Alias::SomeLib ALIAS empty1)

View File

@ -1,6 +1,8 @@
CMake Error at BadSourceExpression1.cmake:1 \(add_library\): CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
Unrecognized generator expression: Error evaluating generator expression:
\$<BAD_EXPRESSION> \$<BAD_EXPRESSION>
Expression did not evaluate to a known generator expression
Call Stack \(most recent call first\): Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\) CMakeLists.txt:3 \(include\)