Merge topic 'target-sources-refactor'
5de63265
Genex: Only evaluate TARGET_OBJECTS to determine target sources.aa0a3562
cmGeneratorTarget: Compute target objects on demand042c1c83
cmTarget: Compute languages from object libraries on demand.fdcefe3c
cmGeneratorTarget: Compute consumed object libraries on demand.c355d108
cmComputeTargetDepends: Track object library depends.e5da9e51
cmTarget: Allow any generator expression in SOURCES property.5702e106
cmTarget: Include TARGET_OBJECTS genex in target SOURCES property.857d30b5
cmGlobalGenerator: Add interface to call ForceLinkerLanguages28e1d2f8
cmStringCommand: Add GENEX_STRIP subcommand.bf98cc25
Genex: Evaluate TARGET_OBJECTS as a normal expression.8cd113ad
cmTarget: Store strings instead of cmSourceFile* to represent SOURCES.4959f341
cmSourceFileLocation: Collapse full path for directory comparisons.fcc92878
cmSourceFileLocation: Remove unused Update method.59e8740a
cmTarget: Remove AddSourceFile method26d494ba
cmTarget: Use string API to add sources to cmTarget objects.d38423ec
cmTarget: Add a method to obtain list of filenames for sources. ...
This commit is contained in:
commit
93054aa84f
|
@ -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.
|
||||
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ String operations.
|
|||
string(FIND <string> <substring> <output variable> [REVERSE])
|
||||
string(TIMESTAMP <output variable> [<format string>] [UTC])
|
||||
string(MAKE_C_IDENTIFIER <input string> <output variable>)
|
||||
string(GENEX_STRIP <input string> <output variable>)
|
||||
|
||||
REGEX MATCH will match the regular expression once and store the match
|
||||
in the output variable.
|
||||
|
@ -154,3 +155,7 @@ If no explicit <format string> is given it will default to:
|
|||
|
||||
MAKE_C_IDENTIFIER will write a string which can be used as an
|
||||
identifier in C.
|
||||
|
||||
``GENEX_STRIP`` will strip any
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>` from the
|
||||
``input string`` and store the result in the ``output variable``.
|
||||
|
|
|
@ -188,3 +188,8 @@ property is non-empty::
|
|||
Content of ``...`` converted to upper case.
|
||||
``$<MAKE_C_IDENTIFIER:...>``
|
||||
Content of ``...`` converted to a C identifier.
|
||||
``$<TARGET_OBJECTS:objLib>``
|
||||
List of objects resulting from build of ``objLib``. ``objLib`` must be an
|
||||
object of type ``OBJECT_LIBRARY``. This expression may only be used in
|
||||
the sources of :command:`add_library` and :command:`add_executable`
|
||||
commands.
|
||||
|
|
|
@ -102,3 +102,4 @@ All Policies
|
|||
/policy/CMP0048
|
||||
/policy/CMP0049
|
||||
/policy/CMP0050
|
||||
/policy/CMP0051
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
CMP0051
|
||||
-------
|
||||
|
||||
List TARGET_OBJECTS in SOURCES target property.
|
||||
|
||||
CMake 3.0 and lower did not include the ``TARGET_OBJECTS``
|
||||
:manual:`generator expression <cmake-generator-expressions(7)>` when
|
||||
returning the :prop_tgt:`SOURCES` target property.
|
||||
|
||||
Configure-time CMake code is not able to handle generator expressions. If
|
||||
using the :prop_tgt:`SOURCES` target property at configure time, it may be
|
||||
necessary to first remove generator expressions using the
|
||||
:command:`string(STRIP_GENEX)` command. Generate-time CMake code such as
|
||||
:command:`file(GENERATE)` can handle the content without stripping.
|
||||
|
||||
The ``OLD`` behavior for this policy is to omit ``TARGET_OBJECTS``
|
||||
expressions from the :prop_tgt:`SOURCES` target property. The ``NEW``
|
||||
behavior for this policy is to include ``TARGET_OBJECTS`` expressions
|
||||
in the output.
|
||||
|
||||
This policy was introduced in CMake version 3.1.
|
||||
CMake version |release| warns when the policy is not set and uses
|
||||
``OLD`` behavior. Use the :command:`cmake_policy` command to set it
|
||||
to ``OLD`` or ``NEW`` explicitly.
|
|
@ -0,0 +1,6 @@
|
|||
string-GENEX_STRIP
|
||||
------------------
|
||||
|
||||
* The :command:`string` command learned a new ``GENEX_STRIP`` subcommand
|
||||
which removes
|
||||
:manual:`generator expression <cmake-generator-expressions(7)>`.
|
|
@ -0,0 +1,12 @@
|
|||
target-SOURCES-genex
|
||||
--------------------
|
||||
|
||||
* The :prop_tgt:`SOURCES` target property now contains
|
||||
:manual:`generator expression <cmake-generator-expressions(7)>`
|
||||
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 <cmake-generator-expressions(7)>`. The
|
||||
generator expressions may be used in the :command:`add_library` and
|
||||
:command:`add_executable` commands.
|
|
@ -16,6 +16,7 @@
|
|||
#include "cmLocalGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmake.h"
|
||||
|
||||
|
@ -213,6 +214,34 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
|
|||
{
|
||||
std::set<std::string> emitted;
|
||||
{
|
||||
cmGeneratorTarget* gt = depender->GetMakefile()->GetLocalGenerator()
|
||||
->GetGlobalGenerator()
|
||||
->GetGeneratorTarget(depender);
|
||||
std::vector<cmSourceFile const*> objectFiles;
|
||||
gt->GetExternalObjects(objectFiles);
|
||||
for(std::vector<cmSourceFile const*>::const_iterator
|
||||
it = objectFiles.begin(); it != objectFiles.end(); ++it)
|
||||
{
|
||||
std::string objLib = (*it)->GetObjectLibrary();
|
||||
if (!objLib.empty() && emitted.insert(objLib).second)
|
||||
{
|
||||
if(depender->GetType() != cmTarget::EXECUTABLE &&
|
||||
depender->GetType() != cmTarget::STATIC_LIBRARY &&
|
||||
depender->GetType() != cmTarget::SHARED_LIBRARY &&
|
||||
depender->GetType() != cmTarget::MODULE_LIBRARY)
|
||||
{
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR,
|
||||
"Only executables and non-OBJECT libraries may "
|
||||
"reference target objects.",
|
||||
depender->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
const_cast<cmTarget*>(depender)->AddUtility(objLib);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::string> tlibs;
|
||||
depender->GetDirectLinkLibraries("", tlibs, depender);
|
||||
// A target should not depend on itself.
|
||||
|
|
|
@ -168,7 +168,7 @@ void cmFLTKWrapUICommand::FinalPass()
|
|||
for(size_t classNum = 0; classNum < lastHeadersClass; classNum++)
|
||||
{
|
||||
this->Makefile->GetTargets()[this->Target]
|
||||
.AddSourceFile(this->GeneratedSourcesClasses[classNum]);
|
||||
.AddSource(this->GeneratedSourcesClasses[classNum]->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
|||
context.HadError = false;
|
||||
context.HadContextSensitiveCondition = false;
|
||||
context.HeadTarget = headTarget;
|
||||
context.EvaluateForBuildsystem = this->EvaluateForBuildsystem;
|
||||
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
|
||||
context.Backtrace = this->Backtrace;
|
||||
|
||||
|
@ -124,7 +125,8 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
|
|||
cmListFileBacktrace const& backtrace,
|
||||
const std::string& input)
|
||||
: Backtrace(backtrace), Input(input),
|
||||
HadContextSensitiveCondition(false)
|
||||
HadContextSensitiveCondition(false),
|
||||
EvaluateForBuildsystem(false)
|
||||
{
|
||||
cmGeneratorExpressionLexer l;
|
||||
std::vector<cmGeneratorExpressionToken> tokens =
|
||||
|
|
|
@ -112,6 +112,11 @@ public:
|
|||
return this->HadContextSensitiveCondition;
|
||||
}
|
||||
|
||||
void SetEvaluateForBuildsystem(bool eval)
|
||||
{
|
||||
this->EvaluateForBuildsystem = eval;
|
||||
}
|
||||
|
||||
private:
|
||||
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
|
||||
const std::string& input);
|
||||
|
@ -131,6 +136,7 @@ private:
|
|||
mutable std::set<std::string> SeenTargetProperties;
|
||||
mutable std::string Output;
|
||||
mutable bool HadContextSensitiveCondition;
|
||||
bool EvaluateForBuildsystem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "cmGeneratorExpressionParser.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmSourceFile.h"
|
||||
|
||||
#include <cmsys/String.h>
|
||||
|
||||
|
@ -1239,6 +1241,77 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
|
|||
|
||||
} targetNameNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const struct TargetObjectsNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
TargetObjectsNode() {}
|
||||
|
||||
std::string Evaluate(const std::vector<std::string> ¶meters,
|
||||
cmGeneratorExpressionContext *context,
|
||||
const GeneratorExpressionContent *content,
|
||||
cmGeneratorExpressionDAGChecker *) const
|
||||
{
|
||||
if (!context->EvaluateForBuildsystem)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "The evaluation of the TARGET_OBJECTS generator expression "
|
||||
"is only suitable for consumption by CMake. It is not suitable "
|
||||
"for writing out elsewhere.";
|
||||
reportError(context, content->GetOriginalExpression(), e.str());
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string tgtName = parameters.front();
|
||||
cmGeneratorTarget* gt =
|
||||
context->Makefile->FindGeneratorTargetToUse(tgtName.c_str());
|
||||
if (!gt)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Objects of target \"" << tgtName
|
||||
<< "\" referenced but no such target exists.";
|
||||
reportError(context, content->GetOriginalExpression(), e.str());
|
||||
return std::string();
|
||||
}
|
||||
if (gt->GetType() != cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Objects of target \"" << tgtName
|
||||
<< "\" referenced but is not an OBJECT library.";
|
||||
reportError(context, content->GetOriginalExpression(), e.str());
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
gt->GetObjectSources(objectSources);
|
||||
std::map<cmSourceFile const*, std::string> mapping;
|
||||
|
||||
for(std::vector<cmSourceFile const*>::const_iterator it
|
||||
= objectSources.begin(); it != objectSources.end(); ++it)
|
||||
{
|
||||
mapping[*it];
|
||||
}
|
||||
|
||||
gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
|
||||
|
||||
std::string obj_dir = gt->ObjectDirectory;
|
||||
std::string result;
|
||||
const char* sep = "";
|
||||
for(std::map<cmSourceFile const*, std::string>::const_iterator it
|
||||
= mapping.begin(); it != mapping.end(); ++it)
|
||||
{
|
||||
assert(!it->second.empty());
|
||||
result += sep;
|
||||
std::string objFile = obj_dir + it->second;
|
||||
cmSourceFile* sf = context->Makefile->GetOrCreateSource(objFile, true);
|
||||
sf->SetObjectLibrary(tgtName);
|
||||
sf->SetProperty("EXTERNAL_OBJECT", "1");
|
||||
result += objFile;
|
||||
sep = ";";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} targetObjectsNode;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const char* targetPolicyWhitelist[] = {
|
||||
0
|
||||
|
@ -1593,6 +1666,7 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
|
|||
nodeMap["SEMICOLON"] = &semicolonNode;
|
||||
nodeMap["TARGET_PROPERTY"] = &targetPropertyNode;
|
||||
nodeMap["TARGET_NAME"] = &targetNameNode;
|
||||
nodeMap["TARGET_OBJECTS"] = &targetObjectsNode;
|
||||
nodeMap["TARGET_POLICY"] = &targetPolicyNode;
|
||||
nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode;
|
||||
nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode;
|
||||
|
|
|
@ -34,6 +34,7 @@ struct cmGeneratorExpressionContext
|
|||
bool Quiet;
|
||||
bool HadError;
|
||||
bool HadContextSensitiveCondition;
|
||||
bool EvaluateForBuildsystem;
|
||||
};
|
||||
|
||||
struct cmGeneratorExpressionDAGChecker;
|
||||
|
|
|
@ -311,20 +311,38 @@ cmGeneratorTarget
|
|||
::GetObjectSources(std::vector<cmSourceFile const*> &data) const
|
||||
{
|
||||
IMPLEMENT_VISIT(ObjectSources);
|
||||
|
||||
if (!this->Objects.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(std::vector<cmSourceFile const*>::const_iterator it = data.begin();
|
||||
it != data.end(); ++it)
|
||||
{
|
||||
this->Objects[*it];
|
||||
}
|
||||
|
||||
this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::ComputeObjectMapping()
|
||||
{
|
||||
if(!this->Objects.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::vector<cmSourceFile const*> sourceFiles;
|
||||
this->GetObjectSources(sourceFiles);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const std::string& cmGeneratorTarget::GetObjectName(cmSourceFile const* file)
|
||||
{
|
||||
this->ComputeObjectMapping();
|
||||
return this->Objects[file];
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::AddObject(cmSourceFile const* sf,
|
||||
std::string const&name)
|
||||
{
|
||||
this->Objects[sf] = name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
|
||||
{
|
||||
|
@ -334,6 +352,7 @@ void cmGeneratorTarget::AddExplicitObjectName(cmSourceFile const* sf)
|
|||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
|
||||
{
|
||||
const_cast<cmGeneratorTarget*>(this)->ComputeObjectMapping();
|
||||
std::set<cmSourceFile const*>::const_iterator it
|
||||
= this->ExplicitObjectName.find(file);
|
||||
return it != this->ExplicitObjectName.end();
|
||||
|
@ -503,58 +522,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
|||
this->Target->GetSourceFiles(files);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorTarget::LookupObjectLibraries()
|
||||
{
|
||||
std::vector<std::string> const& objLibs =
|
||||
this->Target->GetObjectLibraries();
|
||||
for(std::vector<std::string>::const_iterator oli = objLibs.begin();
|
||||
oli != objLibs.end(); ++oli)
|
||||
{
|
||||
std::string const& objLibName = *oli;
|
||||
if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName))
|
||||
{
|
||||
if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
if(this->Target->GetType() != cmTarget::EXECUTABLE &&
|
||||
this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
|
||||
this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
|
||||
this->Target->GetType() != cmTarget::MODULE_LIBRARY)
|
||||
{
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR,
|
||||
"Only executables and non-OBJECT libraries may "
|
||||
"reference target objects.",
|
||||
this->Target->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
this->Target->AddUtility(objLib->GetName());
|
||||
this->ObjectLibraries.push_back(objLib);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Objects of target \"" << objLibName
|
||||
<< "\" referenced but is not an OBJECT library.";
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||
this->Target->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Objects of target \"" << objLibName
|
||||
<< "\" referenced but no such target exists.";
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||
this->Target->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmGeneratorTarget::GetModuleDefinitionFile() const
|
||||
{
|
||||
|
@ -567,9 +534,26 @@ std::string cmGeneratorTarget::GetModuleDefinitionFile() const
|
|||
void
|
||||
cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
|
||||
{
|
||||
std::vector<cmSourceFile const*> objectFiles;
|
||||
this->GetExternalObjects(objectFiles);
|
||||
std::vector<cmTarget*> objectLibraries;
|
||||
std::set<cmTarget*> emitted;
|
||||
for(std::vector<cmSourceFile const*>::const_iterator
|
||||
it = objectFiles.begin(); it != objectFiles.end(); ++it)
|
||||
{
|
||||
std::string objLib = (*it)->GetObjectLibrary();
|
||||
if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
|
||||
{
|
||||
if (emitted.insert(tgt).second)
|
||||
{
|
||||
objectLibraries.push_back(tgt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
ti = this->ObjectLibraries.begin();
|
||||
ti != this->ObjectLibraries.end(); ++ti)
|
||||
ti = objectLibraries.begin();
|
||||
ti != objectLibraries.end(); ++ti)
|
||||
{
|
||||
cmTarget* objLib = *ti;
|
||||
cmGeneratorTarget* ogt =
|
||||
|
@ -600,12 +584,12 @@ private:
|
|||
cmGlobalGenerator const* GlobalGenerator;
|
||||
typedef cmGeneratorTarget::SourceEntry SourceEntry;
|
||||
SourceEntry* CurrentEntry;
|
||||
std::queue<cmSourceFile*> SourceQueue;
|
||||
std::set<cmSourceFile*> SourcesQueued;
|
||||
std::queue<std::string> SourceQueue;
|
||||
std::set<std::string> SourcesQueued;
|
||||
typedef std::map<std::string, cmSourceFile*> NameMapType;
|
||||
NameMapType NameMap;
|
||||
|
||||
void QueueSource(cmSourceFile* sf);
|
||||
void QueueSource(std::string const& name);
|
||||
void FollowName(std::string const& name);
|
||||
void FollowNames(std::vector<std::string> const& names);
|
||||
bool IsUtility(std::string const& dep);
|
||||
|
@ -628,11 +612,11 @@ cmTargetTraceDependencies
|
|||
this->CurrentEntry = 0;
|
||||
|
||||
// Queue all the source files already specified for the target.
|
||||
std::vector<cmSourceFile*> sources;
|
||||
if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
std::vector<std::string> sources;
|
||||
this->Target->GetSourceFiles(sources);
|
||||
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
|
||||
for(std::vector<std::string>::const_iterator si = sources.begin();
|
||||
si != sources.end(); ++si)
|
||||
{
|
||||
this->QueueSource(*si);
|
||||
|
@ -652,7 +636,8 @@ void cmTargetTraceDependencies::Trace()
|
|||
while(!this->SourceQueue.empty())
|
||||
{
|
||||
// Get the next source from the queue.
|
||||
cmSourceFile* sf = this->SourceQueue.front();
|
||||
std::string src = this->SourceQueue.front();
|
||||
cmSourceFile* sf = this->Makefile->GetSource(src);
|
||||
this->SourceQueue.pop();
|
||||
this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
|
||||
|
||||
|
@ -680,14 +665,14 @@ void cmTargetTraceDependencies::Trace()
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTargetTraceDependencies::QueueSource(cmSourceFile* sf)
|
||||
void cmTargetTraceDependencies::QueueSource(std::string const& name)
|
||||
{
|
||||
if(this->SourcesQueued.insert(sf).second)
|
||||
if(this->SourcesQueued.insert(name).second)
|
||||
{
|
||||
this->SourceQueue.push(sf);
|
||||
this->SourceQueue.push(name);
|
||||
|
||||
// Make sure this file is in the target.
|
||||
this->Target->AddSourceFile(sf);
|
||||
this->Target->AddSource(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -709,8 +694,7 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
|
|||
{
|
||||
this->CurrentEntry->Depends.push_back(sf);
|
||||
}
|
||||
|
||||
this->QueueSource(sf);
|
||||
this->QueueSource(sf->GetFullPath());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ public:
|
|||
void GetObjectSources(std::vector<cmSourceFile const*> &) const;
|
||||
const std::string& GetObjectName(cmSourceFile const* file);
|
||||
|
||||
void AddObject(cmSourceFile const* sf, std::string const&name);
|
||||
bool HasExplicitObjectName(cmSourceFile const* file) const;
|
||||
void AddExplicitObjectName(cmSourceFile const* sf);
|
||||
|
||||
|
@ -47,6 +46,8 @@ public:
|
|||
void GetCustomCommands(std::vector<cmSourceFile const*>&) const;
|
||||
void GetExpectedResxHeaders(std::set<std::string>&) const;
|
||||
|
||||
void ComputeObjectMapping();
|
||||
|
||||
cmTarget* Target;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalGenerator* LocalGenerator;
|
||||
|
@ -84,8 +85,6 @@ public:
|
|||
*/
|
||||
void TraceDependencies();
|
||||
|
||||
void LookupObjectLibraries();
|
||||
|
||||
/** Get sources that must be built before the given source. */
|
||||
std::vector<cmSourceFile*> const*
|
||||
GetSourceDepends(cmSourceFile const* sf) const;
|
||||
|
@ -125,9 +124,8 @@ private:
|
|||
typedef std::map<cmSourceFile const*, SourceEntry> SourceEntriesType;
|
||||
SourceEntriesType SourceEntries;
|
||||
|
||||
std::map<cmSourceFile const*, std::string> Objects;
|
||||
mutable std::map<cmSourceFile const*, std::string> Objects;
|
||||
std::set<cmSourceFile const*> ExplicitObjectName;
|
||||
std::vector<cmTarget*> ObjectLibraries;
|
||||
mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
|
||||
|
||||
void ConstructSourceFileFlags() const;
|
||||
|
|
|
@ -216,6 +216,11 @@ bool cmGlobalGenerator::GenerateImportFile(const std::string &file)
|
|||
return false;
|
||||
}
|
||||
|
||||
void cmGlobalGenerator::ForceLinkerLanguages()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const
|
||||
{
|
||||
|
@ -1196,6 +1201,8 @@ void cmGlobalGenerator::Generate()
|
|||
// Create per-target generator information.
|
||||
this->CreateGeneratorTargets();
|
||||
|
||||
this->ForceLinkerLanguages();
|
||||
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
for (AutogensType::iterator it = autogens.begin(); it != autogens.end();
|
||||
++it)
|
||||
|
@ -1217,8 +1224,6 @@ void cmGlobalGenerator::Generate()
|
|||
this->LocalGenerators[i]->GenerateTargetManifest();
|
||||
}
|
||||
|
||||
this->ComputeGeneratorTargetObjects();
|
||||
|
||||
this->ProcessEvaluationFiles();
|
||||
|
||||
// Compute the inter-target dependencies.
|
||||
|
@ -1409,6 +1414,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(cmMakefile *mf)
|
|||
{
|
||||
cmTarget* t = &ti->second;
|
||||
cmGeneratorTarget* gt = new cmGeneratorTarget(t);
|
||||
this->ComputeTargetObjectDirectory(gt);
|
||||
this->GeneratorTargets[t] = gt;
|
||||
generatorTargets[t] = gt;
|
||||
}
|
||||
|
@ -1434,29 +1440,6 @@ void cmGlobalGenerator::CreateGeneratorTargets()
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::ComputeGeneratorTargetObjects()
|
||||
{
|
||||
// Construct per-target generator information.
|
||||
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
|
||||
{
|
||||
cmMakefile *mf = this->LocalGenerators[i]->GetMakefile();
|
||||
cmGeneratorTargetsType targets = mf->GetGeneratorTargets();
|
||||
for(cmGeneratorTargetsType::iterator ti = targets.begin();
|
||||
ti != targets.end(); ++ti)
|
||||
{
|
||||
if (ti->second->Target->IsImported()
|
||||
|| ti->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cmGeneratorTarget* gt = ti->second;
|
||||
this->ComputeTargetObjectDirectory(gt);
|
||||
gt->LookupObjectLibraries();
|
||||
this->ComputeTargetObjects(gt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::ClearGeneratorMembers()
|
||||
|
@ -1517,29 +1500,6 @@ cmGlobalGenerator::GetGeneratorTarget(cmTarget const* t) const
|
|||
return ti->second;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
|
||||
{
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
gt->GetObjectSources(objectSources);
|
||||
|
||||
std::map<cmSourceFile const*, std::string> mapping;
|
||||
for(std::vector<cmSourceFile const*>::const_iterator it
|
||||
= objectSources.begin(); it != objectSources.end(); ++it)
|
||||
{
|
||||
mapping[*it];
|
||||
}
|
||||
|
||||
gt->LocalGenerator->ComputeObjectFilenames(mapping, gt);
|
||||
|
||||
for(std::map<cmSourceFile const*, std::string>::const_iterator it
|
||||
= mapping.begin(); it != mapping.end(); ++it)
|
||||
{
|
||||
assert(!it->second.empty());
|
||||
gt->AddObject(it->first, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::ComputeTargetObjectDirectory(cmGeneratorTarget*) const
|
||||
{
|
||||
|
|
|
@ -423,6 +423,8 @@ private:
|
|||
void WriteSummary(cmTarget* target);
|
||||
void FinalizeTargetCompileInfo();
|
||||
|
||||
virtual void ForceLinkerLanguages();
|
||||
|
||||
virtual void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
|
||||
const char* envVar) const;
|
||||
void CheckCompilerIdCompatibility(cmMakefile* mf,
|
||||
|
@ -442,8 +444,6 @@ private:
|
|||
friend class cmake;
|
||||
void CreateGeneratorTargets(cmMakefile* mf);
|
||||
void CreateGeneratorTargets();
|
||||
void ComputeGeneratorTargetObjects();
|
||||
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||
|
||||
void ClearGeneratorMembers();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "cmVisualStudioWCEPlatformParser.h"
|
||||
#include "cmake.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmSourceFile.h"
|
||||
|
||||
static const char vs8generatorName[] = "Visual Studio 8 2005";
|
||||
|
||||
|
@ -323,7 +324,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
|
|||
no_main_dependency, commandLines, "Checking Build System",
|
||||
no_working_directory, true))
|
||||
{
|
||||
tgt->AddSourceFile(file);
|
||||
tgt->AddSource(file->GetFullPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -343,7 +343,6 @@ void cmGlobalXCodeGenerator::Generate()
|
|||
// add ALL_BUILD, INSTALL, etc
|
||||
this->AddExtraTargets(root, it->second);
|
||||
}
|
||||
this->ForceLinkerLanguages();
|
||||
this->cmGlobalGenerator::Generate();
|
||||
if(cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
|
@ -412,7 +411,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
|||
std::string listfile = mf->GetStartDirectory();
|
||||
listfile += "/";
|
||||
listfile += "CMakeLists.txt";
|
||||
allbuild->AddSource(listfile.c_str());
|
||||
allbuild->AddSourceCMP0049(listfile.c_str());
|
||||
|
||||
// Add XCODE depend helper
|
||||
std::string dir = mf->GetCurrentOutputDirectory();
|
||||
|
@ -495,7 +494,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
|||
listfile = lg->GetMakefile()->GetStartDirectory();
|
||||
listfile += "/";
|
||||
listfile += "CMakeLists.txt";
|
||||
target.AddSource(listfile.c_str());
|
||||
target.AddSourceCMP0049(listfile.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -988,6 +987,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
cmtarget.GetSourceFiles(classes);
|
||||
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
|
||||
|
||||
gtgt->ComputeObjectMapping();
|
||||
|
||||
std::vector<cmXCodeObject*> externalObjFiles;
|
||||
std::vector<cmXCodeObject*> headerFiles;
|
||||
std::vector<cmXCodeObject*> resourceFiles;
|
||||
|
@ -1008,7 +1009,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) ||
|
||||
|
@ -1260,7 +1264,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
|
|||
if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
|
||||
{
|
||||
sf->SetProperty("LANGUAGE", llang.c_str());
|
||||
cmtarget.AddSourceFile(sf);
|
||||
cmtarget.AddSource(fname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2934,8 +2938,8 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
|
|||
if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"))
|
||||
{
|
||||
std::string plist = this->ComputeInfoPListLocation(cmtarget);
|
||||
cmSourceFile* sf = mf->GetOrCreateSource(plist.c_str(), true);
|
||||
cmtarget.AddSourceFile(sf);
|
||||
mf->GetOrCreateSource(plist, true);
|
||||
cmtarget.AddSource(plist);
|
||||
}
|
||||
|
||||
std::vector<cmSourceFile*> classes;
|
||||
|
|
|
@ -751,8 +751,8 @@ void cmLocalGenerator::AddBuildTargetRule(const std::string& llang,
|
|||
comment.c_str(),
|
||||
this->Makefile->GetStartOutputDirectory()
|
||||
);
|
||||
target.Target->AddSourceFile
|
||||
(this->Makefile->GetSource(targetFullPath));
|
||||
this->Makefile->GetSource(targetFullPath);
|
||||
target.Target->AddSource(targetFullPath);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -253,9 +253,9 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule(cmTarget& tgt)
|
|||
makefileIn.c_str(), commandLines,
|
||||
comment.c_str(),
|
||||
no_working_directory, true);
|
||||
if(cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str()))
|
||||
if(this->Makefile->GetSource(makefileIn.c_str()))
|
||||
{
|
||||
tgt.AddSourceFile(file);
|
||||
tgt.AddSource(makefileIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -324,6 +324,11 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
|||
for(std::vector<cmSourceFile*>::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 cmSourceFile *>::const_iterator sf =
|
||||
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
|
||||
{
|
||||
if (!(*sf)->GetObjectLibrary().empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string source = (*sf)->GetFullPath();
|
||||
const cmCustomCommand *command =
|
||||
(*sf)->GetCustomCommand();
|
||||
|
@ -591,7 +601,7 @@ cmLocalVisualStudio6Generator
|
|||
origCommand.GetCommandLines(), comment,
|
||||
origCommand.GetWorkingDirectory().c_str()))
|
||||
{
|
||||
target.AddSourceFile(outsf);
|
||||
target.AddSource(outsf->GetFullPath());
|
||||
}
|
||||
|
||||
// Replace the dependencies with the output of this rule so that the
|
||||
|
|
|
@ -117,7 +117,7 @@ void cmLocalVisualStudio7Generator::AddCMakeListsRules()
|
|||
{
|
||||
if(l->first != CMAKE_CHECK_BUILD_SYSTEM_TARGET)
|
||||
{
|
||||
l->second.AddSourceFile(sf);
|
||||
l->second.AddSource(sf->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
|
|||
force.c_str(), no_depends, no_main_dependency,
|
||||
force_commands, " ", 0, true))
|
||||
{
|
||||
tgt.AddSourceFile(file);
|
||||
tgt.AddSource(file->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1401,6 +1401,10 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
|||
for(std::vector<cmSourceFile*>::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")
|
||||
|
|
|
@ -1182,7 +1182,7 @@ cmMakefile::AddCustomCommandOldStyle(const std::string& target,
|
|||
{
|
||||
if (this->Targets.find(target) != this->Targets.end())
|
||||
{
|
||||
this->Targets[target].AddSourceFile(sf);
|
||||
this->Targets[target].AddSource(sf->GetFullPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1266,7 +1266,7 @@ cmMakefile::AddUtilityCommand(const std::string& utilityName,
|
|||
commandLines, comment,
|
||||
workingDirectory, no_replace,
|
||||
escapeOldStyle);
|
||||
cmSourceFile* sf = target->AddSource(force);
|
||||
cmSourceFile* sf = target->AddSourceCMP0049(force);
|
||||
|
||||
// The output is not actually created so mark it symbolic.
|
||||
if(sf)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -525,17 +525,6 @@ cmNinjaTargetGenerator
|
|||
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";
|
||||
}
|
||||
|
||||
|
|
|
@ -343,6 +343,11 @@ cmPolicies::cmPolicies()
|
|||
CMP0050, "CMP0050",
|
||||
"Disallow add_custom_command SOURCE signatures.",
|
||||
3,0,0, cmPolicies::WARN);
|
||||
|
||||
this->DefinePolicy(
|
||||
CMP0051, "CMP0051",
|
||||
"List TARGET_OBJECTS in SOURCES target property.",
|
||||
3,1,0, cmPolicies::WARN);
|
||||
}
|
||||
|
||||
cmPolicies::~cmPolicies()
|
||||
|
|
|
@ -104,6 +104,7 @@ public:
|
|||
CMP0048, ///< project() command manages VERSION variables
|
||||
CMP0049, ///< Do not expand variables in target source entries
|
||||
CMP0050, ///< Disallow add_custom_command SOURCE signatures
|
||||
CMP0051, ///< List TARGET_OBJECTS in SOURCES target property
|
||||
|
||||
/** \brief Always the last entry.
|
||||
*
|
||||
|
|
|
@ -187,13 +187,11 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmTarget* target)
|
|||
mocCppFile += "/";
|
||||
mocCppFile += automocTargetName;
|
||||
mocCppFile += ".cpp";
|
||||
cmSourceFile* mocCppSource = makefile->GetOrCreateSource(
|
||||
mocCppFile,
|
||||
true);
|
||||
makefile->GetOrCreateSource(mocCppFile, true);
|
||||
makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
|
||||
mocCppFile.c_str(), false);
|
||||
|
||||
target->AddSourceFile(mocCppSource);
|
||||
target->AddSource(mocCppFile);
|
||||
}
|
||||
// create a custom target for running generators at buildtime:
|
||||
std::string autogenTargetName = getAutogenTargetName(target);
|
||||
|
@ -479,7 +477,7 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
|
|||
const char *skipMocSep = "";
|
||||
const char *skipUicSep = "";
|
||||
|
||||
std::vector<cmSourceFile*> newRccFiles;
|
||||
std::vector<std::string> newRccFiles;
|
||||
|
||||
for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
|
||||
fileIt != srcFiles.end();
|
||||
|
@ -512,9 +510,8 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
|
|||
rcc_output_file += "/qrc_" + basename + ".cpp";
|
||||
makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
|
||||
rcc_output_file.c_str(), false);
|
||||
cmSourceFile* rccCppSource
|
||||
= makefile->GetOrCreateSource(rcc_output_file, true);
|
||||
newRccFiles.push_back(rccCppSource);
|
||||
makefile->GetOrCreateSource(rcc_output_file, true);
|
||||
newRccFiles.push_back(rcc_output_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,11 +543,11 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target)
|
|||
}
|
||||
}
|
||||
|
||||
for(std::vector<cmSourceFile*>::const_iterator fileIt = newRccFiles.begin();
|
||||
for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
|
||||
fileIt != newRccFiles.end();
|
||||
++fileIt)
|
||||
{
|
||||
const_cast<cmTarget*>(target)->AddSourceFile(*fileIt);
|
||||
const_cast<cmTarget*>(target)->AddSource(*fileIt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,18 @@ std::string const& cmSourceFile::GetExtension() const
|
|||
return this->Extension;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSourceFile::SetObjectLibrary(std::string const& objlib)
|
||||
{
|
||||
this->ObjectLibrary = objlib;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmSourceFile::GetObjectLibrary() const
|
||||
{
|
||||
return this->ObjectLibrary;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string cmSourceFile::GetLanguage()
|
||||
{
|
||||
|
|
|
@ -97,6 +97,9 @@ public:
|
|||
*/
|
||||
bool Matches(cmSourceFileLocation const&);
|
||||
|
||||
void SetObjectLibrary(std::string const& objlib);
|
||||
std::string GetObjectLibrary() const;
|
||||
|
||||
private:
|
||||
cmSourceFileLocation Location;
|
||||
cmPropertyMap Properties;
|
||||
|
@ -105,6 +108,7 @@ private:
|
|||
std::string Language;
|
||||
std::string FullPath;
|
||||
bool FindFullPathFailed;
|
||||
std::string ObjectLibrary;
|
||||
|
||||
bool FindFullPath(std::string* error);
|
||||
bool TryFullPath(const std::string& path, const std::string& ext);
|
||||
|
|
|
@ -16,6 +16,42 @@
|
|||
#include "cmGlobalGenerator.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmSourceFileLocation::cmSourceFileLocation()
|
||||
: Makefile(0), AmbiguousDirectory(true), AmbiguousExtension(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmSourceFileLocation::cmSourceFileLocation(const cmSourceFileLocation& loc)
|
||||
: Makefile(loc.Makefile)
|
||||
{
|
||||
this->AmbiguousDirectory = loc.AmbiguousDirectory;
|
||||
this->AmbiguousExtension = loc.AmbiguousExtension;
|
||||
this->Directory = loc.Directory;
|
||||
this->Name = loc.Name;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmSourceFileLocation&
|
||||
cmSourceFileLocation::operator=(const cmSourceFileLocation& loc)
|
||||
{
|
||||
if(this == &loc)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
this->Makefile = loc.Makefile;
|
||||
this->AmbiguousDirectory = loc.AmbiguousDirectory;
|
||||
this->AmbiguousExtension = loc.AmbiguousExtension;
|
||||
this->Directory = loc.Directory;
|
||||
this->Name = loc.Name;
|
||||
this->UpdateExtension(this->Name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmSourceFileLocation
|
||||
::cmSourceFileLocation(cmMakefile const* mf, const std::string& name)
|
||||
|
@ -24,23 +60,15 @@ cmSourceFileLocation
|
|||
this->AmbiguousDirectory = !cmSystemTools::FileIsFullPath(name.c_str());
|
||||
this->AmbiguousExtension = true;
|
||||
this->Directory = cmSystemTools::GetFilenamePath(name);
|
||||
if (cmSystemTools::FileIsFullPath(this->Directory.c_str()))
|
||||
{
|
||||
this->Directory
|
||||
= cmSystemTools::CollapseFullPath(this->Directory.c_str());
|
||||
}
|
||||
this->Name = cmSystemTools::GetFilenameName(name);
|
||||
this->UpdateExtension(name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSourceFileLocation::Update(const std::string& name)
|
||||
{
|
||||
if(this->AmbiguousDirectory)
|
||||
{
|
||||
this->UpdateDirectory(name);
|
||||
}
|
||||
if(this->AmbiguousExtension)
|
||||
{
|
||||
this->UpdateExtension(name);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
|
||||
{
|
||||
|
@ -59,6 +87,7 @@ void cmSourceFileLocation::Update(cmSourceFileLocation const& loc)
|
|||
//----------------------------------------------------------------------------
|
||||
void cmSourceFileLocation::DirectoryUseSource()
|
||||
{
|
||||
assert(this->Makefile);
|
||||
if(this->AmbiguousDirectory)
|
||||
{
|
||||
this->Directory =
|
||||
|
@ -71,6 +100,7 @@ void cmSourceFileLocation::DirectoryUseSource()
|
|||
//----------------------------------------------------------------------------
|
||||
void cmSourceFileLocation::DirectoryUseBinary()
|
||||
{
|
||||
assert(this->Makefile);
|
||||
if(this->AmbiguousDirectory)
|
||||
{
|
||||
this->Directory =
|
||||
|
@ -83,6 +113,7 @@ void cmSourceFileLocation::DirectoryUseBinary()
|
|||
//----------------------------------------------------------------------------
|
||||
void cmSourceFileLocation::UpdateExtension(const std::string& name)
|
||||
{
|
||||
assert(this->Makefile);
|
||||
// Check the extension.
|
||||
std::string ext = cmSystemTools::GetFilenameLastExtension(name);
|
||||
if(!ext.empty()) { ext = ext.substr(1); }
|
||||
|
@ -136,22 +167,12 @@ void cmSourceFileLocation::UpdateExtension(const std::string& name)
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSourceFileLocation::UpdateDirectory(const std::string& name)
|
||||
{
|
||||
// If a full path was given we know the directory.
|
||||
if(cmSystemTools::FileIsFullPath(name.c_str()))
|
||||
{
|
||||
this->Directory = cmSystemTools::GetFilenamePath(name);
|
||||
this->AmbiguousDirectory = false;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmSourceFileLocation
|
||||
::MatchesAmbiguousExtension(cmSourceFileLocation const& loc) const
|
||||
{
|
||||
assert(this->Makefile);
|
||||
// This location's extension is not ambiguous but loc's extension
|
||||
// is. See if the names match as-is.
|
||||
if(this->Name == loc.Name)
|
||||
|
@ -188,6 +209,7 @@ cmSourceFileLocation
|
|||
//----------------------------------------------------------------------------
|
||||
bool cmSourceFileLocation::Matches(cmSourceFileLocation const& loc)
|
||||
{
|
||||
assert(this->Makefile);
|
||||
if(this->AmbiguousExtension && loc.AmbiguousExtension)
|
||||
{
|
||||
// Both extensions are ambiguous. Since only the old fixed set of
|
||||
|
|
|
@ -34,6 +34,9 @@ public:
|
|||
* instance with an initial name.
|
||||
*/
|
||||
cmSourceFileLocation(cmMakefile const* mf, const std::string& name);
|
||||
cmSourceFileLocation();
|
||||
cmSourceFileLocation(const cmSourceFileLocation& loc);
|
||||
cmSourceFileLocation& operator=(const cmSourceFileLocation& loc);
|
||||
|
||||
/**
|
||||
* Return whether the givne source file location could refers to the
|
||||
|
@ -93,9 +96,7 @@ private:
|
|||
|
||||
// Update the location with additional knowledge.
|
||||
void Update(cmSourceFileLocation const& loc);
|
||||
void Update(const std::string& name);
|
||||
void UpdateExtension(const std::string& name);
|
||||
void UpdateDirectory(const std::string& name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -101,6 +101,10 @@ bool cmStringCommand
|
|||
{
|
||||
return this->HandleMakeCIdentifierCommand(args);
|
||||
}
|
||||
else if(subCommand == "GENEX_STRIP")
|
||||
{
|
||||
return this->HandleGenexStripCommand(args);
|
||||
}
|
||||
|
||||
std::string e = "does not recognize sub-command "+subCommand;
|
||||
this->SetError(e);
|
||||
|
@ -809,6 +813,27 @@ bool cmStringCommand
|
|||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmStringCommand
|
||||
::HandleGenexStripCommand(std::vector<std::string> const& args)
|
||||
{
|
||||
if(args.size() != 3)
|
||||
{
|
||||
this->SetError("sub-command GENEX_STRIP requires two arguments.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string& input = args[1];
|
||||
|
||||
std::string result = cmGeneratorExpression::Preprocess(input,
|
||||
cmGeneratorExpression::StripAllGeneratorExpressions);
|
||||
|
||||
const std::string& variableName = args[2];
|
||||
|
||||
this->Makefile->AddDefinition(variableName, result.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmStringCommand::HandleStripCommand(
|
||||
std::vector<std::string> const& args)
|
||||
|
|
|
@ -75,6 +75,7 @@ protected:
|
|||
bool HandleFindCommand(std::vector<std::string> const& args);
|
||||
bool HandleTimestampCommand(std::vector<std::string> const& args);
|
||||
bool HandleMakeCIdentifierCommand(std::vector<std::string> const& args);
|
||||
bool HandleGenexStripCommand(std::vector<std::string> const& args);
|
||||
|
||||
class RegexReplacement
|
||||
{
|
||||
|
|
|
@ -150,6 +150,7 @@ public:
|
|||
std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
|
||||
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
|
||||
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
|
||||
std::vector<TargetPropertyEntry*> SourceEntries;
|
||||
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries;
|
||||
|
||||
mutable std::map<std::string, std::vector<TargetPropertyEntry*> >
|
||||
|
@ -542,35 +543,58 @@ bool cmTarget::IsBundleOnApple() const
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
||||
void cmTarget::GetSourceFiles(std::vector<std::string> &files) const
|
||||
{
|
||||
assert(this->GetType() != INTERFACE_LIBRARY);
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->SourceFiles.begin();
|
||||
si != this->SourceFiles.end(); ++si)
|
||||
for(std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator
|
||||
si = this->Internal->SourceEntries.begin();
|
||||
si != this->Internal->SourceEntries.end(); ++si)
|
||||
{
|
||||
std::string e;
|
||||
if((*si)->GetFullPath(&e).empty())
|
||||
std::vector<std::string> srcs;
|
||||
cmSystemTools::ExpandListArgument((*si)->ge->Evaluate(this->Makefile,
|
||||
"",
|
||||
false,
|
||||
this),
|
||||
srcs);
|
||||
|
||||
for(std::vector<std::string>::const_iterator i = srcs.begin();
|
||||
i != srcs.end(); ++i)
|
||||
{
|
||||
if(!e.empty())
|
||||
std::string src = *i;
|
||||
cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
|
||||
std::string e;
|
||||
src = sf->GetFullPath(&e);
|
||||
if(src.empty())
|
||||
{
|
||||
cmake* cm = this->Makefile->GetCMakeInstance();
|
||||
cm->IssueMessage(cmake::FATAL_ERROR, e,
|
||||
this->GetBacktrace());
|
||||
if(!e.empty())
|
||||
{
|
||||
cmake* cm = this->Makefile->GetCMakeInstance();
|
||||
cm->IssueMessage(cmake::FATAL_ERROR, e,
|
||||
this->GetBacktrace());
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
files.push_back(src);
|
||||
}
|
||||
}
|
||||
files = this->SourceFiles;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::AddSourceFile(cmSourceFile* sf)
|
||||
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
||||
{
|
||||
if (std::find(this->SourceFiles.begin(), this->SourceFiles.end(), sf)
|
||||
== this->SourceFiles.end())
|
||||
std::vector<std::string> srcs;
|
||||
this->GetSourceFiles(srcs);
|
||||
|
||||
std::set<cmSourceFile*> emitted;
|
||||
|
||||
for(std::vector<std::string>::const_iterator i = srcs.begin();
|
||||
i != srcs.end(); ++i)
|
||||
{
|
||||
this->SourceFiles.push_back(sf);
|
||||
cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
|
||||
if (emitted.insert(sf).second)
|
||||
{
|
||||
files.push_back(sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -583,17 +607,17 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
|
|||
const char* src = i->c_str();
|
||||
if(src[0] == '$' && src[1] == '<')
|
||||
{
|
||||
this->ProcessSourceExpression(*i);
|
||||
this->AddSource(src);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AddSource(src);
|
||||
this->AddSourceCMP0049(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmSourceFile* cmTarget::AddSource(const std::string& s)
|
||||
cmSourceFile* cmTarget::AddSourceCMP0049(const std::string& s)
|
||||
{
|
||||
std::string src = s;
|
||||
|
||||
|
@ -632,28 +656,91 @@ cmSourceFile* cmTarget::AddSource(const std::string& s)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmSourceFile* sf = this->Makefile->GetOrCreateSource(src);
|
||||
this->AddSourceFile(sf);
|
||||
return sf;
|
||||
return this->AddSource(src);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::ProcessSourceExpression(std::string const& expr)
|
||||
struct CreateLocation
|
||||
{
|
||||
if(cmHasLiteralPrefix(expr.c_str(), "$<TARGET_OBJECTS:") &&
|
||||
expr[expr.size()-1] == '>')
|
||||
cmMakefile const* Makefile;
|
||||
|
||||
CreateLocation(cmMakefile const* mf)
|
||||
: Makefile(mf)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cmSourceFileLocation operator()(const std::string& filename)
|
||||
{
|
||||
return cmSourceFileLocation(this->Makefile, filename);
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct LocationMatcher
|
||||
{
|
||||
const cmSourceFileLocation& Needle;
|
||||
|
||||
LocationMatcher(const cmSourceFileLocation& needle)
|
||||
: Needle(needle)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool operator()(cmSourceFileLocation &loc)
|
||||
{
|
||||
return loc.Matches(this->Needle);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct TargetPropertyEntryFinder
|
||||
{
|
||||
private:
|
||||
const cmSourceFileLocation& Needle;
|
||||
public:
|
||||
TargetPropertyEntryFinder(const cmSourceFileLocation& needle)
|
||||
: Needle(needle)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool operator()(cmTargetInternals::TargetPropertyEntry* entry)
|
||||
{
|
||||
std::vector<std::string> files;
|
||||
cmSystemTools::ExpandListArgument(entry->ge->GetInput(), files);
|
||||
std::vector<cmSourceFileLocation> locations(files.size());
|
||||
std::transform(files.begin(), files.end(), locations.begin(),
|
||||
CreateLocation(this->Needle.GetMakefile()));
|
||||
|
||||
return std::find_if(locations.begin(), locations.end(),
|
||||
LocationMatcher(this->Needle)) != locations.end();
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmSourceFile* cmTarget::AddSource(const std::string& src)
|
||||
{
|
||||
cmSourceFileLocation sfl(this->Makefile, src);
|
||||
if (std::find_if(this->Internal->SourceEntries.begin(),
|
||||
this->Internal->SourceEntries.end(),
|
||||
TargetPropertyEntryFinder(sfl))
|
||||
== this->Internal->SourceEntries.end())
|
||||
{
|
||||
std::string objLibName = expr.substr(17, expr.size()-18);
|
||||
this->ObjectLibraries.push_back(objLibName);
|
||||
cmListFileBacktrace lfbt;
|
||||
this->Makefile->GetBacktrace(lfbt);
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
|
||||
cge->SetEvaluateForBuildsystem(true);
|
||||
this->Internal->SourceEntries.push_back(
|
||||
new cmTargetInternals::TargetPropertyEntry(cge));
|
||||
}
|
||||
else
|
||||
if (cmGeneratorExpression::Find(src) != std::string::npos)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Unrecognized generator expression:\n"
|
||||
<< " " << expr;
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return 0;
|
||||
}
|
||||
return this->Makefile->GetOrCreateSource(src);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -2766,25 +2853,90 @@ const char *cmTarget::GetProperty(const std::string& prop,
|
|||
{
|
||||
cmOStringStream ss;
|
||||
const char* sep = "";
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
i = this->SourceFiles.begin();
|
||||
i != this->SourceFiles.end(); ++i)
|
||||
typedef cmTargetInternals::TargetPropertyEntry
|
||||
TargetPropertyEntry;
|
||||
for(std::vector<TargetPropertyEntry*>::const_iterator
|
||||
i = this->Internal->SourceEntries.begin();
|
||||
i != this->Internal->SourceEntries.end(); ++i)
|
||||
{
|
||||
// Separate from the previous list entries.
|
||||
ss << sep;
|
||||
sep = ";";
|
||||
std::string entry = (*i)->ge->GetInput();
|
||||
|
||||
// Construct what is known about this source file location.
|
||||
cmSourceFileLocation const& location = (*i)->GetLocation();
|
||||
std::string sname = location.GetDirectory();
|
||||
if(!sname.empty())
|
||||
std::vector<std::string> files;
|
||||
cmSystemTools::ExpandListArgument(entry, files);
|
||||
for (std::vector<std::string>::const_iterator
|
||||
li = files.begin(); li != files.end(); ++li)
|
||||
{
|
||||
sname += "/";
|
||||
}
|
||||
sname += location.GetName();
|
||||
if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
|
||||
(*li)[li->size() - 1] == '>')
|
||||
{
|
||||
std::string objLibName = li->substr(17, li->size()-18);
|
||||
|
||||
// Append this list entry.
|
||||
ss << sname;
|
||||
if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
|
||||
{
|
||||
ss << sep;
|
||||
sep = ";";
|
||||
ss << *li;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool addContent = false;
|
||||
bool noMessage = true;
|
||||
cmOStringStream e;
|
||||
cmake::MessageType messageType = cmake::AUTHOR_WARNING;
|
||||
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0051))
|
||||
{
|
||||
case cmPolicies::WARN:
|
||||
e << (this->Makefile->GetPolicies()
|
||||
->GetPolicyWarning(cmPolicies::CMP0051)) << "\n";
|
||||
noMessage = false;
|
||||
case cmPolicies::OLD:
|
||||
break;
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::NEW:
|
||||
addContent = true;
|
||||
}
|
||||
if (!noMessage)
|
||||
{
|
||||
e << "Target \"" << this->Name << "\" contains $<TARGET_OBJECTS> "
|
||||
"generator expression in its sources list. This content was not "
|
||||
"previously part of the SOURCES property when that property was "
|
||||
"read at configure time. Code reading that property needs to be "
|
||||
"adapted to ignore the generator expression using the "
|
||||
"string(GENEX_STRIP) command.";
|
||||
this->Makefile->IssueMessage(messageType, e.str());
|
||||
}
|
||||
if (addContent)
|
||||
{
|
||||
ss << sep;
|
||||
sep = ";";
|
||||
ss << *li;
|
||||
}
|
||||
}
|
||||
else if (cmGeneratorExpression::Find(*li) == std::string::npos)
|
||||
{
|
||||
ss << sep;
|
||||
sep = ";";
|
||||
ss << *li;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmSourceFile *sf = this->Makefile->GetOrCreateSource(*li);
|
||||
// Construct what is known about this source file location.
|
||||
cmSourceFileLocation const& location = sf->GetLocation();
|
||||
std::string sname = location.GetDirectory();
|
||||
if(!sname.empty())
|
||||
{
|
||||
sname += "/";
|
||||
}
|
||||
sname += location.GetName();
|
||||
|
||||
ss << sep;
|
||||
sep = ";";
|
||||
// Append this list entry.
|
||||
ss << sname;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->Properties.SetProperty("SOURCES", ss.str().c_str(),
|
||||
cmProperty::TARGET);
|
||||
|
@ -4844,8 +4996,10 @@ bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
|
|||
//----------------------------------------------------------------------------
|
||||
void cmTarget::GetLanguages(std::set<std::string>& languages) const
|
||||
{
|
||||
std::vector<cmSourceFile*> sourceFiles;
|
||||
this->GetSourceFiles(sourceFiles);
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
|
||||
i = sourceFiles.begin(); i != sourceFiles.end(); ++i)
|
||||
{
|
||||
const std::string& lang = (*i)->GetLanguage();
|
||||
if(!lang.empty())
|
||||
|
@ -4853,6 +5007,53 @@ void cmTarget::GetLanguages(std::set<std::string>& languages) const
|
|||
languages.insert(lang);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<cmTarget*> objectLibraries;
|
||||
std::vector<cmSourceFile const*> 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<std::string> srcs;
|
||||
cmSystemTools::ExpandListArgument(this->GetProperty("SOURCES"), srcs);
|
||||
for(std::vector<std::string>::const_iterator it = srcs.begin();
|
||||
it != srcs.end(); ++it)
|
||||
{
|
||||
if (cmHasLiteralPrefix(*it, "$<TARGET_OBJECTS:")
|
||||
&& cmHasLiteralSuffix(*it, ">"))
|
||||
{
|
||||
std::string objLibName = it->substr(17, it->size()-18);
|
||||
if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLibName))
|
||||
{
|
||||
objectLibraries.push_back(tgt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmGeneratorTarget* gt = this->Makefile->GetLocalGenerator()
|
||||
->GetGlobalGenerator()
|
||||
->GetGeneratorTarget(this);
|
||||
gt->GetExternalObjects(externalObjects);
|
||||
for(std::vector<cmSourceFile const*>::const_iterator
|
||||
i = externalObjects.begin(); i != externalObjects.end(); ++i)
|
||||
{
|
||||
std::string objLib = (*i)->GetObjectLibrary();
|
||||
if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
|
||||
{
|
||||
objectLibraries.push_back(tgt);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
i = objectLibraries.begin(); i != objectLibraries.end(); ++i)
|
||||
{
|
||||
(*i)->GetLanguages(languages);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -5917,19 +6118,6 @@ cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
|
|||
std::set<std::string> languages;
|
||||
// Get languages used in our source files.
|
||||
this->GetLanguages(languages);
|
||||
// Get languages used in object library sources.
|
||||
for(std::vector<std::string>::const_iterator
|
||||
i = this->ObjectLibraries.begin();
|
||||
i != this->ObjectLibraries.end(); ++i)
|
||||
{
|
||||
if(cmTarget* objLib = this->Makefile->FindTargetToUse(*i))
|
||||
{
|
||||
if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
objLib->GetLanguages(languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Copy the set of langauges to the link implementation.
|
||||
for(std::set<std::string>::iterator li = languages.begin();
|
||||
li != languages.end(); ++li)
|
||||
|
@ -6395,6 +6583,7 @@ cmTargetInternalPointer::~cmTargetInternalPointer()
|
|||
deleteAndClear(this->Pointer->IncludeDirectoriesEntries);
|
||||
deleteAndClear(this->Pointer->CompileOptionsEntries);
|
||||
deleteAndClear(this->Pointer->CompileDefinitionsEntries);
|
||||
deleteAndClear(this->Pointer->SourceEntries);
|
||||
delete this->Pointer;
|
||||
}
|
||||
|
||||
|
|
|
@ -135,17 +135,14 @@ public:
|
|||
/**
|
||||
* Get the list of the source files used by this target
|
||||
*/
|
||||
void GetSourceFiles(std::vector<std::string> &files) const;
|
||||
void GetSourceFiles(std::vector<cmSourceFile*> &files) const;
|
||||
void AddSourceFile(cmSourceFile* sf);
|
||||
std::vector<std::string> const& GetObjectLibraries() const
|
||||
{
|
||||
return this->ObjectLibraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sources to the target.
|
||||
*/
|
||||
void AddSources(std::vector<std::string> const& srcs);
|
||||
cmSourceFile* AddSourceCMP0049(const std::string& src);
|
||||
cmSourceFile* AddSource(const std::string& src);
|
||||
|
||||
enum LinkLibraryType {GENERAL, DEBUG, OPTIMIZED};
|
||||
|
@ -685,8 +682,6 @@ private:
|
|||
std::vector<cmCustomCommand> PreLinkCommands;
|
||||
std::vector<cmCustomCommand> PostBuildCommands;
|
||||
TargetType TargetTypeValue;
|
||||
std::vector<cmSourceFile*> SourceFiles;
|
||||
std::vector<std::string> ObjectLibraries;
|
||||
LinkLibraryVectorType LinkLibraries;
|
||||
LinkLibraryVectorType PrevLinkedLibraries;
|
||||
bool LinkLibrariesAnalyzed;
|
||||
|
|
|
@ -1054,6 +1054,19 @@ void cmVisualStudio10TargetGenerator::WriteAllSources()
|
|||
|
||||
std::vector<cmSourceFile const*> 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)
|
||||
{
|
||||
// For VS >= 11 we use LinkObjects to avoid linking custom command
|
||||
|
|
|
@ -166,7 +166,7 @@ add_library(imported4 SHARED IMPORTED)
|
|||
set_property(TARGET imported4 APPEND PROPERTY
|
||||
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_library(Alias::SomeLib ALIAS empty1)
|
||||
|
|
|
@ -143,3 +143,5 @@ set_property(CACHE SOME_ENTRY PROPERTY VALUE "${expect_VALUE}")
|
|||
set_property(CACHE SOME_ENTRY PROPERTY ADVANCED "${expect_ADVANCED}")
|
||||
set_property(CACHE SOME_ENTRY PROPERTY STRINGS "${expect_STRINGS}")
|
||||
check_cache_props()
|
||||
|
||||
add_subdirectory(SubDir2)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx"
|
||||
PROPERTIES COMPILE_DEFINITIONS SUBDIR_TEST)
|
||||
|
||||
add_executable(subdirtest "${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx")
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef SUBDIR_TEST
|
||||
#error Expected SUBDIR_TEST
|
||||
#endif
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^Sources: "empty.cpp;\$<TARGET_OBJECTS:objects>"$
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
cmake_policy(SET CMP0051 NEW)
|
||||
|
||||
add_library(objects OBJECT empty.cpp)
|
||||
|
||||
add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
|
||||
|
||||
get_target_property(srcs empty SOURCES)
|
||||
|
||||
message("Sources: \"${srcs}\"")
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1 @@
|
|||
^Sources: "empty.cpp"$
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
cmake_policy(SET CMP0051 OLD)
|
||||
|
||||
add_library(objects OBJECT empty.cpp)
|
||||
|
||||
add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
|
||||
|
||||
get_target_property(srcs empty SOURCES)
|
||||
|
||||
message("Sources: \"${srcs}\"")
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1,15 @@
|
|||
CMake Warning \(dev\) at CMP0051-WARN.cmake:6 \(get_target_property\):
|
||||
Policy CMP0051 is not set: List TARGET_OBJECTS in SOURCES target property.
|
||||
Run "cmake --help-policy CMP0051" for policy details. Use the cmake_policy
|
||||
command to set the policy and suppress this warning.
|
||||
|
||||
Target "empty" contains \$<TARGET_OBJECTS> generator expression in its
|
||||
sources list. This content was not previously part of the SOURCES property
|
||||
when that property was read at configure time. Code reading that property
|
||||
needs to be adapted to ignore the generator expression using the
|
||||
string\(GENEX_STRIP\) command.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
This warning is for project developers. Use -Wno-dev to suppress it.
|
||||
|
||||
Sources: "empty.cpp"$
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
add_library(objects OBJECT empty.cpp)
|
||||
|
||||
add_library(empty empty.cpp $<TARGET_OBJECTS:objects>)
|
||||
|
||||
get_target_property(srcs empty SOURCES)
|
||||
|
||||
message("Sources: \"${srcs}\"")
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(${RunCMake_TEST} CXX)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,5 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(CMP0051-OLD)
|
||||
run_cmake(CMP0051-NEW)
|
||||
run_cmake(CMP0051-WARN)
|
|
@ -0,0 +1,7 @@
|
|||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int empty()
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -34,6 +34,7 @@ add_RunCMake_test(CMP0045)
|
|||
add_RunCMake_test(CMP0046)
|
||||
add_RunCMake_test(CMP0049)
|
||||
add_RunCMake_test(CMP0050)
|
||||
add_RunCMake_test(CMP0051)
|
||||
add_RunCMake_test(CTest)
|
||||
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
add_RunCMake_test(CompilerChange)
|
||||
|
@ -49,6 +50,7 @@ add_RunCMake_test(GeneratorToolset)
|
|||
add_RunCMake_test(TargetPropertyGeneratorExpressions)
|
||||
add_RunCMake_test(Languages)
|
||||
add_RunCMake_test(ObjectLibrary)
|
||||
add_RunCMake_test(TargetObjects)
|
||||
add_RunCMake_test(find_dependency)
|
||||
if(NOT WIN32)
|
||||
add_RunCMake_test(PositionIndependentCode)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
|
||||
Unrecognized generator expression:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<BAD_EXPRESSION>
|
||||
|
||||
Expression did not evaluate to a known generator expression
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:DoesNotExist>
|
||||
|
||||
Objects of target "DoesNotExist" referenced but no such target exists.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:NotObjLib>
|
||||
|
||||
Objects of target "NotObjLib" referenced but is not an OBJECT library.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,17 @@
|
|||
CMake Error at BadContext.cmake:2 \(file\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:NoTarget>
|
||||
|
||||
The evaluation of the TARGET_OBJECTS generator expression is only suitable
|
||||
for consumption by CMake. It is not suitable for writing out elsewhere.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<TARGET_OBJECTS:NoTarget>
|
||||
|
||||
The evaluation of the TARGET_OBJECTS generator expression is only suitable
|
||||
for consumption by CMake. It is not suitable for writing out elsewhere.
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
file(GENERATE OUTPUT test_output CONTENT $<TARGET_OBJECTS:NoTarget>)
|
||||
|
||||
install(FILES $<TARGET_OBJECTS:NoTarget> DESTINATION objects)
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8.4)
|
||||
project(${RunCMake_TEST})
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,3 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(BadContext)
|
|
@ -286,3 +286,9 @@ string(MAKE_C_IDENTIFIER "1one-two$" MCI_1)
|
|||
if(NOT MCI_1 STREQUAL _1one_two_)
|
||||
message(SEND_ERROR "MAKE_C_IDENTIFIER did not create expected result.")
|
||||
endif()
|
||||
|
||||
string(GENEX_STRIP "one;$<1:two;three>;four;$<TARGET_OBJECTS:some_target>" strip_result)
|
||||
|
||||
if (NOT strip_result STREQUAL "one;four")
|
||||
message(SEND_ERROR "GENEX_STRIP did not create expected result: ${strip_result}")
|
||||
endif()
|
||||
|
|
Loading…
Reference in New Issue