Merge topic 'target-SOURCES-refactor'
f9d5b1fd
Handle Mac OSX source flags for individual files lazily.64d39841
cmGeneratorTarget: Classify sources on demand, not up front.d3682d86
cmGeneratorTarget: Use a method to access the definition file.5771f81d
cmTarget: Add GetTransitiveTargetClosure method.a6dd4990
cmTarget: Create a temporary cmTarget in checkInterfacePropertyCompatibilityb8b99cc1
cmTarget: Avoid computing languages when computing transitive targets.01bca553
cmTarget: Move ComputeLinkInterface to the internal class.d93e1af2
cmTarget: Extract a ComputeLinkInterfaceLibraries method.3bcb197c
cmTarget: Re-arrange the ComputeLinkInterface method.326d07d2
cmTarget: Extract a ComputeLinkImplementationLanguages method.21e91350
cmTarget: Change GetTransitivePropertyLinkLibraries to output targets.f81eb49e
cmTarget: Find source files on request.84e5f5a0
cmTarget: Move SourceFileFlags to cmGeneratorTarget.
This commit is contained in:
commit
049790c0eb
|
@ -800,7 +800,7 @@ static const char* targetPropertyTransitiveWhitelist[] = {
|
||||||
|
|
||||||
#undef TRANSITIVE_PROPERTY_NAME
|
#undef TRANSITIVE_PROPERTY_NAME
|
||||||
|
|
||||||
std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
std::string getLinkedTargetsContent(const std::vector<cmTarget*> &targets,
|
||||||
cmTarget const* target,
|
cmTarget const* target,
|
||||||
cmTarget const* headTarget,
|
cmTarget const* headTarget,
|
||||||
cmGeneratorExpressionContext *context,
|
cmGeneratorExpressionContext *context,
|
||||||
|
@ -811,24 +811,22 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
||||||
|
|
||||||
std::string sep;
|
std::string sep;
|
||||||
std::string depString;
|
std::string depString;
|
||||||
for (std::vector<std::string>::const_iterator
|
for (std::vector<cmTarget*>::const_iterator
|
||||||
it = libraries.begin();
|
it = targets.begin();
|
||||||
it != libraries.end(); ++it)
|
it != targets.end(); ++it)
|
||||||
{
|
{
|
||||||
if (*it == target->GetName())
|
if (*it == target)
|
||||||
{
|
{
|
||||||
// Broken code can have a target in its own link interface.
|
// Broken code can have a target in its own link interface.
|
||||||
// Don't follow such link interface entries so as not to create a
|
// Don't follow such link interface entries so as not to create a
|
||||||
// self-referencing loop.
|
// self-referencing loop.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (context->Makefile->FindTargetToUse(*it))
|
|
||||||
{
|
|
||||||
depString +=
|
depString +=
|
||||||
sep + "$<TARGET_PROPERTY:" + *it + "," + interfacePropertyName + ">";
|
sep + "$<TARGET_PROPERTY:" +
|
||||||
|
(*it)->GetName() + "," + interfacePropertyName + ">";
|
||||||
sep = ";";
|
sep = ";";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
|
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
|
||||||
std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
|
std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
|
||||||
context->Config,
|
context->Config,
|
||||||
|
@ -843,6 +841,27 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
||||||
return linkedTargetsContent;
|
return linkedTargetsContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
||||||
|
cmTarget const* target,
|
||||||
|
cmTarget const* headTarget,
|
||||||
|
cmGeneratorExpressionContext *context,
|
||||||
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
|
const std::string &interfacePropertyName)
|
||||||
|
{
|
||||||
|
std::vector<cmTarget*> tgts;
|
||||||
|
for (std::vector<std::string>::const_iterator
|
||||||
|
it = libraries.begin();
|
||||||
|
it != libraries.end(); ++it)
|
||||||
|
{
|
||||||
|
if (cmTarget *tgt = context->Makefile->FindTargetToUse(*it))
|
||||||
|
{
|
||||||
|
tgts.push_back(tgt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getLinkedTargetsContent(tgts, target, headTarget, context,
|
||||||
|
dagChecker, interfacePropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
{
|
{
|
||||||
|
@ -1065,13 +1084,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
cmStrCmp(propertyName)) != transEnd)
|
cmStrCmp(propertyName)) != transEnd)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::vector<std::string> libs;
|
std::vector<cmTarget*> tgts;
|
||||||
target->GetTransitivePropertyLinkLibraries(context->Config,
|
target->GetTransitivePropertyTargets(context->Config,
|
||||||
headTarget, libs);
|
headTarget, tgts);
|
||||||
if (!libs.empty())
|
if (!tgts.empty())
|
||||||
{
|
{
|
||||||
linkedTargetsContent =
|
linkedTargetsContent =
|
||||||
getLinkedTargetsContent(libs, target,
|
getLinkedTargetsContent(tgts, target,
|
||||||
headTarget,
|
headTarget,
|
||||||
context, &dagChecker,
|
context, &dagChecker,
|
||||||
interfacePropertyName);
|
interfacePropertyName);
|
||||||
|
@ -1080,8 +1099,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
else if (std::find_if(transBegin, transEnd,
|
else if (std::find_if(transBegin, transEnd,
|
||||||
cmStrCmp(interfacePropertyName)) != transEnd)
|
cmStrCmp(interfacePropertyName)) != transEnd)
|
||||||
{
|
{
|
||||||
const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
|
const cmTarget::LinkImplementation *impl
|
||||||
context->Config,
|
= target->GetLinkImplementationLibraries(context->Config,
|
||||||
headTarget);
|
headTarget);
|
||||||
if(impl)
|
if(impl)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,196 @@
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
|
void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
|
||||||
|
cmTarget *target, cmake *cm)
|
||||||
|
{
|
||||||
|
if(!badObjLib.empty())
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "OBJECT library \"" << target->GetName() << "\" contains:\n";
|
||||||
|
for(std::vector<cmSourceFile*>::const_iterator i = badObjLib.begin();
|
||||||
|
i != badObjLib.end(); ++i)
|
||||||
|
{
|
||||||
|
e << " " << (*i)->GetLocation().GetName() << "\n";
|
||||||
|
}
|
||||||
|
e << "but may contain only headers and sources that compile.";
|
||||||
|
cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||||
|
target->GetBacktrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ObjectSourcesTag {};
|
||||||
|
struct CustomCommandsTag {};
|
||||||
|
struct ExtraSourcesTag {};
|
||||||
|
struct HeaderSourcesTag {};
|
||||||
|
struct ExternalObjectsTag {};
|
||||||
|
struct IDLSourcesTag {};
|
||||||
|
struct ResxTag {};
|
||||||
|
struct ModuleDefinitionFileTag {};
|
||||||
|
|
||||||
|
#if !defined(_MSC_VER) || _MSC_VER >= 1310
|
||||||
|
template<typename Tag, typename OtherTag>
|
||||||
|
struct IsSameTag
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
Result = false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Tag>
|
||||||
|
struct IsSameTag<Tag, Tag>
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
Result = true
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
struct IsSameTagBase
|
||||||
|
{
|
||||||
|
typedef char (&no_type)[1];
|
||||||
|
typedef char (&yes_type)[2];
|
||||||
|
template<typename T> struct Check;
|
||||||
|
template<typename T> static yes_type check(Check<T>*, Check<T>*);
|
||||||
|
static no_type check(...);
|
||||||
|
};
|
||||||
|
template<typename Tag1, typename Tag2>
|
||||||
|
struct IsSameTag: public IsSameTagBase
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
Result = (sizeof(check(static_cast< Check<Tag1>* >(0),
|
||||||
|
static_cast< Check<Tag2>* >(0))) ==
|
||||||
|
sizeof(yes_type))
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<bool>
|
||||||
|
struct DoAccept
|
||||||
|
{
|
||||||
|
template <typename T> static void Do(T&, cmSourceFile*) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct DoAccept<true>
|
||||||
|
{
|
||||||
|
static void Do(std::vector<cmSourceFile*>& files, cmSourceFile* f)
|
||||||
|
{
|
||||||
|
files.push_back(f);
|
||||||
|
}
|
||||||
|
static void Do(cmGeneratorTarget::ResxData& data, cmSourceFile* f)
|
||||||
|
{
|
||||||
|
// Build and save the name of the corresponding .h file
|
||||||
|
// This relationship will be used later when building the project files.
|
||||||
|
// Both names would have been auto generated from Visual Studio
|
||||||
|
// where the user supplied the file name and Visual Studio
|
||||||
|
// appended the suffix.
|
||||||
|
std::string resx = f->GetFullPath();
|
||||||
|
std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
|
||||||
|
data.ExpectedResxHeaders.insert(hFileName);
|
||||||
|
data.ResxSources.push_back(f);
|
||||||
|
}
|
||||||
|
static void Do(std::string& data, cmSourceFile* f)
|
||||||
|
{
|
||||||
|
data = f->GetFullPath();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
template<typename Tag, typename DataType = std::vector<cmSourceFile*> >
|
||||||
|
struct TagVisitor
|
||||||
|
{
|
||||||
|
DataType& Data;
|
||||||
|
std::vector<cmSourceFile*> BadObjLibFiles;
|
||||||
|
cmTarget *Target;
|
||||||
|
cmGlobalGenerator *GlobalGenerator;
|
||||||
|
cmsys::RegularExpression Header;
|
||||||
|
bool IsObjLib;
|
||||||
|
|
||||||
|
TagVisitor(cmTarget *target, DataType& data)
|
||||||
|
: Data(data), Target(target),
|
||||||
|
GlobalGenerator(target->GetMakefile()
|
||||||
|
->GetLocalGenerator()->GetGlobalGenerator()),
|
||||||
|
Header(CM_HEADER_REGEX),
|
||||||
|
IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~TagVisitor()
|
||||||
|
{
|
||||||
|
reportBadObjLib(this->BadObjLibFiles, this->Target,
|
||||||
|
this->GlobalGenerator->GetCMakeInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Accept(cmSourceFile *sf)
|
||||||
|
{
|
||||||
|
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
|
||||||
|
if(sf->GetCustomCommand())
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, CustomCommandsTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else if(this->Target->GetType() == cmTarget::UTILITY)
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ExternalObjectsTag>::Result>::Do(this->Data, sf);
|
||||||
|
if(this->IsObjLib)
|
||||||
|
{
|
||||||
|
this->BadObjLibFiles.push_back(sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(sf->GetLanguage())
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ObjectSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else if(ext == "def")
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ModuleDefinitionFileTag>::Result>::Do(this->Data,
|
||||||
|
sf);
|
||||||
|
if(this->IsObjLib)
|
||||||
|
{
|
||||||
|
this->BadObjLibFiles.push_back(sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ext == "idl")
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, IDLSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
if(this->IsObjLib)
|
||||||
|
{
|
||||||
|
this->BadObjLibFiles.push_back(sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ext == "resx")
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ResxTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else if(this->Header.find(sf->GetFullPath().c_str()))
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, HeaderSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
|
||||||
|
if(this->IsObjLib && ext != "txt")
|
||||||
|
{
|
||||||
|
this->BadObjLibFiles.push_back(sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t),
|
||||||
|
SourceFileFlagsConstructed(false)
|
||||||
{
|
{
|
||||||
this->Makefile = this->Target->GetMakefile();
|
this->Makefile = this->Target->GetMakefile();
|
||||||
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||||
|
@ -62,19 +251,12 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name,
|
static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
|
||||||
const char *config, cmTarget *headTarget,
|
const char *config, cmTarget *headTarget,
|
||||||
cmGeneratorExpressionDAGChecker *dagChecker,
|
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||||
std::vector<std::string>& result,
|
std::vector<std::string>& result,
|
||||||
bool excludeImported)
|
bool excludeImported)
|
||||||
{
|
{
|
||||||
cmTarget* depTgt = mf->FindTargetToUse(name);
|
|
||||||
|
|
||||||
if (!depTgt)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmListFileBacktrace lfbt;
|
cmListFileBacktrace lfbt;
|
||||||
|
|
||||||
if (const char* dirs =
|
if (const char* dirs =
|
||||||
|
@ -102,11 +284,34 @@ static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
|
||||||
|
{ \
|
||||||
|
std::vector<cmSourceFile*> sourceFiles; \
|
||||||
|
this->Target->GetSourceFiles(sourceFiles); \
|
||||||
|
TagVisitor<DATA ## Tag DATATYPE> visitor(this->Target, data); \
|
||||||
|
for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
|
||||||
|
si != sourceFiles.end(); ++si) \
|
||||||
|
{ \
|
||||||
|
visitor.Accept(*si); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
#define IMPLEMENT_VISIT(DATA) \
|
||||||
|
IMPLEMENT_VISIT_IMPL(DATA, EMPTY) \
|
||||||
|
|
||||||
|
#define EMPTY
|
||||||
|
#define COMMA ,
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &objs) const
|
cmGeneratorTarget::GetObjectSources(std::vector<cmSourceFile*> &data) const
|
||||||
{
|
{
|
||||||
objs = this->ObjectSources;
|
IMPLEMENT_VISIT(ObjectSources);
|
||||||
|
if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||||
|
{
|
||||||
|
this->ObjectSources = data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -135,49 +340,53 @@ bool cmGeneratorTarget::HasExplicitObjectName(cmSourceFile const* file) const
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile*>& srcs) const
|
void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& data) const
|
||||||
{
|
{
|
||||||
srcs = this->ResxSources;
|
IMPLEMENT_VISIT(IDLSources);
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& srcs) const
|
|
||||||
{
|
|
||||||
srcs = this->IDLSources;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmGeneratorTarget::GetHeaderSources(std::vector<cmSourceFile*>& srcs) const
|
cmGeneratorTarget::GetHeaderSources(std::vector<cmSourceFile*>& data) const
|
||||||
{
|
{
|
||||||
srcs = this->HeaderSources;
|
IMPLEMENT_VISIT(HeaderSources);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile*>& srcs) const
|
void cmGeneratorTarget::GetExtraSources(std::vector<cmSourceFile*>& data) const
|
||||||
{
|
{
|
||||||
srcs = this->ExtraSources;
|
IMPLEMENT_VISIT(ExtraSources);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmGeneratorTarget::GetCustomCommands(std::vector<cmSourceFile*>& srcs) const
|
cmGeneratorTarget::GetCustomCommands(std::vector<cmSourceFile*>& data) const
|
||||||
{
|
{
|
||||||
srcs = this->CustomCommands;
|
IMPLEMENT_VISIT(CustomCommands);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& data) const
|
||||||
|
{
|
||||||
|
IMPLEMENT_VISIT(ExternalObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
|
cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
|
||||||
{
|
{
|
||||||
srcs = this->ExpectedResxHeaders;
|
ResxData data;
|
||||||
|
IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
|
||||||
|
srcs = data.ExpectedResxHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void cmGeneratorTarget::GetResxSources(std::vector<cmSourceFile*>& srcs) const
|
||||||
cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& srcs) const
|
|
||||||
{
|
{
|
||||||
srcs = this->ExternalObjects;
|
ResxData data;
|
||||||
|
IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
|
||||||
|
srcs = data.ResxSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -224,26 +433,25 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir,
|
||||||
&dagChecker), result);
|
&dagChecker), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<cmStdString> uniqueDeps;
|
std::set<cmTarget*> uniqueDeps;
|
||||||
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
|
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
|
||||||
li != impl->Libraries.end(); ++li)
|
li != impl->Libraries.end(); ++li)
|
||||||
{
|
{
|
||||||
if (uniqueDeps.insert(*li).second)
|
|
||||||
{
|
|
||||||
cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
|
cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
|
||||||
|
|
||||||
if (!tgt)
|
if (!tgt)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
|
if (uniqueDeps.insert(tgt).second)
|
||||||
|
{
|
||||||
|
handleSystemIncludesDep(this->Makefile, tgt, config, this->Target,
|
||||||
&dagChecker, result, excludeImported);
|
&dagChecker, result, excludeImported);
|
||||||
|
|
||||||
std::vector<std::string> deps;
|
std::vector<cmTarget*> deps;
|
||||||
tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps);
|
tgt->GetTransitivePropertyTargets(config, this->Target, deps);
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator di = deps.begin();
|
for(std::vector<cmTarget*>::const_iterator di = deps.begin();
|
||||||
di != deps.end(); ++di)
|
di != deps.end(); ++di)
|
||||||
{
|
{
|
||||||
if (uniqueDeps.insert(*di).second)
|
if (uniqueDeps.insert(*di).second)
|
||||||
|
@ -289,102 +497,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
||||||
this->Target->GetSourceFiles(files);
|
this->Target->GetSourceFiles(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmGeneratorTarget::ClassifySources()
|
|
||||||
{
|
|
||||||
cmsys::RegularExpression header(CM_HEADER_REGEX);
|
|
||||||
|
|
||||||
cmTarget::TargetType targetType = this->Target->GetType();
|
|
||||||
bool isObjLib = targetType == cmTarget::OBJECT_LIBRARY;
|
|
||||||
|
|
||||||
std::vector<cmSourceFile*> badObjLib;
|
|
||||||
std::vector<cmSourceFile*> sources;
|
|
||||||
this->Target->GetSourceFiles(sources);
|
|
||||||
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
|
|
||||||
si != sources.end(); ++si)
|
|
||||||
{
|
|
||||||
cmSourceFile* sf = *si;
|
|
||||||
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
|
|
||||||
if(sf->GetCustomCommand())
|
|
||||||
{
|
|
||||||
this->CustomCommands.push_back(sf);
|
|
||||||
}
|
|
||||||
else if(targetType == cmTarget::UTILITY)
|
|
||||||
{
|
|
||||||
this->ExtraSources.push_back(sf);
|
|
||||||
}
|
|
||||||
else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
|
||||||
{
|
|
||||||
this->HeaderSources.push_back(sf);
|
|
||||||
}
|
|
||||||
else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
|
||||||
{
|
|
||||||
this->ExternalObjects.push_back(sf);
|
|
||||||
if(isObjLib) { badObjLib.push_back(sf); }
|
|
||||||
}
|
|
||||||
else if(sf->GetLanguage())
|
|
||||||
{
|
|
||||||
this->ObjectSources.push_back(sf);
|
|
||||||
}
|
|
||||||
else if(ext == "def")
|
|
||||||
{
|
|
||||||
this->ModuleDefinitionFile = sf->GetFullPath();
|
|
||||||
if(isObjLib) { badObjLib.push_back(sf); }
|
|
||||||
}
|
|
||||||
else if(ext == "idl")
|
|
||||||
{
|
|
||||||
this->IDLSources.push_back(sf);
|
|
||||||
if(isObjLib) { badObjLib.push_back(sf); }
|
|
||||||
}
|
|
||||||
else if(ext == "resx")
|
|
||||||
{
|
|
||||||
// Build and save the name of the corresponding .h file
|
|
||||||
// This relationship will be used later when building the project files.
|
|
||||||
// Both names would have been auto generated from Visual Studio
|
|
||||||
// where the user supplied the file name and Visual Studio
|
|
||||||
// appended the suffix.
|
|
||||||
std::string resx = sf->GetFullPath();
|
|
||||||
std::string hFileName = resx.substr(0, resx.find_last_of(".")) + ".h";
|
|
||||||
this->ExpectedResxHeaders.insert(hFileName);
|
|
||||||
this->ResxSources.push_back(sf);
|
|
||||||
}
|
|
||||||
else if(header.find(sf->GetFullPath().c_str()))
|
|
||||||
{
|
|
||||||
this->HeaderSources.push_back(sf);
|
|
||||||
}
|
|
||||||
else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
|
|
||||||
{
|
|
||||||
// We only get here if a source file is not an external object
|
|
||||||
// and has an extension that is listed as an ignored file type.
|
|
||||||
// No message or diagnosis should be given.
|
|
||||||
this->ExtraSources.push_back(sf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->ExtraSources.push_back(sf);
|
|
||||||
if(isObjLib && ext != "txt")
|
|
||||||
{
|
|
||||||
badObjLib.push_back(sf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!badObjLib.empty())
|
|
||||||
{
|
|
||||||
cmOStringStream e;
|
|
||||||
e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
|
|
||||||
for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
|
|
||||||
i != badObjLib.end(); ++i)
|
|
||||||
{
|
|
||||||
e << " " << (*i)->GetLocation().GetName() << "\n";
|
|
||||||
}
|
|
||||||
e << "but may contain only headers and sources that compile.";
|
|
||||||
this->GlobalGenerator->GetCMakeInstance()
|
|
||||||
->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
|
||||||
this->Target->GetBacktrace());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmGeneratorTarget::LookupObjectLibraries()
|
void cmGeneratorTarget::LookupObjectLibraries()
|
||||||
{
|
{
|
||||||
|
@ -437,6 +549,14 @@ void cmGeneratorTarget::LookupObjectLibraries()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string cmGeneratorTarget::GetModuleDefinitionFile() const
|
||||||
|
{
|
||||||
|
std::string data;
|
||||||
|
IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
|
cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
|
||||||
|
@ -876,3 +996,97 @@ bool cmStrictTargetComparison::operator()(cmTarget const* t1,
|
||||||
}
|
}
|
||||||
return nameResult < 0;
|
return nameResult < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
struct cmGeneratorTarget::SourceFileFlags
|
||||||
|
cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
|
||||||
|
{
|
||||||
|
struct SourceFileFlags flags;
|
||||||
|
this->ConstructSourceFileFlags();
|
||||||
|
std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
|
||||||
|
this->SourceFlagsMap.find(sf);
|
||||||
|
if(si != this->SourceFlagsMap.end())
|
||||||
|
{
|
||||||
|
flags = si->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle the MACOSX_PACKAGE_LOCATION property on source files that
|
||||||
|
// were not listed in one of the other lists.
|
||||||
|
if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
|
||||||
|
{
|
||||||
|
flags.MacFolder = location;
|
||||||
|
if(strcmp(location, "Resources") == 0)
|
||||||
|
{
|
||||||
|
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags.Type = cmGeneratorTarget::SourceFileTypeMacContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGeneratorTarget::ConstructSourceFileFlags() const
|
||||||
|
{
|
||||||
|
if(this->SourceFileFlagsConstructed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->SourceFileFlagsConstructed = true;
|
||||||
|
|
||||||
|
// Process public headers to mark the source files.
|
||||||
|
if(const char* files = this->Target->GetProperty("PUBLIC_HEADER"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> relFiles;
|
||||||
|
cmSystemTools::ExpandListArgument(files, relFiles);
|
||||||
|
for(std::vector<std::string>::iterator it = relFiles.begin();
|
||||||
|
it != relFiles.end(); ++it)
|
||||||
|
{
|
||||||
|
if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
|
||||||
|
{
|
||||||
|
SourceFileFlags& flags = this->SourceFlagsMap[sf];
|
||||||
|
flags.MacFolder = "Headers";
|
||||||
|
flags.Type = cmGeneratorTarget::SourceFileTypePublicHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process private headers after public headers so that they take
|
||||||
|
// precedence if a file is listed in both.
|
||||||
|
if(const char* files = this->Target->GetProperty("PRIVATE_HEADER"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> relFiles;
|
||||||
|
cmSystemTools::ExpandListArgument(files, relFiles);
|
||||||
|
for(std::vector<std::string>::iterator it = relFiles.begin();
|
||||||
|
it != relFiles.end(); ++it)
|
||||||
|
{
|
||||||
|
if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
|
||||||
|
{
|
||||||
|
SourceFileFlags& flags = this->SourceFlagsMap[sf];
|
||||||
|
flags.MacFolder = "PrivateHeaders";
|
||||||
|
flags.Type = cmGeneratorTarget::SourceFileTypePrivateHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark sources listed as resources.
|
||||||
|
if(const char* files = this->Target->GetProperty("RESOURCE"))
|
||||||
|
{
|
||||||
|
std::vector<std::string> relFiles;
|
||||||
|
cmSystemTools::ExpandListArgument(files, relFiles);
|
||||||
|
for(std::vector<std::string>::iterator it = relFiles.begin();
|
||||||
|
it != relFiles.end(); ++it)
|
||||||
|
{
|
||||||
|
if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
|
||||||
|
{
|
||||||
|
SourceFileFlags& flags = this->SourceFlagsMap[sf];
|
||||||
|
flags.MacFolder = "Resources";
|
||||||
|
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
cmLocalGenerator* LocalGenerator;
|
cmLocalGenerator* LocalGenerator;
|
||||||
cmGlobalGenerator const* GlobalGenerator;
|
cmGlobalGenerator const* GlobalGenerator;
|
||||||
|
|
||||||
std::string ModuleDefinitionFile;
|
std::string GetModuleDefinitionFile() const;
|
||||||
|
|
||||||
/** Full path with trailing slash to the top-level directory
|
/** Full path with trailing slash to the top-level directory
|
||||||
holding object files for this target. Includes the build
|
holding object files for this target. Includes the build
|
||||||
|
@ -82,31 +82,56 @@ public:
|
||||||
*/
|
*/
|
||||||
void TraceDependencies();
|
void TraceDependencies();
|
||||||
|
|
||||||
void ClassifySources();
|
|
||||||
void LookupObjectLibraries();
|
void LookupObjectLibraries();
|
||||||
|
|
||||||
/** Get sources that must be built before the given source. */
|
/** Get sources that must be built before the given source. */
|
||||||
std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf) const;
|
std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags for a given source file as used in this target. Typically assigned
|
||||||
|
* via SET_TARGET_PROPERTIES when the property is a list of source files.
|
||||||
|
*/
|
||||||
|
enum SourceFileType
|
||||||
|
{
|
||||||
|
SourceFileTypeNormal,
|
||||||
|
SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
|
||||||
|
SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property
|
||||||
|
SourceFileTypeResource, // is in "RESOURCE" target property *or*
|
||||||
|
// has MACOSX_PACKAGE_LOCATION=="Resources"
|
||||||
|
SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources"
|
||||||
|
};
|
||||||
|
struct SourceFileFlags
|
||||||
|
{
|
||||||
|
SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
|
||||||
|
SourceFileFlags(SourceFileFlags const& r):
|
||||||
|
Type(r.Type), MacFolder(r.MacFolder) {}
|
||||||
|
SourceFileType Type;
|
||||||
|
const char* MacFolder; // location inside Mac content folders
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SourceFileFlags
|
||||||
|
GetTargetSourceFileFlags(const cmSourceFile* sf) const;
|
||||||
|
|
||||||
|
struct ResxData {
|
||||||
|
mutable std::set<std::string> ExpectedResxHeaders;
|
||||||
|
mutable std::vector<cmSourceFile*> ResxSources;
|
||||||
|
};
|
||||||
private:
|
private:
|
||||||
friend class cmTargetTraceDependencies;
|
friend class cmTargetTraceDependencies;
|
||||||
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
|
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
|
||||||
typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
|
typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
|
||||||
SourceEntriesType SourceEntries;
|
SourceEntriesType SourceEntries;
|
||||||
|
|
||||||
std::vector<cmSourceFile*> CustomCommands;
|
|
||||||
std::vector<cmSourceFile*> ExtraSources;
|
|
||||||
std::vector<cmSourceFile*> HeaderSources;
|
|
||||||
std::vector<cmSourceFile*> ExternalObjects;
|
|
||||||
std::vector<cmSourceFile*> IDLSources;
|
|
||||||
std::vector<cmSourceFile*> ResxSources;
|
|
||||||
std::map<cmSourceFile const*, std::string> Objects;
|
std::map<cmSourceFile const*, std::string> Objects;
|
||||||
std::set<cmSourceFile const*> ExplicitObjectName;
|
std::set<cmSourceFile const*> ExplicitObjectName;
|
||||||
std::set<std::string> ExpectedResxHeaders;
|
mutable std::vector<cmSourceFile*> ObjectSources;
|
||||||
std::vector<cmSourceFile*> ObjectSources;
|
|
||||||
std::vector<cmTarget*> ObjectLibraries;
|
std::vector<cmTarget*> ObjectLibraries;
|
||||||
mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
|
mutable std::map<std::string, std::vector<std::string> > SystemIncludesCache;
|
||||||
|
|
||||||
|
void ConstructSourceFileFlags() const;
|
||||||
|
mutable bool SourceFileFlagsConstructed;
|
||||||
|
mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
|
||||||
|
|
||||||
cmGeneratorTarget(cmGeneratorTarget const&);
|
cmGeneratorTarget(cmGeneratorTarget const&);
|
||||||
void operator=(cmGeneratorTarget const&);
|
void operator=(cmGeneratorTarget const&);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1148,12 +1148,6 @@ void cmGlobalGenerator::Generate()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all targets are valid.
|
|
||||||
if(!this->CheckTargets())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->FinalizeTargetCompileInfo();
|
this->FinalizeTargetCompileInfo();
|
||||||
|
|
||||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||||
|
@ -1305,35 +1299,6 @@ bool cmGlobalGenerator::ComputeTargetDepends()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool cmGlobalGenerator::CheckTargets()
|
|
||||||
{
|
|
||||||
// Make sure all targets can find their source files.
|
|
||||||
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
|
|
||||||
{
|
|
||||||
cmTargets& targets =
|
|
||||||
this->LocalGenerators[i]->GetMakefile()->GetTargets();
|
|
||||||
for(cmTargets::iterator ti = targets.begin();
|
|
||||||
ti != targets.end(); ++ti)
|
|
||||||
{
|
|
||||||
cmTarget& target = ti->second;
|
|
||||||
if(target.GetType() == cmTarget::EXECUTABLE ||
|
|
||||||
target.GetType() == cmTarget::STATIC_LIBRARY ||
|
|
||||||
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
|
||||||
target.GetType() == cmTarget::MODULE_LIBRARY ||
|
|
||||||
target.GetType() == cmTarget::OBJECT_LIBRARY ||
|
|
||||||
target.GetType() == cmTarget::UTILITY)
|
|
||||||
{
|
|
||||||
if(!target.FindSourceFiles())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
|
void cmGlobalGenerator::CreateQtAutoGeneratorsTargets(AutogensType &autogens)
|
||||||
{
|
{
|
||||||
|
@ -1474,7 +1439,6 @@ void cmGlobalGenerator::ComputeGeneratorTargetObjects()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cmGeneratorTarget* gt = ti->second;
|
cmGeneratorTarget* gt = ti->second;
|
||||||
gt->ClassifySources();
|
|
||||||
gt->LookupObjectLibraries();
|
gt->LookupObjectLibraries();
|
||||||
this->ComputeTargetObjects(gt);
|
this->ComputeTargetObjects(gt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,7 +340,6 @@ protected:
|
||||||
|
|
||||||
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
|
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
|
||||||
|
|
||||||
bool CheckTargets();
|
|
||||||
typedef std::vector<std::pair<cmQtAutoGenerators,
|
typedef std::vector<std::pair<cmQtAutoGenerators,
|
||||||
cmTarget const*> > AutogensType;
|
cmTarget const*> > AutogensType;
|
||||||
void CreateQtAutoGeneratorsTargets(AutogensType& autogens);
|
void CreateQtAutoGeneratorsTargets(AutogensType& autogens);
|
||||||
|
|
|
@ -713,22 +713,23 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
|
||||||
|
|
||||||
// Is this a resource file in this target? Add it to the resources group...
|
// Is this a resource file in this target? Add it to the resources group...
|
||||||
//
|
//
|
||||||
cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
|
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||||
bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);
|
this->GetGeneratorTarget(&cmtarget)->GetTargetSourceFileFlags(sf);
|
||||||
|
bool isResource = tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource;
|
||||||
|
|
||||||
// Is this a "private" or "public" framework header file?
|
// Is this a "private" or "public" framework header file?
|
||||||
// Set the ATTRIBUTES attribute appropriately...
|
// Set the ATTRIBUTES attribute appropriately...
|
||||||
//
|
//
|
||||||
if(cmtarget.IsFrameworkOnApple())
|
if(cmtarget.IsFrameworkOnApple())
|
||||||
{
|
{
|
||||||
if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
|
if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader)
|
||||||
{
|
{
|
||||||
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||||
attrs->AddObject(this->CreateString("Private"));
|
attrs->AddObject(this->CreateString("Private"));
|
||||||
settings->AddAttribute("ATTRIBUTES", attrs);
|
settings->AddAttribute("ATTRIBUTES", attrs);
|
||||||
isResource = true;
|
isResource = true;
|
||||||
}
|
}
|
||||||
else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
|
else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader)
|
||||||
{
|
{
|
||||||
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||||
attrs->AddObject(this->CreateString("Public"));
|
attrs->AddObject(this->CreateString("Public"));
|
||||||
|
@ -973,6 +974,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
||||||
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
|
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
|
||||||
{
|
{
|
||||||
cmTarget& cmtarget = l->second;
|
cmTarget& cmtarget = l->second;
|
||||||
|
cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
|
||||||
|
|
||||||
// make sure ALL_BUILD, INSTALL, etc are only done once
|
// make sure ALL_BUILD, INSTALL, etc are only done once
|
||||||
if(this->SpecialTargetEmitted(l->first.c_str()))
|
if(this->SpecialTargetEmitted(l->first.c_str()))
|
||||||
|
@ -1011,8 +1013,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
||||||
cmXCodeObject* filetype =
|
cmXCodeObject* filetype =
|
||||||
fr->GetObject()->GetObject("explicitFileType");
|
fr->GetObject()->GetObject("explicitFileType");
|
||||||
|
|
||||||
cmTarget::SourceFileFlags tsFlags =
|
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||||
cmtarget.GetTargetSourceFileFlags(*i);
|
gtgt->GetTargetSourceFileFlags(*i);
|
||||||
|
|
||||||
if(filetype &&
|
if(filetype &&
|
||||||
strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
|
strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
|
||||||
|
@ -1020,12 +1022,12 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
||||||
externalObjFiles.push_back(xsf);
|
externalObjFiles.push_back(xsf);
|
||||||
}
|
}
|
||||||
else if(this->IsHeaderFile(*i) ||
|
else if(this->IsHeaderFile(*i) ||
|
||||||
(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
|
(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||
|
||||||
(tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
|
(tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader))
|
||||||
{
|
{
|
||||||
headerFiles.push_back(xsf);
|
headerFiles.push_back(xsf);
|
||||||
}
|
}
|
||||||
else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
|
else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource)
|
||||||
{
|
{
|
||||||
resourceFiles.push_back(xsf);
|
resourceFiles.push_back(xsf);
|
||||||
}
|
}
|
||||||
|
@ -1048,7 +1050,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
||||||
// the externalObjFiles above, except each one is not a cmSourceFile
|
// the externalObjFiles above, except each one is not a cmSourceFile
|
||||||
// within the target.)
|
// within the target.)
|
||||||
std::vector<std::string> objs;
|
std::vector<std::string> objs;
|
||||||
this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
|
gtgt->UseObjectLibraries(objs);
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||||
{
|
{
|
||||||
|
@ -1138,9 +1140,9 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
||||||
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)
|
||||||
{
|
{
|
||||||
cmTarget::SourceFileFlags tsFlags =
|
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||||
cmtarget.GetTargetSourceFileFlags(*i);
|
gtgt->GetTargetSourceFileFlags(*i);
|
||||||
if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
|
if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent)
|
||||||
{
|
{
|
||||||
bundleFiles[tsFlags.MacFolder].push_back(*i);
|
bundleFiles[tsFlags.MacFolder].push_back(*i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1650,9 +1650,10 @@ void cmMakefileTargetGenerator
|
||||||
this->AppendTargetDepends(depends);
|
this->AppendTargetDepends(depends);
|
||||||
|
|
||||||
// Add a dependency on the link definitions file, if any.
|
// Add a dependency on the link definitions file, if any.
|
||||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||||
|
if(!def.empty())
|
||||||
{
|
{
|
||||||
depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
|
depends.push_back(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add user-specified dependencies.
|
// Add user-specified dependencies.
|
||||||
|
@ -2019,7 +2020,8 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
||||||
{
|
{
|
||||||
if(this->GeneratorTarget->ModuleDefinitionFile.empty())
|
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||||
|
if(def.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2035,8 +2037,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
||||||
// Append the flag and value. Use ConvertToLinkReference to help
|
// Append the flag and value. Use ConvertToLinkReference to help
|
||||||
// vs6's "cl -link" pass it to the linker.
|
// vs6's "cl -link" pass it to the linker.
|
||||||
std::string flag = defFileFlag;
|
std::string flag = defFileFlag;
|
||||||
flag += (this->LocalGenerator->ConvertToLinkReference(
|
flag += (this->LocalGenerator->ConvertToLinkReference(def.c_str()));
|
||||||
this->GeneratorTarget->ModuleDefinitionFile.c_str()));
|
|
||||||
this->LocalGenerator->AppendFlags(flags, flag.c_str());
|
this->LocalGenerator->AppendFlags(flags, flag.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -498,10 +498,10 @@ cmNinjaTargetGenerator
|
||||||
{
|
{
|
||||||
this->WriteObjectBuildStatement(*si);
|
this->WriteObjectBuildStatement(*si);
|
||||||
}
|
}
|
||||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||||
|
if(!def.empty())
|
||||||
{
|
{
|
||||||
this->ModuleDefinitionFile = this->ConvertToNinjaPath(
|
this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
|
||||||
this->GeneratorTarget->ModuleDefinitionFile.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
cmOSXBundleGenerator::
|
cmOSXBundleGenerator::
|
||||||
cmOSXBundleGenerator(cmGeneratorTarget* target,
|
cmOSXBundleGenerator(cmGeneratorTarget* target,
|
||||||
const char* configName)
|
const char* configName)
|
||||||
: Target(target->Target)
|
: GT(target)
|
||||||
, Makefile(target->Target->GetMakefile())
|
, Makefile(target->Target->GetMakefile())
|
||||||
, LocalGenerator(Makefile->GetLocalGenerator())
|
, LocalGenerator(Makefile->GetLocalGenerator())
|
||||||
, ConfigName(configName)
|
, ConfigName(configName)
|
||||||
|
@ -34,7 +34,7 @@ cmOSXBundleGenerator(cmGeneratorTarget* target,
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmOSXBundleGenerator::MustSkip()
|
bool cmOSXBundleGenerator::MustSkip()
|
||||||
{
|
{
|
||||||
return !this->Target->HaveWellDefinedOutputFiles();
|
return !this->GT->Target->HaveWellDefinedOutputFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -47,7 +47,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
|
||||||
// Compute bundle directory names.
|
// Compute bundle directory names.
|
||||||
std::string out = outpath;
|
std::string out = outpath;
|
||||||
out += "/";
|
out += "/";
|
||||||
out += this->Target->GetAppBundleDirectory(this->ConfigName, false);
|
out += this->GT->Target->GetAppBundleDirectory(this->ConfigName, false);
|
||||||
cmSystemTools::MakeDirectory(out.c_str());
|
cmSystemTools::MakeDirectory(out.c_str());
|
||||||
this->Makefile->AddCMakeOutputFile(out);
|
this->Makefile->AddCMakeOutputFile(out);
|
||||||
|
|
||||||
|
@ -57,9 +57,9 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
|
||||||
// to be set.
|
// to be set.
|
||||||
std::string plist = outpath;
|
std::string plist = outpath;
|
||||||
plist += "/";
|
plist += "/";
|
||||||
plist += this->Target->GetAppBundleDirectory(this->ConfigName, true);
|
plist += this->GT->Target->GetAppBundleDirectory(this->ConfigName, true);
|
||||||
plist += "/Info.plist";
|
plist += "/Info.plist";
|
||||||
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
|
this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
|
||||||
targetName.c_str(),
|
targetName.c_str(),
|
||||||
plist.c_str());
|
plist.c_str());
|
||||||
this->Makefile->AddCMakeOutputFile(plist);
|
this->Makefile->AddCMakeOutputFile(plist);
|
||||||
|
@ -77,20 +77,20 @@ void cmOSXBundleGenerator::CreateFramework(
|
||||||
|
|
||||||
// Compute the location of the top-level foo.framework directory.
|
// Compute the location of the top-level foo.framework directory.
|
||||||
std::string contentdir = outpath + "/" +
|
std::string contentdir = outpath + "/" +
|
||||||
this->Target->GetFrameworkDirectory(this->ConfigName, true);
|
this->GT->Target->GetFrameworkDirectory(this->ConfigName, true);
|
||||||
contentdir += "/";
|
contentdir += "/";
|
||||||
|
|
||||||
std::string newoutpath = outpath + "/" +
|
std::string newoutpath = outpath + "/" +
|
||||||
this->Target->GetFrameworkDirectory(this->ConfigName, false);
|
this->GT->Target->GetFrameworkDirectory(this->ConfigName, false);
|
||||||
|
|
||||||
std::string frameworkVersion = this->Target->GetFrameworkVersion();
|
std::string frameworkVersion = this->GT->Target->GetFrameworkVersion();
|
||||||
|
|
||||||
// Configure the Info.plist file into the Resources directory.
|
// Configure the Info.plist file into the Resources directory.
|
||||||
this->MacContentFolders->insert("Resources");
|
this->MacContentFolders->insert("Resources");
|
||||||
std::string plist = newoutpath;
|
std::string plist = newoutpath;
|
||||||
plist += "/Resources/Info.plist";
|
plist += "/Resources/Info.plist";
|
||||||
std::string name = cmSystemTools::GetFilenameName(targetName);
|
std::string name = cmSystemTools::GetFilenameName(targetName);
|
||||||
this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
|
this->LocalGenerator->GenerateFrameworkInfoPList(this->GT->Target,
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
plist.c_str());
|
plist.c_str());
|
||||||
|
|
||||||
|
@ -172,16 +172,16 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
|
||||||
// Compute bundle directory names.
|
// Compute bundle directory names.
|
||||||
std::string out = root;
|
std::string out = root;
|
||||||
out += "/";
|
out += "/";
|
||||||
out += this->Target->GetCFBundleDirectory(this->ConfigName, false);
|
out += this->GT->Target->GetCFBundleDirectory(this->ConfigName, false);
|
||||||
cmSystemTools::MakeDirectory(out.c_str());
|
cmSystemTools::MakeDirectory(out.c_str());
|
||||||
this->Makefile->AddCMakeOutputFile(out);
|
this->Makefile->AddCMakeOutputFile(out);
|
||||||
|
|
||||||
// Configure the Info.plist file. Note that it needs the executable name
|
// Configure the Info.plist file. Note that it needs the executable name
|
||||||
// to be set.
|
// to be set.
|
||||||
std::string plist =
|
std::string plist =
|
||||||
this->Target->GetCFBundleDirectory(this->ConfigName, true);
|
this->GT->Target->GetCFBundleDirectory(this->ConfigName, true);
|
||||||
plist += "/Info.plist";
|
plist += "/Info.plist";
|
||||||
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
|
this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
|
||||||
targetName.c_str(),
|
targetName.c_str(),
|
||||||
plist.c_str());
|
plist.c_str());
|
||||||
this->Makefile->AddCMakeOutputFile(plist);
|
this->Makefile->AddCMakeOutputFile(plist);
|
||||||
|
@ -199,9 +199,9 @@ GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
|
||||||
for(std::vector<cmSourceFile*>::const_iterator
|
for(std::vector<cmSourceFile*>::const_iterator
|
||||||
si = sources.begin(); si != sources.end(); ++si)
|
si = sources.begin(); si != sources.end(); ++si)
|
||||||
{
|
{
|
||||||
cmTarget::SourceFileFlags tsFlags =
|
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||||
this->Target->GetTargetSourceFileFlags(*si);
|
this->GT->GetTargetSourceFileFlags(*si);
|
||||||
if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
|
if(tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal)
|
||||||
{
|
{
|
||||||
(*generator)(**si, tsFlags.MacFolder);
|
(*generator)(**si, tsFlags.MacFolder);
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
|
||||||
// Construct the full path to the content subdirectory.
|
// Construct the full path to the content subdirectory.
|
||||||
|
|
||||||
std::string macdir =
|
std::string macdir =
|
||||||
this->Target->GetMacContentDirectory(this->ConfigName,
|
this->GT->Target->GetMacContentDirectory(this->ConfigName,
|
||||||
/*implib*/ false);
|
/*implib*/ false);
|
||||||
macdir += "/";
|
macdir += "/";
|
||||||
macdir += pkgloc;
|
macdir += pkgloc;
|
||||||
|
|
|
@ -59,7 +59,7 @@ private:
|
||||||
bool MustSkip();
|
bool MustSkip();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cmTarget* Target;
|
cmGeneratorTarget* GT;
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
cmLocalGenerator* LocalGenerator;
|
cmLocalGenerator* LocalGenerator;
|
||||||
const char* ConfigName;
|
const char* ConfigName;
|
||||||
|
|
|
@ -83,17 +83,12 @@ public:
|
||||||
cmTargetInternals()
|
cmTargetInternals()
|
||||||
{
|
{
|
||||||
this->PolicyWarnedCMP0022 = false;
|
this->PolicyWarnedCMP0022 = false;
|
||||||
this->SourceFileFlagsConstructed = false;
|
|
||||||
}
|
}
|
||||||
cmTargetInternals(cmTargetInternals const&)
|
cmTargetInternals(cmTargetInternals const&)
|
||||||
{
|
{
|
||||||
this->PolicyWarnedCMP0022 = false;
|
this->PolicyWarnedCMP0022 = false;
|
||||||
this->SourceFileFlagsConstructed = false;
|
|
||||||
}
|
}
|
||||||
~cmTargetInternals();
|
~cmTargetInternals();
|
||||||
typedef cmTarget::SourceFileFlags SourceFileFlags;
|
|
||||||
mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
|
|
||||||
mutable bool SourceFileFlagsConstructed;
|
|
||||||
|
|
||||||
// The backtrace when the target was created.
|
// The backtrace when the target was created.
|
||||||
cmListFileBacktrace Backtrace;
|
cmListFileBacktrace Backtrace;
|
||||||
|
@ -101,9 +96,17 @@ public:
|
||||||
// Cache link interface computation from each configuration.
|
// Cache link interface computation from each configuration.
|
||||||
struct OptionalLinkInterface: public cmTarget::LinkInterface
|
struct OptionalLinkInterface: public cmTarget::LinkInterface
|
||||||
{
|
{
|
||||||
OptionalLinkInterface(): Exists(false) {}
|
OptionalLinkInterface():
|
||||||
|
Exists(false), Complete(false), ExplicitLibraries(0) {}
|
||||||
bool Exists;
|
bool Exists;
|
||||||
|
bool Complete;
|
||||||
|
const char* ExplicitLibraries;
|
||||||
};
|
};
|
||||||
|
void ComputeLinkInterface(cmTarget const* thisTarget,
|
||||||
|
const char* config, OptionalLinkInterface& iface,
|
||||||
|
cmTarget const* head,
|
||||||
|
const char *explicitLibraries) const;
|
||||||
|
|
||||||
typedef std::map<TargetConfigPair, OptionalLinkInterface>
|
typedef std::map<TargetConfigPair, OptionalLinkInterface>
|
||||||
LinkInterfaceMapType;
|
LinkInterfaceMapType;
|
||||||
LinkInterfaceMapType LinkInterfaceMap;
|
LinkInterfaceMapType LinkInterfaceMap;
|
||||||
|
@ -527,8 +530,9 @@ bool cmTarget::IsBundleOnApple() const
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmTarget::FindSourceFiles()
|
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
||||||
{
|
{
|
||||||
|
assert(this->GetType() != INTERFACE_LIBRARY);
|
||||||
for(std::vector<cmSourceFile*>::const_iterator
|
for(std::vector<cmSourceFile*>::const_iterator
|
||||||
si = this->SourceFiles.begin();
|
si = this->SourceFiles.begin();
|
||||||
si != this->SourceFiles.end(); ++si)
|
si != this->SourceFiles.end(); ++si)
|
||||||
|
@ -542,16 +546,9 @@ bool cmTarget::FindSourceFiles()
|
||||||
cm->IssueMessage(cmake::FATAL_ERROR, e,
|
cm->IssueMessage(cmake::FATAL_ERROR, e,
|
||||||
this->GetBacktrace());
|
this->GetBacktrace());
|
||||||
}
|
}
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
|
||||||
{
|
|
||||||
assert(this->GetType() != INTERFACE_LIBRARY);
|
|
||||||
files = this->SourceFiles;
|
files = this->SourceFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,109 +644,6 @@ void cmTarget::ProcessSourceExpression(std::string const& expr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
struct cmTarget::SourceFileFlags
|
|
||||||
cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
|
|
||||||
{
|
|
||||||
struct SourceFileFlags flags;
|
|
||||||
this->ConstructSourceFileFlags();
|
|
||||||
std::map<cmSourceFile const*, SourceFileFlags>::iterator si =
|
|
||||||
this->Internal->SourceFlagsMap.find(sf);
|
|
||||||
if(si != this->Internal->SourceFlagsMap.end())
|
|
||||||
{
|
|
||||||
flags = si->second;
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmTarget::ConstructSourceFileFlags() const
|
|
||||||
{
|
|
||||||
if(this->Internal->SourceFileFlagsConstructed)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->Internal->SourceFileFlagsConstructed = true;
|
|
||||||
|
|
||||||
// Process public headers to mark the source files.
|
|
||||||
if(const char* files = this->GetProperty("PUBLIC_HEADER"))
|
|
||||||
{
|
|
||||||
std::vector<std::string> relFiles;
|
|
||||||
cmSystemTools::ExpandListArgument(files, relFiles);
|
|
||||||
for(std::vector<std::string>::iterator it = relFiles.begin();
|
|
||||||
it != relFiles.end(); ++it)
|
|
||||||
{
|
|
||||||
if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
|
|
||||||
{
|
|
||||||
SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
|
|
||||||
flags.MacFolder = "Headers";
|
|
||||||
flags.Type = cmTarget::SourceFileTypePublicHeader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process private headers after public headers so that they take
|
|
||||||
// precedence if a file is listed in both.
|
|
||||||
if(const char* files = this->GetProperty("PRIVATE_HEADER"))
|
|
||||||
{
|
|
||||||
std::vector<std::string> relFiles;
|
|
||||||
cmSystemTools::ExpandListArgument(files, relFiles);
|
|
||||||
for(std::vector<std::string>::iterator it = relFiles.begin();
|
|
||||||
it != relFiles.end(); ++it)
|
|
||||||
{
|
|
||||||
if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
|
|
||||||
{
|
|
||||||
SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
|
|
||||||
flags.MacFolder = "PrivateHeaders";
|
|
||||||
flags.Type = cmTarget::SourceFileTypePrivateHeader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark sources listed as resources.
|
|
||||||
if(const char* files = this->GetProperty("RESOURCE"))
|
|
||||||
{
|
|
||||||
std::vector<std::string> relFiles;
|
|
||||||
cmSystemTools::ExpandListArgument(files, relFiles);
|
|
||||||
for(std::vector<std::string>::iterator it = relFiles.begin();
|
|
||||||
it != relFiles.end(); ++it)
|
|
||||||
{
|
|
||||||
if(cmSourceFile* sf = this->Makefile->GetSource(it->c_str()))
|
|
||||||
{
|
|
||||||
SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
|
|
||||||
flags.MacFolder = "Resources";
|
|
||||||
flags.Type = cmTarget::SourceFileTypeResource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the MACOSX_PACKAGE_LOCATION property on source files that
|
|
||||||
// were not listed in one of the other lists.
|
|
||||||
std::vector<cmSourceFile*> sources;
|
|
||||||
this->GetSourceFiles(sources);
|
|
||||||
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
|
|
||||||
si != sources.end(); ++si)
|
|
||||||
{
|
|
||||||
cmSourceFile* sf = *si;
|
|
||||||
if(const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"))
|
|
||||||
{
|
|
||||||
SourceFileFlags& flags = this->Internal->SourceFlagsMap[sf];
|
|
||||||
if(flags.Type == cmTarget::SourceFileTypeNormal)
|
|
||||||
{
|
|
||||||
flags.MacFolder = location;
|
|
||||||
if(strcmp(location, "Resources") == 0)
|
|
||||||
{
|
|
||||||
flags.Type = cmTarget::SourceFileTypeResource;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flags.Type = cmTarget::SourceFileTypeMacContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::MergeLinkLibraries( cmMakefile& mf,
|
void cmTarget::MergeLinkLibraries( cmMakefile& mf,
|
||||||
const char *selfname,
|
const char *selfname,
|
||||||
|
@ -4530,12 +4424,13 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
assert((impliedByUse ^ explicitlySet)
|
assert((impliedByUse ^ explicitlySet)
|
||||||
|| (!impliedByUse && !explicitlySet));
|
|| (!impliedByUse && !explicitlySet));
|
||||||
|
|
||||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
std::vector<cmTarget*> deps;
|
||||||
if(!info)
|
tgt->GetTransitiveTargetClosure(config, tgt, deps);
|
||||||
|
|
||||||
|
if(deps.empty())
|
||||||
{
|
{
|
||||||
return propContent;
|
return propContent;
|
||||||
}
|
}
|
||||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
|
||||||
bool propInitialized = explicitlySet;
|
bool propInitialized = explicitlySet;
|
||||||
|
|
||||||
std::string report = " * Target \"";
|
std::string report = " * Target \"";
|
||||||
|
@ -4555,7 +4450,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
report += "\" property not set.\n";
|
report += "\" property not set.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
for(std::vector<cmTarget*>::const_iterator li =
|
||||||
deps.begin();
|
deps.begin();
|
||||||
li != deps.end(); ++li)
|
li != deps.end(); ++li)
|
||||||
{
|
{
|
||||||
|
@ -4565,23 +4460,20 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
// target itself has a POSITION_INDEPENDENT_CODE which disagrees
|
// target itself has a POSITION_INDEPENDENT_CODE which disagrees
|
||||||
// with a dependency.
|
// with a dependency.
|
||||||
|
|
||||||
if (!li->Target)
|
cmTarget const* theTarget = *li;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool ifaceIsSet = li->Target->GetProperties()
|
const bool ifaceIsSet = theTarget->GetProperties()
|
||||||
.find("INTERFACE_" + p)
|
.find("INTERFACE_" + p)
|
||||||
!= li->Target->GetProperties().end();
|
!= theTarget->GetProperties().end();
|
||||||
PropertyType ifacePropContent =
|
PropertyType ifacePropContent =
|
||||||
getTypedProperty<PropertyType>(li->Target,
|
getTypedProperty<PropertyType>(theTarget,
|
||||||
("INTERFACE_" + p).c_str(), 0);
|
("INTERFACE_" + p).c_str(), 0);
|
||||||
|
|
||||||
std::string reportEntry;
|
std::string reportEntry;
|
||||||
if (ifaceIsSet)
|
if (ifaceIsSet)
|
||||||
{
|
{
|
||||||
reportEntry += " * Target \"";
|
reportEntry += " * Target \"";
|
||||||
reportEntry += li->Target->GetName();
|
reportEntry += theTarget->GetName();
|
||||||
reportEntry += "\" property value \"";
|
reportEntry += "\" property value \"";
|
||||||
reportEntry += valueAsString<PropertyType>(ifacePropContent);
|
reportEntry += valueAsString<PropertyType>(ifacePropContent);
|
||||||
reportEntry += "\" ";
|
reportEntry += "\" ";
|
||||||
|
@ -4602,7 +4494,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
e << "Property " << p << " on target \""
|
e << "Property " << p << " on target \""
|
||||||
<< tgt->GetName() << "\" does\nnot match the "
|
<< tgt->GetName() << "\" does\nnot match the "
|
||||||
"INTERFACE_" << p << " property requirement\nof "
|
"INTERFACE_" << p << " property requirement\nof "
|
||||||
"dependency \"" << li->Target->GetName() << "\".\n";
|
"dependency \"" << theTarget->GetName() << "\".\n";
|
||||||
cmSystemTools::Error(e.str().c_str());
|
cmSystemTools::Error(e.str().c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4636,7 +4528,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
<< tgt->GetName() << "\" is\nimplied to be " << defaultValue
|
<< tgt->GetName() << "\" is\nimplied to be " << defaultValue
|
||||||
<< " because it was used to determine the link libraries\n"
|
<< " because it was used to determine the link libraries\n"
|
||||||
"already. The INTERFACE_" << p << " property on\ndependency \""
|
"already. The INTERFACE_" << p << " property on\ndependency \""
|
||||||
<< li->Target->GetName() << "\" is in conflict.\n";
|
<< theTarget->GetName() << "\" is in conflict.\n";
|
||||||
cmSystemTools::Error(e.str().c_str());
|
cmSystemTools::Error(e.str().c_str());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4667,7 +4559,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
||||||
{
|
{
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
e << "The INTERFACE_" << p << " property of \""
|
e << "The INTERFACE_" << p << " property of \""
|
||||||
<< li->Target->GetName() << "\" does\nnot agree with the value "
|
<< theTarget->GetName() << "\" does\nnot agree with the value "
|
||||||
"of " << p << " already determined\nfor \""
|
"of " << p << " already determined\nfor \""
|
||||||
<< tgt->GetName() << "\".\n";
|
<< tgt->GetName() << "\".\n";
|
||||||
cmSystemTools::Error(e.str().c_str());
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
@ -4748,23 +4640,19 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
|
||||||
const char *interfaceProperty,
|
const char *interfaceProperty,
|
||||||
const char *config)
|
const char *config)
|
||||||
{
|
{
|
||||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
std::vector<cmTarget*> deps;
|
||||||
if(!info)
|
tgt->GetTransitiveTargetClosure(config, tgt, deps);
|
||||||
|
|
||||||
|
if(deps.empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
for(std::vector<cmTarget*>::const_iterator li =
|
||||||
|
|
||||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
|
||||||
deps.begin();
|
deps.begin();
|
||||||
li != deps.end(); ++li)
|
li != deps.end(); ++li)
|
||||||
{
|
{
|
||||||
if (!li->Target)
|
const char *prop = (*li)->GetProperty(interfaceProperty);
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const char *prop = li->Target->GetProperty(interfaceProperty);
|
|
||||||
if (!prop)
|
if (!prop)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -5316,24 +5204,124 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
|
||||||
{
|
{
|
||||||
// Compute the link interface for this configuration.
|
// Compute the link interface for this configuration.
|
||||||
cmTargetInternals::OptionalLinkInterface iface;
|
cmTargetInternals::OptionalLinkInterface iface;
|
||||||
iface.Exists = this->ComputeLinkInterface(config, iface, head);
|
iface.ExplicitLibraries =
|
||||||
|
this->ComputeLinkInterfaceLibraries(config, iface, head, iface.Exists);
|
||||||
|
if (iface.Exists)
|
||||||
|
{
|
||||||
|
this->Internal->ComputeLinkInterface(this, config, iface,
|
||||||
|
head, iface.ExplicitLibraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the information for this configuration.
|
||||||
|
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
||||||
|
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
||||||
|
}
|
||||||
|
else if(!i->second.Complete && i->second.Exists)
|
||||||
|
{
|
||||||
|
this->Internal->ComputeLinkInterface(this, config, i->second, head,
|
||||||
|
i->second.ExplicitLibraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i->second.Exists ? &i->second : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget::LinkInterface const*
|
||||||
|
cmTarget::GetLinkInterfaceLibraries(const char* config,
|
||||||
|
cmTarget const* head) const
|
||||||
|
{
|
||||||
|
// Imported targets have their own link interface.
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head))
|
||||||
|
{
|
||||||
|
return &info->LinkInterface;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link interfaces are not supported for executables that do not
|
||||||
|
// export symbols.
|
||||||
|
if(this->GetType() == cmTarget::EXECUTABLE &&
|
||||||
|
!this->IsExecutableWithExports())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup any existing link interface for this configuration.
|
||||||
|
TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
|
||||||
|
|
||||||
|
cmTargetInternals::LinkInterfaceMapType::iterator
|
||||||
|
i = this->Internal->LinkInterfaceMap.find(key);
|
||||||
|
if(i == this->Internal->LinkInterfaceMap.end())
|
||||||
|
{
|
||||||
|
// Compute the link interface for this configuration.
|
||||||
|
cmTargetInternals::OptionalLinkInterface iface;
|
||||||
|
iface.ExplicitLibraries = this->ComputeLinkInterfaceLibraries(config,
|
||||||
|
iface,
|
||||||
|
head,
|
||||||
|
iface.Exists);
|
||||||
|
|
||||||
// Store the information for this configuration.
|
// Store the information for this configuration.
|
||||||
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
||||||
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return i->second.Exists? &i->second : 0;
|
return i->second.Exists ? &i->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::GetTransitivePropertyLinkLibraries(
|
void processILibs(const char* config,
|
||||||
const char* config,
|
|
||||||
cmTarget const* headTarget,
|
cmTarget const* headTarget,
|
||||||
std::vector<std::string> &libs) const
|
std::string const& name,
|
||||||
|
std::vector<cmTarget*>& tgts, std::set<cmTarget*>& emitted)
|
||||||
{
|
{
|
||||||
cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
|
if (cmTarget* tgt = headTarget->GetMakefile()
|
||||||
headTarget);
|
->FindTargetToUse(name.c_str()))
|
||||||
|
{
|
||||||
|
if (emitted.insert(tgt).second)
|
||||||
|
{
|
||||||
|
tgts.push_back(tgt);
|
||||||
|
std::vector<std::string> ilibs;
|
||||||
|
cmTarget::LinkInterface const* iface =
|
||||||
|
tgt->GetLinkInterfaceLibraries(config, headTarget);
|
||||||
|
if (iface)
|
||||||
|
{
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
it = iface->Libraries.begin();
|
||||||
|
it != iface->Libraries.end(); ++it)
|
||||||
|
{
|
||||||
|
processILibs(config, headTarget, *it, tgts, emitted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::GetTransitiveTargetClosure(const char* config,
|
||||||
|
cmTarget const* headTarget,
|
||||||
|
std::vector<cmTarget*> &tgts) const
|
||||||
|
{
|
||||||
|
std::set<cmTarget*> emitted;
|
||||||
|
|
||||||
|
cmTarget::LinkImplementation const* impl
|
||||||
|
= this->GetLinkImplementationLibraries(config, headTarget);
|
||||||
|
|
||||||
|
for(std::vector<std::string>::const_iterator it = impl->Libraries.begin();
|
||||||
|
it != impl->Libraries.end(); ++it)
|
||||||
|
{
|
||||||
|
processILibs(config, headTarget, *it, tgts, emitted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::GetTransitivePropertyTargets(const char* config,
|
||||||
|
cmTarget const* headTarget,
|
||||||
|
std::vector<cmTarget*> &tgts) const
|
||||||
|
{
|
||||||
|
cmTarget::LinkInterface const* iface
|
||||||
|
= this->GetLinkInterfaceLibraries(config, headTarget);
|
||||||
if (!iface)
|
if (!iface)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -5342,7 +5330,15 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
|
||||||
|| this->GetPolicyStatusCMP0022() == cmPolicies::WARN
|
|| this->GetPolicyStatusCMP0022() == cmPolicies::WARN
|
||||||
|| this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
|
|| this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
|
||||||
{
|
{
|
||||||
libs = iface->Libraries;
|
for(std::vector<std::string>::const_iterator it = iface->Libraries.begin();
|
||||||
|
it != iface->Libraries.end(); ++it)
|
||||||
|
{
|
||||||
|
if (cmTarget* tgt = headTarget->GetMakefile()
|
||||||
|
->FindTargetToUse(it->c_str()))
|
||||||
|
{
|
||||||
|
tgts.push_back(tgt);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5360,17 +5356,30 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
|
||||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
|
cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
|
||||||
linkIfaceProp, 0, 0);
|
linkIfaceProp, 0, 0);
|
||||||
dagChecker.SetTransitivePropertiesOnly();
|
dagChecker.SetTransitivePropertiesOnly();
|
||||||
|
std::vector<std::string> libs;
|
||||||
cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
|
cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
|
||||||
this->Makefile,
|
this->Makefile,
|
||||||
config,
|
config,
|
||||||
false,
|
false,
|
||||||
headTarget,
|
headTarget,
|
||||||
this, &dagChecker), libs);
|
this, &dagChecker), libs);
|
||||||
|
|
||||||
|
for(std::vector<std::string>::const_iterator it = libs.begin();
|
||||||
|
it != libs.end(); ++it)
|
||||||
|
{
|
||||||
|
if (cmTarget* tgt = headTarget->GetMakefile()
|
||||||
|
->FindTargetToUse(it->c_str()))
|
||||||
|
{
|
||||||
|
tgts.push_back(tgt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
|
||||||
cmTarget const* headTarget) const
|
LinkInterface& iface,
|
||||||
|
cmTarget const* headTarget,
|
||||||
|
bool &exists) const
|
||||||
{
|
{
|
||||||
// Construct the property name suffix for this configuration.
|
// Construct the property name suffix for this configuration.
|
||||||
std::string suffix = "_";
|
std::string suffix = "_";
|
||||||
|
@ -5446,8 +5455,10 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||||
(this->GetType() == cmTarget::EXECUTABLE ||
|
(this->GetType() == cmTarget::EXECUTABLE ||
|
||||||
(this->GetType() == cmTarget::MODULE_LIBRARY)))
|
(this->GetType() == cmTarget::MODULE_LIBRARY)))
|
||||||
{
|
{
|
||||||
return false;
|
exists = false;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
exists = true;
|
||||||
|
|
||||||
if(explicitLibraries)
|
if(explicitLibraries)
|
||||||
{
|
{
|
||||||
|
@ -5462,52 +5473,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||||
false,
|
false,
|
||||||
headTarget,
|
headTarget,
|
||||||
this, &dagChecker), iface.Libraries);
|
this, &dagChecker), iface.Libraries);
|
||||||
|
|
||||||
if(this->GetType() == cmTarget::SHARED_LIBRARY
|
|
||||||
|| this->GetType() == cmTarget::STATIC_LIBRARY
|
|
||||||
|| this->GetType() == cmTarget::INTERFACE_LIBRARY)
|
|
||||||
{
|
|
||||||
// Shared libraries may have runtime implementation dependencies
|
|
||||||
// on other shared libraries that are not in the interface.
|
|
||||||
std::set<cmStdString> emitted;
|
|
||||||
for(std::vector<std::string>::const_iterator
|
|
||||||
li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
|
|
||||||
{
|
|
||||||
emitted.insert(*li);
|
|
||||||
}
|
|
||||||
if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
|
|
||||||
{
|
|
||||||
LinkImplementation const* impl = this->GetLinkImplementation(config,
|
|
||||||
headTarget);
|
|
||||||
for(std::vector<std::string>::const_iterator
|
|
||||||
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
|
|
||||||
{
|
|
||||||
if(emitted.insert(*li).second)
|
|
||||||
{
|
|
||||||
if(cmTarget* tgt = this->Makefile->FindTargetToUse(*li))
|
|
||||||
{
|
|
||||||
// This is a runtime dependency on another shared library.
|
|
||||||
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
|
|
||||||
{
|
|
||||||
iface.SharedDeps.push_back(*li);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: Recognize shared library file names. Perhaps this
|
|
||||||
// should be moved to cmComputeLinkInformation, but that creates
|
|
||||||
// a chicken-and-egg problem since this list is needed for its
|
|
||||||
// construction.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(this->LinkLanguagePropagatesToDependents())
|
|
||||||
{
|
|
||||||
// Targets using this archive need its language runtime libraries.
|
|
||||||
iface.Languages = impl->Languages;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
|
else if (this->PolicyStatusCMP0022 == cmPolicies::WARN
|
||||||
|| this->PolicyStatusCMP0022 == cmPolicies::OLD)
|
|| this->PolicyStatusCMP0022 == cmPolicies::OLD)
|
||||||
|
@ -5517,17 +5482,9 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||||
// to the link implementation.
|
// to the link implementation.
|
||||||
{
|
{
|
||||||
// The link implementation is the default link interface.
|
// The link implementation is the default link interface.
|
||||||
LinkImplementation const* impl = this->GetLinkImplementation(config,
|
LinkImplementation const* impl =
|
||||||
headTarget);
|
this->GetLinkImplementationLibraries(config, headTarget);
|
||||||
iface.ImplementationIsInterface = true;
|
|
||||||
iface.Libraries = impl->Libraries;
|
iface.Libraries = impl->Libraries;
|
||||||
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
|
|
||||||
if(this->LinkLanguagePropagatesToDependents())
|
|
||||||
{
|
|
||||||
// Targets using this archive need its language runtime libraries.
|
|
||||||
iface.Languages = impl->Languages;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
|
if(this->PolicyStatusCMP0022 == cmPolicies::WARN &&
|
||||||
!this->Internal->PolicyWarnedCMP0022)
|
!this->Internal->PolicyWarnedCMP0022)
|
||||||
{
|
{
|
||||||
|
@ -5592,25 +5549,107 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return explicitLibraries;
|
||||||
|
}
|
||||||
|
|
||||||
if(this->GetType() == cmTarget::STATIC_LIBRARY)
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget,
|
||||||
|
const char* config,
|
||||||
|
OptionalLinkInterface& iface,
|
||||||
|
cmTarget const* headTarget,
|
||||||
|
const char* explicitLibraries) const
|
||||||
|
{
|
||||||
|
if(explicitLibraries)
|
||||||
{
|
{
|
||||||
|
if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY
|
||||||
|
|| thisTarget->GetType() == cmTarget::STATIC_LIBRARY
|
||||||
|
|| thisTarget->GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||||
|
{
|
||||||
|
// Shared libraries may have runtime implementation dependencies
|
||||||
|
// on other shared libraries that are not in the interface.
|
||||||
|
std::set<cmStdString> emitted;
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li)
|
||||||
|
{
|
||||||
|
emitted.insert(*li);
|
||||||
|
}
|
||||||
|
if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY)
|
||||||
|
{
|
||||||
|
cmTarget::LinkImplementation const* impl =
|
||||||
|
thisTarget->GetLinkImplementation(config, headTarget);
|
||||||
|
for(std::vector<std::string>::const_iterator
|
||||||
|
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
|
||||||
|
{
|
||||||
|
if(emitted.insert(*li).second)
|
||||||
|
{
|
||||||
|
if(cmTarget* tgt = thisTarget->Makefile->FindTargetToUse(*li))
|
||||||
|
{
|
||||||
|
// This is a runtime dependency on another shared library.
|
||||||
|
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
|
||||||
|
{
|
||||||
|
iface.SharedDeps.push_back(*li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Recognize shared library file names. Perhaps this
|
||||||
|
// should be moved to cmComputeLinkInformation, but that creates
|
||||||
|
// a chicken-and-egg problem since this list is needed for its
|
||||||
|
// construction.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(thisTarget->LinkLanguagePropagatesToDependents())
|
||||||
|
{
|
||||||
|
// Targets using this archive need its language runtime libraries.
|
||||||
|
iface.Languages = impl->Languages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (thisTarget->PolicyStatusCMP0022 == cmPolicies::WARN
|
||||||
|
|| thisTarget->PolicyStatusCMP0022 == cmPolicies::OLD)
|
||||||
|
{
|
||||||
|
// The link implementation is the default link interface.
|
||||||
|
cmTarget::LinkImplementation const*
|
||||||
|
impl = thisTarget->GetLinkImplementation(config, headTarget);
|
||||||
|
iface.ImplementationIsInterface = true;
|
||||||
|
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
|
||||||
|
if(thisTarget->LinkLanguagePropagatesToDependents())
|
||||||
|
{
|
||||||
|
// Targets using this archive need its language runtime libraries.
|
||||||
|
iface.Languages = impl->Languages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY)
|
||||||
|
{
|
||||||
|
// Construct the property name suffix for this configuration.
|
||||||
|
std::string suffix = "_";
|
||||||
|
if(config && *config)
|
||||||
|
{
|
||||||
|
suffix += cmSystemTools::UpperCase(config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
suffix += "NOCONFIG";
|
||||||
|
}
|
||||||
|
|
||||||
// How many repetitions are needed if this library has cyclic
|
// How many repetitions are needed if this library has cyclic
|
||||||
// dependencies?
|
// dependencies?
|
||||||
std::string propName = "LINK_INTERFACE_MULTIPLICITY";
|
std::string propName = "LINK_INTERFACE_MULTIPLICITY";
|
||||||
propName += suffix;
|
propName += suffix;
|
||||||
if(const char* config_reps = this->GetProperty(propName.c_str()))
|
if(const char* config_reps = thisTarget->GetProperty(propName.c_str()))
|
||||||
{
|
{
|
||||||
sscanf(config_reps, "%u", &iface.Multiplicity);
|
sscanf(config_reps, "%u", &iface.Multiplicity);
|
||||||
}
|
}
|
||||||
else if(const char* reps =
|
else if(const char* reps =
|
||||||
this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
|
thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
|
||||||
{
|
{
|
||||||
sscanf(reps, "%u", &iface.Multiplicity);
|
sscanf(reps, "%u", &iface.Multiplicity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iface.Complete = true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -5626,6 +5665,41 @@ cmTarget::GetLinkImplementation(const char* config, cmTarget const* head) const
|
||||||
// Lookup any existing link implementation for this configuration.
|
// Lookup any existing link implementation for this configuration.
|
||||||
TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
|
TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
|
||||||
|
|
||||||
|
cmTargetInternals::LinkImplMapType::iterator
|
||||||
|
i = this->Internal->LinkImplMap.find(key);
|
||||||
|
if(i == this->Internal->LinkImplMap.end())
|
||||||
|
{
|
||||||
|
// Compute the link implementation for this configuration.
|
||||||
|
LinkImplementation impl;
|
||||||
|
this->ComputeLinkImplementation(config, impl, head);
|
||||||
|
this->ComputeLinkImplementationLanguages(impl);
|
||||||
|
|
||||||
|
// Store the information for this configuration.
|
||||||
|
cmTargetInternals::LinkImplMapType::value_type entry(key, impl);
|
||||||
|
i = this->Internal->LinkImplMap.insert(entry).first;
|
||||||
|
}
|
||||||
|
else if (i->second.Languages.empty())
|
||||||
|
{
|
||||||
|
this->ComputeLinkImplementationLanguages(i->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
cmTarget::LinkImplementation const*
|
||||||
|
cmTarget::GetLinkImplementationLibraries(const char* config,
|
||||||
|
cmTarget const* head) const
|
||||||
|
{
|
||||||
|
// There is no link implementation for imported targets.
|
||||||
|
if(this->IsImported())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup any existing link implementation for this configuration.
|
||||||
|
TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : ""));
|
||||||
|
|
||||||
cmTargetInternals::LinkImplMapType::iterator
|
cmTargetInternals::LinkImplMapType::iterator
|
||||||
i = this->Internal->LinkImplMap.find(key);
|
i = this->Internal->LinkImplMap.find(key);
|
||||||
if(i == this->Internal->LinkImplMap.end())
|
if(i == this->Internal->LinkImplMap.end())
|
||||||
|
@ -5715,7 +5789,12 @@ void cmTarget::ComputeLinkImplementation(const char* config,
|
||||||
impl.WrongConfigLibraries.push_back(item);
|
impl.WrongConfigLibraries.push_back(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
|
||||||
|
{
|
||||||
// This target needs runtime libraries for its source languages.
|
// This target needs runtime libraries for its source languages.
|
||||||
std::set<cmStdString> languages;
|
std::set<cmStdString> languages;
|
||||||
// Get languages used in our source files.
|
// Get languages used in our source files.
|
||||||
|
|
|
@ -139,34 +139,6 @@ public:
|
||||||
return this->ObjectLibraries;
|
return this->ObjectLibraries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Flags for a given source file as used in this target. Typically assigned
|
|
||||||
* via SET_TARGET_PROPERTIES when the property is a list of source files.
|
|
||||||
*/
|
|
||||||
enum SourceFileType
|
|
||||||
{
|
|
||||||
SourceFileTypeNormal,
|
|
||||||
SourceFileTypePrivateHeader, // is in "PRIVATE_HEADER" target property
|
|
||||||
SourceFileTypePublicHeader, // is in "PUBLIC_HEADER" target property
|
|
||||||
SourceFileTypeResource, // is in "RESOURCE" target property *or*
|
|
||||||
// has MACOSX_PACKAGE_LOCATION=="Resources"
|
|
||||||
SourceFileTypeMacContent // has MACOSX_PACKAGE_LOCATION!="Resources"
|
|
||||||
};
|
|
||||||
struct SourceFileFlags
|
|
||||||
{
|
|
||||||
SourceFileFlags(): Type(SourceFileTypeNormal), MacFolder(0) {}
|
|
||||||
SourceFileFlags(SourceFileFlags const& r):
|
|
||||||
Type(r.Type), MacFolder(r.MacFolder) {}
|
|
||||||
SourceFileType Type;
|
|
||||||
const char* MacFolder; // location inside Mac content folders
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the flags for a given source file as used in this target
|
|
||||||
*/
|
|
||||||
struct SourceFileFlags
|
|
||||||
GetTargetSourceFileFlags(const cmSourceFile* sf) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add sources to the target.
|
* Add sources to the target.
|
||||||
*/
|
*/
|
||||||
|
@ -292,9 +264,14 @@ public:
|
||||||
if the target cannot be linked. */
|
if the target cannot be linked. */
|
||||||
LinkInterface const* GetLinkInterface(const char* config,
|
LinkInterface const* GetLinkInterface(const char* config,
|
||||||
cmTarget const* headTarget) const;
|
cmTarget const* headTarget) const;
|
||||||
void GetTransitivePropertyLinkLibraries(const char* config,
|
LinkInterface const* GetLinkInterfaceLibraries(const char* config,
|
||||||
|
cmTarget const* headTarget) const;
|
||||||
|
void GetTransitivePropertyTargets(const char* config,
|
||||||
cmTarget const* headTarget,
|
cmTarget const* headTarget,
|
||||||
std::vector<std::string> &libs) const;
|
std::vector<cmTarget*> &libs) const;
|
||||||
|
void GetTransitiveTargetClosure(const char* config,
|
||||||
|
cmTarget const* headTarget,
|
||||||
|
std::vector<cmTarget*> &libs) const;
|
||||||
|
|
||||||
/** The link implementation specifies the direct library
|
/** The link implementation specifies the direct library
|
||||||
dependencies needed by the object files of the target. */
|
dependencies needed by the object files of the target. */
|
||||||
|
@ -313,6 +290,9 @@ public:
|
||||||
LinkImplementation const* GetLinkImplementation(const char* config,
|
LinkImplementation const* GetLinkImplementation(const char* config,
|
||||||
cmTarget const* head) const;
|
cmTarget const* head) const;
|
||||||
|
|
||||||
|
LinkImplementation const* GetLinkImplementationLibraries(const char* config,
|
||||||
|
cmTarget const* head) const;
|
||||||
|
|
||||||
/** Link information from the transitive closure of the link
|
/** Link information from the transitive closure of the link
|
||||||
implementation and the interfaces of its dependencies. */
|
implementation and the interfaces of its dependencies. */
|
||||||
struct LinkClosure
|
struct LinkClosure
|
||||||
|
@ -358,11 +338,6 @@ public:
|
||||||
void
|
void
|
||||||
GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
|
GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure the full path to all source files is known.
|
|
||||||
*/
|
|
||||||
bool FindSourceFiles();
|
|
||||||
|
|
||||||
///! Return the preferred linker language for this target
|
///! Return the preferred linker language for this target
|
||||||
const char* GetLinkerLanguage(const char* config = 0,
|
const char* GetLinkerLanguage(const char* config = 0,
|
||||||
cmTarget const* head = 0) const;
|
cmTarget const* head = 0) const;
|
||||||
|
@ -723,12 +698,15 @@ private:
|
||||||
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||||
const char* config) const;
|
const char* config) const;
|
||||||
|
|
||||||
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
|
const char* ComputeLinkInterfaceLibraries(const char* config,
|
||||||
cmTarget const* head) const;
|
LinkInterface& iface,
|
||||||
|
cmTarget const* head,
|
||||||
|
bool &exists) const;
|
||||||
|
|
||||||
void ComputeLinkImplementation(const char* config,
|
void ComputeLinkImplementation(const char* config,
|
||||||
LinkImplementation& impl,
|
LinkImplementation& impl,
|
||||||
cmTarget const* head) const;
|
cmTarget const* head) const;
|
||||||
|
void ComputeLinkImplementationLanguages(LinkImplementation& impl) const;
|
||||||
void ComputeLinkClosure(const char* config, LinkClosure& lc,
|
void ComputeLinkClosure(const char* config, LinkClosure& lc,
|
||||||
cmTarget const* head) const;
|
cmTarget const* head) const;
|
||||||
|
|
||||||
|
@ -756,7 +734,6 @@ private:
|
||||||
friend class cmTargetTraceDependencies;
|
friend class cmTargetTraceDependencies;
|
||||||
cmTargetInternalPointer Internal;
|
cmTargetInternalPointer Internal;
|
||||||
|
|
||||||
void ConstructSourceFileFlags() const;
|
|
||||||
void ComputeVersionedName(std::string& vName,
|
void ComputeVersionedName(std::string& vName,
|
||||||
std::string const& prefix,
|
std::string const& prefix,
|
||||||
std::string const& base,
|
std::string const& base,
|
||||||
|
|
|
@ -1666,10 +1666,10 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
|
||||||
linkOptions.AddFlag("ImportLibrary", imLib.c_str());
|
linkOptions.AddFlag("ImportLibrary", imLib.c_str());
|
||||||
linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
|
linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
|
||||||
linkOptions.Parse(flags.c_str());
|
linkOptions.Parse(flags.c_str());
|
||||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||||
|
if(!def.empty())
|
||||||
{
|
{
|
||||||
linkOptions.AddFlag("ModuleDefinitionFile",
|
linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
|
||||||
this->GeneratorTarget->ModuleDefinitionFile.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->LinkOptions[config] = pOptions.release();
|
this->LinkOptions[config] = pOptions.release();
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
CMake Debug Log:
|
||||||
|
Boolean compatibility of property "BOOL_PROP7" for target
|
||||||
|
"CompatibleInterface" \(result: "FALSE"\):
|
||||||
|
|
||||||
|
\* Target "CompatibleInterface" property is implied by use.
|
||||||
|
\* Target "iface1" property value "FALSE" \(Agree\)
|
||||||
|
+
|
||||||
CMake Debug Log:
|
CMake Debug Log:
|
||||||
Boolean compatibility of property "BOOL_PROP1" for target
|
Boolean compatibility of property "BOOL_PROP1" for target
|
||||||
"CompatibleInterface" \(result: "TRUE"\):
|
"CompatibleInterface" \(result: "TRUE"\):
|
||||||
|
@ -39,13 +46,6 @@ CMake Debug Log:
|
||||||
\* Target "iface1" property value "FALSE" \(Interface set\)
|
\* Target "iface1" property value "FALSE" \(Interface set\)
|
||||||
\* Target "iface2" property value "FALSE" \(Agree\)
|
\* Target "iface2" property value "FALSE" \(Agree\)
|
||||||
+
|
+
|
||||||
CMake Debug Log:
|
|
||||||
Boolean compatibility of property "BOOL_PROP7" for target
|
|
||||||
"CompatibleInterface" \(result: "FALSE"\):
|
|
||||||
|
|
||||||
\* Target "CompatibleInterface" property is implied by use.
|
|
||||||
\* Target "iface1" property value "FALSE" \(Agree\)
|
|
||||||
+
|
|
||||||
CMake Debug Log:
|
CMake Debug Log:
|
||||||
String compatibility of property "STRING_PROP1" for target
|
String compatibility of property "STRING_PROP1" for target
|
||||||
"CompatibleInterface" \(result: "prop1"\):
|
"CompatibleInterface" \(result: "prop1"\):
|
||||||
|
|
Loading…
Reference in New Issue