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
|
||||
|
||||
std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
||||
std::string getLinkedTargetsContent(const std::vector<cmTarget*> &targets,
|
||||
cmTarget const* target,
|
||||
cmTarget const* headTarget,
|
||||
cmGeneratorExpressionContext *context,
|
||||
|
@ -811,23 +811,21 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
|||
|
||||
std::string sep;
|
||||
std::string depString;
|
||||
for (std::vector<std::string>::const_iterator
|
||||
it = libraries.begin();
|
||||
it != libraries.end(); ++it)
|
||||
for (std::vector<cmTarget*>::const_iterator
|
||||
it = targets.begin();
|
||||
it != targets.end(); ++it)
|
||||
{
|
||||
if (*it == target->GetName())
|
||||
if (*it == target)
|
||||
{
|
||||
// Broken code can have a target in its own link interface.
|
||||
// Don't follow such link interface entries so as not to create a
|
||||
// self-referencing loop.
|
||||
continue;
|
||||
}
|
||||
if (context->Makefile->FindTargetToUse(*it))
|
||||
{
|
||||
depString +=
|
||||
sep + "$<TARGET_PROPERTY:" + *it + "," + interfacePropertyName + ">";
|
||||
sep = ";";
|
||||
}
|
||||
depString +=
|
||||
sep + "$<TARGET_PROPERTY:" +
|
||||
(*it)->GetName() + "," + interfacePropertyName + ">";
|
||||
sep = ";";
|
||||
}
|
||||
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(depString);
|
||||
std::string linkedTargetsContent = cge->Evaluate(context->Makefile,
|
||||
|
@ -843,6 +841,27 @@ std::string getLinkedTargetsContent(const std::vector<std::string> &libraries,
|
|||
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
|
||||
{
|
||||
|
@ -1065,13 +1084,13 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
cmStrCmp(propertyName)) != transEnd)
|
||||
{
|
||||
|
||||
std::vector<std::string> libs;
|
||||
target->GetTransitivePropertyLinkLibraries(context->Config,
|
||||
headTarget, libs);
|
||||
if (!libs.empty())
|
||||
std::vector<cmTarget*> tgts;
|
||||
target->GetTransitivePropertyTargets(context->Config,
|
||||
headTarget, tgts);
|
||||
if (!tgts.empty())
|
||||
{
|
||||
linkedTargetsContent =
|
||||
getLinkedTargetsContent(libs, target,
|
||||
getLinkedTargetsContent(tgts, target,
|
||||
headTarget,
|
||||
context, &dagChecker,
|
||||
interfacePropertyName);
|
||||
|
@ -1080,9 +1099,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
|||
else if (std::find_if(transBegin, transEnd,
|
||||
cmStrCmp(interfacePropertyName)) != transEnd)
|
||||
{
|
||||
const cmTarget::LinkImplementation *impl = target->GetLinkImplementation(
|
||||
context->Config,
|
||||
headTarget);
|
||||
const cmTarget::LinkImplementation *impl
|
||||
= target->GetLinkImplementationLibraries(context->Config,
|
||||
headTarget);
|
||||
if(impl)
|
||||
{
|
||||
linkedTargetsContent =
|
||||
|
|
|
@ -25,7 +25,196 @@
|
|||
#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->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||
|
@ -62,19 +251,12 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name,
|
||||
static void handleSystemIncludesDep(cmMakefile *mf, cmTarget* depTgt,
|
||||
const char *config, cmTarget *headTarget,
|
||||
cmGeneratorExpressionDAGChecker *dagChecker,
|
||||
std::vector<std::string>& result,
|
||||
bool excludeImported)
|
||||
{
|
||||
cmTarget* depTgt = mf->FindTargetToUse(name);
|
||||
|
||||
if (!depTgt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cmListFileBacktrace lfbt;
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorTarget::GetIDLSources(std::vector<cmSourceFile*>& srcs) const
|
||||
{
|
||||
srcs = this->IDLSources;
|
||||
IMPLEMENT_VISIT(IDLSources);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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
|
||||
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
|
||||
cmGeneratorTarget::GetExpectedResxHeaders(std::set<std::string>& srcs) const
|
||||
{
|
||||
srcs = this->ExpectedResxHeaders;
|
||||
ResxData data;
|
||||
IMPLEMENT_VISIT_IMPL(Resx, COMMA cmGeneratorTarget::ResxData)
|
||||
srcs = data.ExpectedResxHeaders;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmGeneratorTarget::GetExternalObjects(std::vector<cmSourceFile*>& srcs) const
|
||||
void cmGeneratorTarget::GetResxSources(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);
|
||||
}
|
||||
|
||||
std::set<cmStdString> uniqueDeps;
|
||||
std::set<cmTarget*> uniqueDeps;
|
||||
for(std::vector<std::string>::const_iterator li = impl->Libraries.begin();
|
||||
li != impl->Libraries.end(); ++li)
|
||||
{
|
||||
if (uniqueDeps.insert(*li).second)
|
||||
cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
|
||||
if (!tgt)
|
||||
{
|
||||
cmTarget* tgt = this->Makefile->FindTargetToUse(*li);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!tgt)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
|
||||
if (uniqueDeps.insert(tgt).second)
|
||||
{
|
||||
handleSystemIncludesDep(this->Makefile, tgt, config, this->Target,
|
||||
&dagChecker, result, excludeImported);
|
||||
|
||||
std::vector<std::string> deps;
|
||||
tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps);
|
||||
std::vector<cmTarget*> 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)
|
||||
{
|
||||
if (uniqueDeps.insert(*di).second)
|
||||
|
@ -289,102 +497,6 @@ void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
|||
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()
|
||||
{
|
||||
|
@ -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
|
||||
cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs) const
|
||||
|
@ -876,3 +996,97 @@ bool cmStrictTargetComparison::operator()(cmTarget const* t1,
|
|||
}
|
||||
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;
|
||||
cmGlobalGenerator const* GlobalGenerator;
|
||||
|
||||
std::string ModuleDefinitionFile;
|
||||
std::string GetModuleDefinitionFile() const;
|
||||
|
||||
/** Full path with trailing slash to the top-level directory
|
||||
holding object files for this target. Includes the build
|
||||
|
@ -82,31 +82,56 @@ public:
|
|||
*/
|
||||
void TraceDependencies();
|
||||
|
||||
void ClassifySources();
|
||||
void LookupObjectLibraries();
|
||||
|
||||
/** Get sources that must be built before the given source. */
|
||||
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:
|
||||
friend class cmTargetTraceDependencies;
|
||||
struct SourceEntry { std::vector<cmSourceFile*> Depends; };
|
||||
typedef std::map<cmSourceFile*, SourceEntry> SourceEntriesType;
|
||||
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::set<cmSourceFile const*> ExplicitObjectName;
|
||||
std::set<std::string> ExpectedResxHeaders;
|
||||
std::vector<cmSourceFile*> ObjectSources;
|
||||
mutable std::vector<cmSourceFile*> ObjectSources;
|
||||
std::vector<cmTarget*> ObjectLibraries;
|
||||
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&);
|
||||
void operator=(cmGeneratorTarget const&);
|
||||
};
|
||||
|
|
|
@ -1148,12 +1148,6 @@ void cmGlobalGenerator::Generate()
|
|||
return;
|
||||
}
|
||||
|
||||
// Check that all targets are valid.
|
||||
if(!this->CheckTargets())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this->FinalizeTargetCompileInfo();
|
||||
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
|
@ -1305,35 +1299,6 @@ bool cmGlobalGenerator::ComputeTargetDepends()
|
|||
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)
|
||||
{
|
||||
|
@ -1474,7 +1439,6 @@ void cmGlobalGenerator::ComputeGeneratorTargetObjects()
|
|||
continue;
|
||||
}
|
||||
cmGeneratorTarget* gt = ti->second;
|
||||
gt->ClassifySources();
|
||||
gt->LookupObjectLibraries();
|
||||
this->ComputeTargetObjects(gt);
|
||||
}
|
||||
|
|
|
@ -340,7 +340,6 @@ protected:
|
|||
|
||||
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const;
|
||||
|
||||
bool CheckTargets();
|
||||
typedef std::vector<std::pair<cmQtAutoGenerators,
|
||||
cmTarget const*> > AutogensType;
|
||||
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...
|
||||
//
|
||||
cmTarget::SourceFileFlags tsFlags = cmtarget.GetTargetSourceFileFlags(sf);
|
||||
bool isResource = (tsFlags.Type == cmTarget::SourceFileTypeResource);
|
||||
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||
this->GetGeneratorTarget(&cmtarget)->GetTargetSourceFileFlags(sf);
|
||||
bool isResource = tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource;
|
||||
|
||||
// Is this a "private" or "public" framework header file?
|
||||
// Set the ATTRIBUTES attribute appropriately...
|
||||
//
|
||||
if(cmtarget.IsFrameworkOnApple())
|
||||
{
|
||||
if(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader)
|
||||
if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader)
|
||||
{
|
||||
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
attrs->AddObject(this->CreateString("Private"));
|
||||
settings->AddAttribute("ATTRIBUTES", attrs);
|
||||
isResource = true;
|
||||
}
|
||||
else if(tsFlags.Type == cmTarget::SourceFileTypePublicHeader)
|
||||
else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader)
|
||||
{
|
||||
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
|
||||
attrs->AddObject(this->CreateString("Public"));
|
||||
|
@ -973,6 +974,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
|
||||
{
|
||||
cmTarget& cmtarget = l->second;
|
||||
cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
|
||||
|
||||
// make sure ALL_BUILD, INSTALL, etc are only done once
|
||||
if(this->SpecialTargetEmitted(l->first.c_str()))
|
||||
|
@ -1011,8 +1013,8 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
cmXCodeObject* filetype =
|
||||
fr->GetObject()->GetObject("explicitFileType");
|
||||
|
||||
cmTarget::SourceFileFlags tsFlags =
|
||||
cmtarget.GetTargetSourceFileFlags(*i);
|
||||
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||
gtgt->GetTargetSourceFileFlags(*i);
|
||||
|
||||
if(filetype &&
|
||||
strcmp(filetype->GetString(), "compiled.mach-o.objfile") == 0)
|
||||
|
@ -1020,12 +1022,12 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
externalObjFiles.push_back(xsf);
|
||||
}
|
||||
else if(this->IsHeaderFile(*i) ||
|
||||
(tsFlags.Type == cmTarget::SourceFileTypePrivateHeader) ||
|
||||
(tsFlags.Type == cmTarget::SourceFileTypePublicHeader))
|
||||
(tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) ||
|
||||
(tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader))
|
||||
{
|
||||
headerFiles.push_back(xsf);
|
||||
}
|
||||
else if(tsFlags.Type == cmTarget::SourceFileTypeResource)
|
||||
else if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource)
|
||||
{
|
||||
resourceFiles.push_back(xsf);
|
||||
}
|
||||
|
@ -1048,7 +1050,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
// the externalObjFiles above, except each one is not a cmSourceFile
|
||||
// within the target.)
|
||||
std::vector<std::string> objs;
|
||||
this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
|
||||
gtgt->UseObjectLibraries(objs);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
|
@ -1138,9 +1140,9 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
||||
i != classes.end(); ++i)
|
||||
{
|
||||
cmTarget::SourceFileFlags tsFlags =
|
||||
cmtarget.GetTargetSourceFileFlags(*i);
|
||||
if(tsFlags.Type == cmTarget::SourceFileTypeMacContent)
|
||||
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||
gtgt->GetTargetSourceFileFlags(*i);
|
||||
if(tsFlags.Type == cmGeneratorTarget::SourceFileTypeMacContent)
|
||||
{
|
||||
bundleFiles[tsFlags.MacFolder].push_back(*i);
|
||||
}
|
||||
|
|
|
@ -1650,9 +1650,10 @@ void cmMakefileTargetGenerator
|
|||
this->AppendTargetDepends(depends);
|
||||
|
||||
// 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.
|
||||
|
@ -2019,7 +2020,8 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
|
|||
//----------------------------------------------------------------------------
|
||||
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
||||
{
|
||||
if(this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||
if(def.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2035,8 +2037,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
|||
// Append the flag and value. Use ConvertToLinkReference to help
|
||||
// vs6's "cl -link" pass it to the linker.
|
||||
std::string flag = defFileFlag;
|
||||
flag += (this->LocalGenerator->ConvertToLinkReference(
|
||||
this->GeneratorTarget->ModuleDefinitionFile.c_str()));
|
||||
flag += (this->LocalGenerator->ConvertToLinkReference(def.c_str()));
|
||||
this->LocalGenerator->AppendFlags(flags, flag.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -498,10 +498,10 @@ cmNinjaTargetGenerator
|
|||
{
|
||||
this->WriteObjectBuildStatement(*si);
|
||||
}
|
||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||
if(!def.empty())
|
||||
{
|
||||
this->ModuleDefinitionFile = this->ConvertToNinjaPath(
|
||||
this->GeneratorTarget->ModuleDefinitionFile.c_str());
|
||||
this->ModuleDefinitionFile = this->ConvertToNinjaPath(def.c_str());
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
cmOSXBundleGenerator::
|
||||
cmOSXBundleGenerator(cmGeneratorTarget* target,
|
||||
const char* configName)
|
||||
: Target(target->Target)
|
||||
: GT(target)
|
||||
, Makefile(target->Target->GetMakefile())
|
||||
, LocalGenerator(Makefile->GetLocalGenerator())
|
||||
, ConfigName(configName)
|
||||
|
@ -34,7 +34,7 @@ cmOSXBundleGenerator(cmGeneratorTarget* target,
|
|||
//----------------------------------------------------------------------------
|
||||
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.
|
||||
std::string out = outpath;
|
||||
out += "/";
|
||||
out += this->Target->GetAppBundleDirectory(this->ConfigName, false);
|
||||
out += this->GT->Target->GetAppBundleDirectory(this->ConfigName, false);
|
||||
cmSystemTools::MakeDirectory(out.c_str());
|
||||
this->Makefile->AddCMakeOutputFile(out);
|
||||
|
||||
|
@ -57,9 +57,9 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
|
|||
// to be set.
|
||||
std::string plist = outpath;
|
||||
plist += "/";
|
||||
plist += this->Target->GetAppBundleDirectory(this->ConfigName, true);
|
||||
plist += this->GT->Target->GetAppBundleDirectory(this->ConfigName, true);
|
||||
plist += "/Info.plist";
|
||||
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
|
||||
this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
|
||||
targetName.c_str(),
|
||||
plist.c_str());
|
||||
this->Makefile->AddCMakeOutputFile(plist);
|
||||
|
@ -77,20 +77,20 @@ void cmOSXBundleGenerator::CreateFramework(
|
|||
|
||||
// Compute the location of the top-level foo.framework directory.
|
||||
std::string contentdir = outpath + "/" +
|
||||
this->Target->GetFrameworkDirectory(this->ConfigName, true);
|
||||
this->GT->Target->GetFrameworkDirectory(this->ConfigName, true);
|
||||
contentdir += "/";
|
||||
|
||||
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.
|
||||
this->MacContentFolders->insert("Resources");
|
||||
std::string plist = newoutpath;
|
||||
plist += "/Resources/Info.plist";
|
||||
std::string name = cmSystemTools::GetFilenameName(targetName);
|
||||
this->LocalGenerator->GenerateFrameworkInfoPList(this->Target,
|
||||
this->LocalGenerator->GenerateFrameworkInfoPList(this->GT->Target,
|
||||
name.c_str(),
|
||||
plist.c_str());
|
||||
|
||||
|
@ -172,16 +172,16 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
|
|||
// Compute bundle directory names.
|
||||
std::string out = root;
|
||||
out += "/";
|
||||
out += this->Target->GetCFBundleDirectory(this->ConfigName, false);
|
||||
out += this->GT->Target->GetCFBundleDirectory(this->ConfigName, false);
|
||||
cmSystemTools::MakeDirectory(out.c_str());
|
||||
this->Makefile->AddCMakeOutputFile(out);
|
||||
|
||||
// Configure the Info.plist file. Note that it needs the executable name
|
||||
// to be set.
|
||||
std::string plist =
|
||||
this->Target->GetCFBundleDirectory(this->ConfigName, true);
|
||||
this->GT->Target->GetCFBundleDirectory(this->ConfigName, true);
|
||||
plist += "/Info.plist";
|
||||
this->LocalGenerator->GenerateAppleInfoPList(this->Target,
|
||||
this->LocalGenerator->GenerateAppleInfoPList(this->GT->Target,
|
||||
targetName.c_str(),
|
||||
plist.c_str());
|
||||
this->Makefile->AddCMakeOutputFile(plist);
|
||||
|
@ -199,9 +199,9 @@ GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
|
|||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = sources.begin(); si != sources.end(); ++si)
|
||||
{
|
||||
cmTarget::SourceFileFlags tsFlags =
|
||||
this->Target->GetTargetSourceFileFlags(*si);
|
||||
if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
|
||||
cmGeneratorTarget::SourceFileFlags tsFlags =
|
||||
this->GT->GetTargetSourceFileFlags(*si);
|
||||
if(tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal)
|
||||
{
|
||||
(*generator)(**si, tsFlags.MacFolder);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ cmOSXBundleGenerator::InitMacOSXContentDirectory(const char* pkgloc)
|
|||
// Construct the full path to the content subdirectory.
|
||||
|
||||
std::string macdir =
|
||||
this->Target->GetMacContentDirectory(this->ConfigName,
|
||||
this->GT->Target->GetMacContentDirectory(this->ConfigName,
|
||||
/*implib*/ false);
|
||||
macdir += "/";
|
||||
macdir += pkgloc;
|
||||
|
|
|
@ -59,7 +59,7 @@ private:
|
|||
bool MustSkip();
|
||||
|
||||
private:
|
||||
cmTarget* Target;
|
||||
cmGeneratorTarget* GT;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalGenerator* LocalGenerator;
|
||||
const char* ConfigName;
|
||||
|
|
|
@ -83,17 +83,12 @@ public:
|
|||
cmTargetInternals()
|
||||
{
|
||||
this->PolicyWarnedCMP0022 = false;
|
||||
this->SourceFileFlagsConstructed = false;
|
||||
}
|
||||
cmTargetInternals(cmTargetInternals const&)
|
||||
{
|
||||
this->PolicyWarnedCMP0022 = false;
|
||||
this->SourceFileFlagsConstructed = false;
|
||||
}
|
||||
~cmTargetInternals();
|
||||
typedef cmTarget::SourceFileFlags SourceFileFlags;
|
||||
mutable std::map<cmSourceFile const*, SourceFileFlags> SourceFlagsMap;
|
||||
mutable bool SourceFileFlagsConstructed;
|
||||
|
||||
// The backtrace when the target was created.
|
||||
cmListFileBacktrace Backtrace;
|
||||
|
@ -101,9 +96,17 @@ public:
|
|||
// Cache link interface computation from each configuration.
|
||||
struct OptionalLinkInterface: public cmTarget::LinkInterface
|
||||
{
|
||||
OptionalLinkInterface(): Exists(false) {}
|
||||
OptionalLinkInterface():
|
||||
Exists(false), Complete(false), ExplicitLibraries(0) {}
|
||||
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>
|
||||
LinkInterfaceMapType;
|
||||
LinkInterfaceMapType LinkInterfaceMap;
|
||||
|
@ -527,10 +530,11 @@ 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
|
||||
si = this->SourceFiles.begin();
|
||||
si = this->SourceFiles.begin();
|
||||
si != this->SourceFiles.end(); ++si)
|
||||
{
|
||||
std::string e;
|
||||
|
@ -542,16 +546,9 @@ bool cmTarget::FindSourceFiles()
|
|||
cm->IssueMessage(cmake::FATAL_ERROR, e,
|
||||
this->GetBacktrace());
|
||||
}
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files) const
|
||||
{
|
||||
assert(this->GetType() != INTERFACE_LIBRARY);
|
||||
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,
|
||||
const char *selfname,
|
||||
|
@ -4530,12 +4424,13 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
|||
assert((impliedByUse ^ explicitlySet)
|
||||
|| (!impliedByUse && !explicitlySet));
|
||||
|
||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||
if(!info)
|
||||
std::vector<cmTarget*> deps;
|
||||
tgt->GetTransitiveTargetClosure(config, tgt, deps);
|
||||
|
||||
if(deps.empty())
|
||||
{
|
||||
return propContent;
|
||||
}
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
bool propInitialized = explicitlySet;
|
||||
|
||||
std::string report = " * Target \"";
|
||||
|
@ -4555,7 +4450,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
|||
report += "\" property not set.\n";
|
||||
}
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
for(std::vector<cmTarget*>::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
|
@ -4565,23 +4460,20 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
|||
// target itself has a POSITION_INDEPENDENT_CODE which disagrees
|
||||
// with a dependency.
|
||||
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cmTarget const* theTarget = *li;
|
||||
|
||||
const bool ifaceIsSet = li->Target->GetProperties()
|
||||
const bool ifaceIsSet = theTarget->GetProperties()
|
||||
.find("INTERFACE_" + p)
|
||||
!= li->Target->GetProperties().end();
|
||||
!= theTarget->GetProperties().end();
|
||||
PropertyType ifacePropContent =
|
||||
getTypedProperty<PropertyType>(li->Target,
|
||||
getTypedProperty<PropertyType>(theTarget,
|
||||
("INTERFACE_" + p).c_str(), 0);
|
||||
|
||||
std::string reportEntry;
|
||||
if (ifaceIsSet)
|
||||
{
|
||||
reportEntry += " * Target \"";
|
||||
reportEntry += li->Target->GetName();
|
||||
reportEntry += theTarget->GetName();
|
||||
reportEntry += "\" property value \"";
|
||||
reportEntry += valueAsString<PropertyType>(ifacePropContent);
|
||||
reportEntry += "\" ";
|
||||
|
@ -4602,7 +4494,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
|||
e << "Property " << p << " on target \""
|
||||
<< tgt->GetName() << "\" does\nnot match the "
|
||||
"INTERFACE_" << p << " property requirement\nof "
|
||||
"dependency \"" << li->Target->GetName() << "\".\n";
|
||||
"dependency \"" << theTarget->GetName() << "\".\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
break;
|
||||
}
|
||||
|
@ -4636,7 +4528,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
|||
<< tgt->GetName() << "\" is\nimplied to be " << defaultValue
|
||||
<< " because it was used to determine the link libraries\n"
|
||||
"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());
|
||||
break;
|
||||
}
|
||||
|
@ -4667,7 +4559,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt,
|
|||
{
|
||||
cmOStringStream e;
|
||||
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 \""
|
||||
<< tgt->GetName() << "\".\n";
|
||||
cmSystemTools::Error(e.str().c_str());
|
||||
|
@ -4748,23 +4640,19 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
|
|||
const char *interfaceProperty,
|
||||
const char *config)
|
||||
{
|
||||
cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
|
||||
if(!info)
|
||||
std::vector<cmTarget*> deps;
|
||||
tgt->GetTransitiveTargetClosure(config, tgt, deps);
|
||||
|
||||
if(deps.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||
|
||||
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||
for(std::vector<cmTarget*>::const_iterator li =
|
||||
deps.begin();
|
||||
li != deps.end(); ++li)
|
||||
{
|
||||
if (!li->Target)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char *prop = li->Target->GetProperty(interfaceProperty);
|
||||
const char *prop = (*li)->GetProperty(interfaceProperty);
|
||||
if (!prop)
|
||||
{
|
||||
continue;
|
||||
|
@ -5316,24 +5204,124 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config,
|
|||
{
|
||||
// Compute the link interface for this configuration.
|
||||
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.
|
||||
cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface);
|
||||
i = this->Internal->LinkInterfaceMap.insert(entry).first;
|
||||
}
|
||||
|
||||
return i->second.Exists? &i->second : 0;
|
||||
return i->second.Exists ? &i->second : 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::GetTransitivePropertyLinkLibraries(
|
||||
const char* config,
|
||||
cmTarget const* headTarget,
|
||||
std::vector<std::string> &libs) const
|
||||
void processILibs(const char* config,
|
||||
cmTarget const* headTarget,
|
||||
std::string const& name,
|
||||
std::vector<cmTarget*>& tgts, std::set<cmTarget*>& emitted)
|
||||
{
|
||||
cmTarget::LinkInterface const* iface = this->GetLinkInterface(config,
|
||||
headTarget);
|
||||
if (cmTarget* tgt = headTarget->GetMakefile()
|
||||
->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)
|
||||
{
|
||||
return;
|
||||
|
@ -5342,7 +5330,15 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
|
|||
|| this->GetPolicyStatusCMP0022() == cmPolicies::WARN
|
||||
|| 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;
|
||||
}
|
||||
|
||||
|
@ -5360,17 +5356,30 @@ void cmTarget::GetTransitivePropertyLinkLibraries(
|
|||
cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
|
||||
linkIfaceProp, 0, 0);
|
||||
dagChecker.SetTransitivePropertiesOnly();
|
||||
std::vector<std::string> libs;
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(interfaceLibs)->Evaluate(
|
||||
this->Makefile,
|
||||
config,
|
||||
false,
|
||||
headTarget,
|
||||
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,
|
||||
cmTarget const* headTarget) const
|
||||
const char* cmTarget::ComputeLinkInterfaceLibraries(const char* config,
|
||||
LinkInterface& iface,
|
||||
cmTarget const* headTarget,
|
||||
bool &exists) const
|
||||
{
|
||||
// Construct the property name suffix for this configuration.
|
||||
std::string suffix = "_";
|
||||
|
@ -5446,8 +5455,10 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
(this->GetType() == cmTarget::EXECUTABLE ||
|
||||
(this->GetType() == cmTarget::MODULE_LIBRARY)))
|
||||
{
|
||||
return false;
|
||||
exists = false;
|
||||
return 0;
|
||||
}
|
||||
exists = true;
|
||||
|
||||
if(explicitLibraries)
|
||||
{
|
||||
|
@ -5462,52 +5473,6 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
false,
|
||||
headTarget,
|
||||
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
|
||||
|| this->PolicyStatusCMP0022 == cmPolicies::OLD)
|
||||
|
@ -5517,17 +5482,9 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
// to the link implementation.
|
||||
{
|
||||
// The link implementation is the default link interface.
|
||||
LinkImplementation const* impl = this->GetLinkImplementation(config,
|
||||
headTarget);
|
||||
iface.ImplementationIsInterface = true;
|
||||
LinkImplementation const* impl =
|
||||
this->GetLinkImplementationLibraries(config, headTarget);
|
||||
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 &&
|
||||
!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
|
||||
// dependencies?
|
||||
std::string propName = "LINK_INTERFACE_MULTIPLICITY";
|
||||
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);
|
||||
}
|
||||
else if(const char* reps =
|
||||
this->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
|
||||
thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY"))
|
||||
{
|
||||
sscanf(reps, "%u", &iface.Multiplicity);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
iface.Complete = true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -5626,6 +5665,41 @@ cmTarget::GetLinkImplementation(const char* config, cmTarget const* head) const
|
|||
// Lookup any existing link implementation for this configuration.
|
||||
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
|
||||
i = this->Internal->LinkImplMap.find(key);
|
||||
if(i == this->Internal->LinkImplMap.end())
|
||||
|
@ -5715,7 +5789,12 @@ void cmTarget::ComputeLinkImplementation(const char* config,
|
|||
impl.WrongConfigLibraries.push_back(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmTarget::ComputeLinkImplementationLanguages(LinkImplementation& impl) const
|
||||
{
|
||||
// This target needs runtime libraries for its source languages.
|
||||
std::set<cmStdString> languages;
|
||||
// Get languages used in our source files.
|
||||
|
|
|
@ -139,34 +139,6 @@ public:
|
|||
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.
|
||||
*/
|
||||
|
@ -292,9 +264,14 @@ public:
|
|||
if the target cannot be linked. */
|
||||
LinkInterface const* GetLinkInterface(const char* config,
|
||||
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,
|
||||
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
|
||||
dependencies needed by the object files of the target. */
|
||||
|
@ -313,6 +290,9 @@ public:
|
|||
LinkImplementation const* GetLinkImplementation(const char* config,
|
||||
cmTarget const* head) const;
|
||||
|
||||
LinkImplementation const* GetLinkImplementationLibraries(const char* config,
|
||||
cmTarget const* head) const;
|
||||
|
||||
/** Link information from the transitive closure of the link
|
||||
implementation and the interfaces of its dependencies. */
|
||||
struct LinkClosure
|
||||
|
@ -358,11 +338,6 @@ public:
|
|||
void
|
||||
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
|
||||
const char* GetLinkerLanguage(const char* config = 0,
|
||||
cmTarget const* head = 0) const;
|
||||
|
@ -723,12 +698,15 @@ private:
|
|||
void CheckPropertyCompatibility(cmComputeLinkInformation *info,
|
||||
const char* config) const;
|
||||
|
||||
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
|
||||
cmTarget const* head) const;
|
||||
const char* ComputeLinkInterfaceLibraries(const char* config,
|
||||
LinkInterface& iface,
|
||||
cmTarget const* head,
|
||||
bool &exists) const;
|
||||
|
||||
void ComputeLinkImplementation(const char* config,
|
||||
LinkImplementation& impl,
|
||||
cmTarget const* head) const;
|
||||
void ComputeLinkImplementationLanguages(LinkImplementation& impl) const;
|
||||
void ComputeLinkClosure(const char* config, LinkClosure& lc,
|
||||
cmTarget const* head) const;
|
||||
|
||||
|
@ -756,7 +734,6 @@ private:
|
|||
friend class cmTargetTraceDependencies;
|
||||
cmTargetInternalPointer Internal;
|
||||
|
||||
void ConstructSourceFileFlags() const;
|
||||
void ComputeVersionedName(std::string& vName,
|
||||
std::string const& prefix,
|
||||
std::string const& base,
|
||||
|
|
|
@ -1666,10 +1666,10 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
|
|||
linkOptions.AddFlag("ImportLibrary", imLib.c_str());
|
||||
linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
|
||||
linkOptions.Parse(flags.c_str());
|
||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
std::string def = this->GeneratorTarget->GetModuleDefinitionFile();
|
||||
if(!def.empty())
|
||||
{
|
||||
linkOptions.AddFlag("ModuleDefinitionFile",
|
||||
this->GeneratorTarget->ModuleDefinitionFile.c_str());
|
||||
linkOptions.AddFlag("ModuleDefinitionFile", def.c_str());
|
||||
}
|
||||
|
||||
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:
|
||||
Boolean compatibility of property "BOOL_PROP1" for target
|
||||
"CompatibleInterface" \(result: "TRUE"\):
|
||||
|
@ -39,13 +46,6 @@ CMake Debug Log:
|
|||
\* Target "iface1" property value "FALSE" \(Interface set\)
|
||||
\* 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:
|
||||
String compatibility of property "STRING_PROP1" for target
|
||||
"CompatibleInterface" \(result: "prop1"\):
|
||||
|
|
Loading…
Reference in New Issue