summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r--Source/cmGeneratorTarget.cxx2173
1 files changed, 1866 insertions, 307 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 194cd88..b05fb41 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -62,7 +62,7 @@ void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib,
e << "but may contain only sources that compile, header files, and "
"other files that would not affect linking of a normal library.";
cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
- target->Target->GetBacktrace());
+ target->GetBacktrace());
}
}
@@ -155,7 +155,7 @@ struct TagVisitor
: Data(data), Target(target),
GlobalGenerator(target->GetLocalGenerator()->GetGlobalGenerator()),
Header(CM_HEADER_REGEX),
- IsObjLib(target->GetType() == cmTarget::OBJECT_LIBRARY)
+ IsObjLib(target->GetType() == cmState::OBJECT_LIBRARY)
{
}
@@ -172,7 +172,7 @@ struct TagVisitor
{
DoAccept<IsSameTag<Tag, CustomCommandsTag>::Result>::Do(this->Data, sf);
}
- else if(this->Target->GetType() == cmTarget::UTILITY)
+ else if(this->Target->GetType() == cmState::UTILITY)
{
DoAccept<IsSameTag<Tag, ExtraSourcesTag>::Result>::Do(this->Data, sf);
}
@@ -269,7 +269,10 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
DebugIncludesDone(false),
DebugCompileOptionsDone(false),
DebugCompileFeaturesDone(false),
- DebugCompileDefinitionsDone(false)
+ DebugCompileDefinitionsDone(false),
+ DebugSourcesDone(false),
+ LinkImplementationLanguageIsContextDependent(true),
+ UtilityItemsDone(false)
{
this->Makefile = this->Target->GetMakefile();
this->LocalGenerator = lg;
@@ -296,6 +299,17 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
t->GetCompileDefinitionsEntries(),
t->GetCompileDefinitionsBacktraces(),
this->CompileDefinitionsEntries);
+
+ CreatePropertyGeneratorExpressions(
+ t->GetSourceEntries(),
+ t->GetSourceBacktraces(),
+ this->SourceEntries, true);
+
+ this->DLLPlatform = (this->Makefile->IsOn("WIN32") ||
+ this->Makefile->IsOn("CYGWIN") ||
+ this->Makefile->IsOn("MINGW"));
+
+ this->PolicyMap = t->PolicyMap;
}
cmGeneratorTarget::~cmGeneratorTarget()
@@ -304,6 +318,7 @@ cmGeneratorTarget::~cmGeneratorTarget()
cmDeleteAll(this->CompileOptionsEntries);
cmDeleteAll(this->CompileFeaturesEntries);
cmDeleteAll(this->CompileDefinitionsEntries);
+ cmDeleteAll(this->SourceEntries);
cmDeleteAll(this->LinkInformation);
this->LinkInformation.clear();
}
@@ -314,7 +329,7 @@ cmLocalGenerator* cmGeneratorTarget::GetLocalGenerator() const
}
//----------------------------------------------------------------------------
-int cmGeneratorTarget::GetType() const
+cmState::TargetType cmGeneratorTarget::GetType() const
{
return this->Target->GetType();
}
@@ -326,12 +341,88 @@ std::string cmGeneratorTarget::GetName() const
}
//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetExportName() const
+{
+ const char *exportName = this->GetProperty("EXPORT_NAME");
+
+ if (exportName && *exportName)
+ {
+ if (!cmGeneratorExpression::IsValidTargetName(exportName))
+ {
+ std::ostringstream e;
+ e << "EXPORT_NAME property \"" << exportName << "\" for \""
+ << this->GetName() << "\": is not valid.";
+ cmSystemTools::Error(e.str().c_str());
+ return "";
+ }
+ return exportName;
+ }
+ return this->GetName();
+}
+
+//----------------------------------------------------------------------------
const char *cmGeneratorTarget::GetProperty(const std::string& prop) const
{
return this->Target->GetProperty(prop);
}
//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetOutputTargetType(bool implib) const
+{
+ switch(this->GetType())
+ {
+ case cmState::SHARED_LIBRARY:
+ if(this->IsDLLPlatform())
+ {
+ if(implib)
+ {
+ // A DLL import library is treated as an archive target.
+ return "ARCHIVE";
+ }
+ else
+ {
+ // A DLL shared library is treated as a runtime target.
+ return "RUNTIME";
+ }
+ }
+ else
+ {
+ // For non-DLL platforms shared libraries are treated as
+ // library targets.
+ return "LIBRARY";
+ }
+ case cmState::STATIC_LIBRARY:
+ // Static libraries are always treated as archive targets.
+ return "ARCHIVE";
+ case cmState::MODULE_LIBRARY:
+ if(implib)
+ {
+ // Module libraries are always treated as library targets.
+ return "ARCHIVE";
+ }
+ else
+ {
+ // Module import libraries are treated as archive targets.
+ return "LIBRARY";
+ }
+ case cmState::EXECUTABLE:
+ if(implib)
+ {
+ // Executable import libraries are treated as archive targets.
+ return "ARCHIVE";
+ }
+ else
+ {
+ // Executables are always treated as runtime targets.
+ return "RUNTIME";
+ }
+ default:
+ break;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
std::string cmGeneratorTarget::GetOutputName(const std::string& config,
bool implib) const
{
@@ -347,7 +438,7 @@ std::string cmGeneratorTarget::GetOutputName(const std::string& config,
// Compute output name.
std::vector<std::string> props;
- std::string type = this->Target->GetOutputTargetType(implib);
+ std::string type = this->GetOutputTargetType(implib);
std::string configUpper = cmSystemTools::UpperCase(config);
if(!type.empty() && !configUpper.empty())
{
@@ -373,7 +464,7 @@ std::string cmGeneratorTarget::GetOutputName(const std::string& config,
for(std::vector<std::string>::const_iterator it = props.begin();
it != props.end(); ++it)
{
- if (const char* outNameProp = this->Target->GetProperty(*it))
+ if (const char* outNameProp = this->GetProperty(*it))
{
outName = outNameProp;
break;
@@ -388,35 +479,67 @@ std::string cmGeneratorTarget::GetOutputName(const std::string& config,
// Now evaluate genex and update the previously-prepared map entry.
cmGeneratorExpression ge;
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(outName);
- i->second = cge->Evaluate(this->Makefile, config);
+ i->second = cge->Evaluate(this->LocalGenerator, config);
}
else if(i->second.empty())
{
// An empty map entry indicates we have been called recursively
// from the above block.
- this->Makefile->GetCMakeInstance()->IssueMessage(
+ this->LocalGenerator->GetCMakeInstance()
+ ->IssueMessage(
cmake::FATAL_ERROR,
"Target '" + this->GetName() + "' OUTPUT_NAME depends on itself.",
- this->Target->GetBacktrace());
+ this->GetBacktrace());
}
return i->second;
}
+void cmGeneratorTarget::AddSource(const std::string& src)
+{
+ this->Target->AddSource(src);
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(src);
+ cge->SetEvaluateForBuildsystem(true);
+ this->SourceEntries.push_back(
+ new TargetPropertyEntry(cge));
+ this->SourceFilesMap.clear();
+ this->LinkImplementationLanguageIsContextDependent = true;
+}
+
+void cmGeneratorTarget::AddTracedSources(std::vector<std::string> const& srcs)
+{
+ this->Target->AddTracedSources(srcs);
+ if (!srcs.empty())
+ {
+ std::string srcFiles = cmJoin(srcs, ";");
+ this->SourceFilesMap.clear();
+ this->LinkImplementationLanguageIsContextDependent = true;
+ cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(srcFiles);
+ cge->SetEvaluateForBuildsystem(true);
+ this->SourceEntries.push_back(
+ new cmGeneratorTarget::TargetPropertyEntry(cge));
+ }
+}
+
//----------------------------------------------------------------------------
std::vector<cmSourceFile*> const*
cmGeneratorTarget::GetSourceDepends(cmSourceFile const* sf) const
{
- SourceEntriesType::const_iterator i = this->SourceEntries.find(sf);
- if(i != this->SourceEntries.end())
+ SourceEntriesType::const_iterator i = this->SourceDepends.find(sf);
+ if(i != this->SourceDepends.end())
{
return &i->second.Depends;
}
return 0;
}
-static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
+static void handleSystemIncludesDep(cmLocalGenerator *lg,
+ cmGeneratorTarget const* depTgt,
const std::string& config,
- cmTarget *headTarget,
+ cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker *dagChecker,
std::vector<std::string>& result,
bool excludeImported)
@@ -426,7 +549,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
{
cmGeneratorExpression ge;
cmSystemTools::ExpandListArgument(ge.Parse(dirs)
- ->Evaluate(mf,
+ ->Evaluate(lg,
config, false, headTarget,
depTgt, dagChecker), result);
}
@@ -440,7 +563,7 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
{
cmGeneratorExpression ge;
cmSystemTools::ExpandListArgument(ge.Parse(dirs)
- ->Evaluate(mf,
+ ->Evaluate(lg,
config, false, headTarget,
depTgt, dagChecker), result);
}
@@ -449,8 +572,8 @@ static void handleSystemIncludesDep(cmMakefile *mf, cmTarget const* depTgt,
#define IMPLEMENT_VISIT_IMPL(DATA, DATATYPE) \
{ \
std::vector<cmSourceFile*> sourceFiles; \
- this->Target->GetSourceFiles(sourceFiles, config); \
- TagVisitor<DATA ## Tag DATATYPE> visitor(this, data); \
+ this->GetSourceFiles(sourceFiles, config); \
+ TagVisitor< DATA##Tag DATATYPE > visitor(this, data); \
for(std::vector<cmSourceFile*>::const_iterator si = sourceFiles.begin(); \
si != sourceFiles.end(); ++si) \
{ \
@@ -517,12 +640,12 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
std::string featureConfig = feature;
featureConfig += "_";
featureConfig += cmSystemTools::UpperCase(config);
- if(const char* value = this->Target->GetProperty(featureConfig))
+ if(const char* value = this->GetProperty(featureConfig))
{
return value;
}
}
- if(const char* value = this->Target->GetProperty(feature))
+ if(const char* value = this->GetProperty(feature))
{
return value;
}
@@ -665,7 +788,24 @@ cmGeneratorTarget::GetExpectedXamlSources(std::set<std::string>& srcs,
{
XamlData data;
IMPLEMENT_VISIT_IMPL(Xaml, COMMA cmGeneratorTarget::XamlData)
- srcs = data.ExpectedXamlSources;
+ srcs = data.ExpectedXamlSources;
+}
+
+std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
+{
+ if(!this->UtilityItemsDone)
+ {
+ this->UtilityItemsDone = true;
+ std::set<std::string> const& utilities = this->GetUtilities();
+ for(std::set<std::string>::const_iterator i = utilities.begin();
+ i != utilities.end(); ++i)
+ {
+ cmGeneratorTarget* gt =
+ this->LocalGenerator->FindGeneratorTargetToUse(*i);
+ this->UtilityItems.insert(cmLinkItem(*i, gt));
+ }
+ }
+ return this->UtilityItems;
}
//----------------------------------------------------------------------------
@@ -682,7 +822,7 @@ void cmGeneratorTarget
const char* cmGeneratorTarget::GetLocation(const std::string& config) const
{
static std::string location;
- if (this->Target->IsImported())
+ if (this->IsImported())
{
location = this->Target->ImportedGetFullPath(config, false);
}
@@ -693,11 +833,34 @@ const char* cmGeneratorTarget::GetLocation(const std::string& config) const
return location.c_str();
}
+std::vector<cmCustomCommand> const&
+cmGeneratorTarget::GetPreBuildCommands() const
+{
+ return this->Target->GetPreBuildCommands();
+}
+
+std::vector<cmCustomCommand> const&
+cmGeneratorTarget::GetPreLinkCommands() const
+{
+ return this->Target->GetPreLinkCommands();
+}
+
+std::vector<cmCustomCommand> const&
+cmGeneratorTarget::GetPostBuildCommands() const
+{
+ return this->Target->GetPostBuildCommands();
+}
+
bool cmGeneratorTarget::IsImported() const
{
return this->Target->IsImported();
}
+bool cmGeneratorTarget::IsImportedGloballyVisible() const
+{
+ return this->Target->IsImportedGloballyVisible();
+}
+
//----------------------------------------------------------------------------
const char* cmGeneratorTarget::GetLocationForBuild() const
{
@@ -709,7 +872,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const
}
// Now handle the deprecated build-time configuration location.
- location = this->Target->GetDirectory();
+ location = this->GetDirectory();
const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR");
if(cfgid && strcmp(cfgid, ".") != 0)
{
@@ -717,7 +880,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const
location += cfgid;
}
- if(this->Target->IsAppBundleOnApple())
+ if(this->IsAppBundleOnApple())
{
std::string macdir = this->BuildMacContentDirectory("", "",
false);
@@ -737,7 +900,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const
bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
const std::string& config) const
{
- assert(this->GetType() != cmTarget::INTERFACE_LIBRARY);
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
std::string config_upper;
if(!config.empty())
{
@@ -755,7 +918,7 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
"SYSTEM_INCLUDE_DIRECTORIES", 0, 0);
bool excludeImported
- = this->Target->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
+ = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
std::vector<std::string> result;
for (std::set<std::string>::const_iterator
@@ -764,17 +927,17 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const std::string& dir,
{
cmGeneratorExpression ge;
cmSystemTools::ExpandListArgument(ge.Parse(*it)
- ->Evaluate(this->Makefile,
- config, false, this->Target,
+ ->Evaluate(this->LocalGenerator,
+ config, false, this,
&dagChecker), result);
}
- std::vector<cmTarget const*> const& deps =
+ std::vector<cmGeneratorTarget const*> const& deps =
this->GetLinkImplementationClosure(config);
- for(std::vector<cmTarget const*>::const_iterator
+ for(std::vector<cmGeneratorTarget const*>::const_iterator
li = deps.begin(), le = deps.end(); li != le; ++li)
{
- handleSystemIncludesDep(this->Makefile, *li, config, this->Target,
+ handleSystemIncludesDep(this->LocalGenerator, *li, config, this,
&dagChecker, result, excludeImported);
}
@@ -802,10 +965,258 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
}
//----------------------------------------------------------------------------
+static void AddInterfaceEntries(
+ cmGeneratorTarget const* thisTarget, std::string const& config,
+ std::string const& prop,
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+{
+ if(cmLinkImplementationLibraries const* impl =
+ thisTarget->GetLinkImplementationLibraries(config))
+ {
+ for (std::vector<cmLinkImplItem>::const_iterator
+ it = impl->Libraries.begin(), end = impl->Libraries.end();
+ it != end; ++it)
+ {
+ if(it->Target)
+ {
+ std::string genex =
+ "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
+ cmGeneratorExpression ge(it->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
+ cge->SetEvaluateForBuildsystem(true);
+ entries.push_back(
+ new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+static bool processSources(cmGeneratorTarget const* tgt,
+ const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries,
+ std::vector<std::string> &srcs,
+ UNORDERED_SET<std::string> &uniqueSrcs,
+ cmGeneratorExpressionDAGChecker *dagChecker,
+ std::string const& config, bool debugSources)
+{
+ cmMakefile *mf = tgt->Target->GetMakefile();
+
+ bool contextDependent = false;
+
+ for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
+ it = entries.begin(), end = entries.end(); it != end; ++it)
+ {
+ cmLinkImplItem const& item = (*it)->LinkImplItem;
+ std::string const& targetName = item;
+ std::vector<std::string> entrySources;
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(
+ tgt->GetLocalGenerator(),
+ config,
+ false,
+ tgt,
+ tgt,
+ dagChecker),
+ entrySources);
+
+ if ((*it)->ge->GetHadContextSensitiveCondition())
+ {
+ contextDependent = true;
+ }
+
+ for(std::vector<std::string>::iterator i = entrySources.begin();
+ i != entrySources.end(); ++i)
+ {
+ std::string& src = *i;
+ cmSourceFile* sf = mf->GetOrCreateSource(src);
+ std::string e;
+ std::string fullPath = sf->GetFullPath(&e);
+ if(fullPath.empty())
+ {
+ if(!e.empty())
+ {
+ cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e,
+ tgt->GetBacktrace());
+ }
+ return contextDependent;
+ }
+
+ if (!targetName.empty() && !cmSystemTools::FileIsFullPath(src.c_str()))
+ {
+ std::ostringstream err;
+ if (!targetName.empty())
+ {
+ err << "Target \"" << targetName << "\" contains relative "
+ "path in its INTERFACE_SOURCES:\n"
+ " \"" << src << "\"";
+ }
+ else
+ {
+ err << "Found relative path while evaluating sources of "
+ "\"" << tgt->GetName() << "\":\n \"" << src << "\"\n";
+ }
+ tgt->GetLocalGenerator()->IssueMessage(cmake::FATAL_ERROR, err.str());
+ return contextDependent;
+ }
+ src = fullPath;
+ }
+ std::string usedSources;
+ for(std::vector<std::string>::iterator
+ li = entrySources.begin(); li != entrySources.end(); ++li)
+ {
+ std::string src = *li;
+
+ if(uniqueSrcs.insert(src).second)
+ {
+ srcs.push_back(src);
+ if (debugSources)
+ {
+ usedSources += " * " + src + "\n";
+ }
+ }
+ }
+ if (!usedSources.empty())
+ {
+ tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ std::string("Used sources for target ")
+ + tgt->GetName() + ":\n"
+ + usedSources, (*it)->ge->GetBacktrace());
+ }
+ }
+ return contextDependent;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetSourceFiles(std::vector<std::string> &files,
+ const std::string& config) const
+{
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
+
+ if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026())
+ {
+ // At configure-time, this method can be called as part of getting the
+ // LOCATION property or to export() a file to be include()d. However
+ // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+ // for TARGET_OBJECTS instead for backwards compatibility with OLD
+ // behavior of CMP0024 and CMP0026 only.
+
+ cmStringRange sourceEntries = this->Target->GetSourceEntries();
+ for(cmStringRange::const_iterator
+ i = sourceEntries.begin();
+ i != sourceEntries.end(); ++i)
+ {
+ std::string const& entry = *i;
+
+ std::vector<std::string> items;
+ cmSystemTools::ExpandListArgument(entry, items);
+ for (std::vector<std::string>::const_iterator
+ li = items.begin(); li != items.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
+ {
+ continue;
+ }
+ files.push_back(*li);
+ }
+ }
+ return;
+ }
+
+ std::vector<std::string> debugProperties;
+ const char *debugProp =
+ this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
+ if (debugProp)
+ {
+ cmSystemTools::ExpandListArgument(debugProp, debugProperties);
+ }
+
+ bool debugSources = !this->DebugSourcesDone
+ && std::find(debugProperties.begin(),
+ debugProperties.end(),
+ "SOURCES")
+ != debugProperties.end();
+
+ if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026())
+ {
+ this->DebugSourcesDone = true;
+ }
+
+ cmGeneratorExpressionDAGChecker dagChecker(this->GetName(),
+ "SOURCES", 0, 0);
+
+ UNORDERED_SET<std::string> uniqueSrcs;
+ bool contextDependentDirectSources = processSources(this,
+ this->SourceEntries,
+ files,
+ uniqueSrcs,
+ &dagChecker,
+ config,
+ debugSources);
+
+ std::vector<cmGeneratorTarget::TargetPropertyEntry*>
+ linkInterfaceSourcesEntries;
+
+ AddInterfaceEntries(
+ this, config, "INTERFACE_SOURCES",
+ linkInterfaceSourcesEntries);
+
+ std::vector<std::string>::size_type numFilesBefore = files.size();
+ bool contextDependentInterfaceSources = processSources(this,
+ linkInterfaceSourcesEntries,
+ files,
+ uniqueSrcs,
+ &dagChecker,
+ config,
+ debugSources);
+
+ if (!contextDependentDirectSources
+ && !(contextDependentInterfaceSources && numFilesBefore < files.size()))
+ {
+ this->LinkImplementationLanguageIsContextDependent = false;
+ }
+
+ cmDeleteAll(linkInterfaceSourcesEntries);
+}
+
+//----------------------------------------------------------------------------
void cmGeneratorTarget::GetSourceFiles(std::vector<cmSourceFile*> &files,
const std::string& config) const
{
- this->Target->GetSourceFiles(files, config);
+
+ // Lookup any existing link implementation for this configuration.
+ std::string key = cmSystemTools::UpperCase(config);
+
+ if(!this->LinkImplementationLanguageIsContextDependent)
+ {
+ files = this->SourceFilesMap.begin()->second;
+ return;
+ }
+
+ SourceFilesMapType::iterator
+ it = this->SourceFilesMap.find(key);
+ if(it != this->SourceFilesMap.end())
+ {
+ files = it->second;
+ }
+ else
+ {
+ std::vector<std::string> srcs;
+ this->GetSourceFiles(srcs, config);
+
+ std::set<cmSourceFile*> emitted;
+
+ for(std::vector<std::string>::const_iterator i = srcs.begin();
+ i != srcs.end(); ++i)
+ {
+ cmSourceFile* sf = this->Makefile->GetOrCreateSource(*i);
+ if (emitted.insert(sf).second)
+ {
+ files.push_back(sf);
+ }
+ }
+ this->SourceFilesMap[key] = files;
+ }
}
//----------------------------------------------------------------------------
@@ -821,13 +1232,13 @@ cmGeneratorTarget::GetCompilePDBName(const std::string& config) const
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configProp = "COMPILE_PDB_NAME_";
configProp += configUpper;
- const char* config_name = this->Target->GetProperty(configProp);
+ const char* config_name = this->GetProperty(configProp);
if(config_name && *config_name)
{
return prefix + config_name + ".pdb";
}
- const char* name = this->Target->GetProperty("COMPILE_PDB_NAME");
+ const char* name = this->GetProperty("COMPILE_PDB_NAME");
if(name && *name)
{
return prefix + name + ".pdb";
@@ -844,7 +1255,7 @@ cmGeneratorTarget::GetCompilePDBPath(const std::string& config) const
std::string name = this->GetCompilePDBName(config);
if(dir.empty() && !name.empty())
{
- dir = this->Target->GetPDBDirectory(config);
+ dir = this->GetPDBDirectory(config);
}
if(!dir.empty())
{
@@ -858,7 +1269,7 @@ bool cmGeneratorTarget::HasSOName(const std::string& config) const
{
// soname is supported only for shared libraries and modules,
// and then only when the platform supports an soname flag.
- return ((this->GetType() == cmTarget::SHARED_LIBRARY) &&
+ return ((this->GetType() == cmState::SHARED_LIBRARY) &&
!this->GetPropertyAsBool("NO_SONAME") &&
this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config)));
}
@@ -869,9 +1280,9 @@ cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
{
// Only executables and shared libraries can have an rpath and may
// need relinking.
- if(this->GetType() != cmTarget::EXECUTABLE &&
- this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY)
+ if(this->GetType() != cmState::EXECUTABLE &&
+ this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY)
{
return false;
}
@@ -926,16 +1337,16 @@ cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const
// will likely change between the build tree and install tree and
// this target must be relinked.
return this->HaveBuildTreeRPATH(config)
- || this->Target->HaveInstallTreeRPATH();
+ || this->HaveInstallTreeRPATH();
}
//----------------------------------------------------------------------------
bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
{
// Only certain target types have an rpath.
- if(!(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY ||
- this->GetType() == cmTarget::EXECUTABLE))
+ if(!(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::EXECUTABLE))
{
return false;
}
@@ -996,14 +1407,144 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
return false;
}
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsImportedSharedLibWithoutSOName(
+ const std::string& config) const
+{
+ if(this->IsImported() && this->GetType() == cmState::SHARED_LIBRARY)
+ {
+ if(cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config))
+ {
+ return info->NoSOName;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
+ const std::string& config) const
+{
+ bool install_name_is_rpath = false;
+ bool macosx_rpath = false;
+
+ if(!this->IsImported())
+ {
+ if(this->GetType() != cmState::SHARED_LIBRARY)
+ {
+ return false;
+ }
+ const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+ bool use_install_name =
+ this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH");
+ if(install_name && use_install_name &&
+ std::string(install_name) == "@rpath")
+ {
+ install_name_is_rpath = true;
+ }
+ else if(install_name && use_install_name)
+ {
+ return false;
+ }
+ if(!install_name_is_rpath)
+ {
+ macosx_rpath = this->MacOSXRpathInstallNameDirDefault();
+ }
+ }
+ else
+ {
+ // Lookup the imported soname.
+ if(cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config))
+ {
+ if(!info->NoSOName && !info->SOName.empty())
+ {
+ if(info->SOName.find("@rpath/") == 0)
+ {
+ install_name_is_rpath = true;
+ }
+ }
+ else
+ {
+ std::string install_name;
+ cmSystemTools::GuessLibraryInstallName(info->Location, install_name);
+ if(install_name.find("@rpath") != std::string::npos)
+ {
+ install_name_is_rpath = true;
+ }
+ }
+ }
+ }
+
+ if(!install_name_is_rpath && !macosx_rpath)
+ {
+ return false;
+ }
+
+ if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
+ {
+ std::ostringstream w;
+ w << "Attempting to use";
+ if(macosx_rpath)
+ {
+ w << " MACOSX_RPATH";
+ }
+ else
+ {
+ w << " @rpath";
+ }
+ w << " without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being set.";
+ w << " This could be because you are using a Mac OS X version";
+ w << " less than 10.5 or because CMake's platform configuration is";
+ w << " corrupt.";
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, w.str(),
+ this->GetBacktrace());
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
+{
+ // we can't do rpaths when unsupported
+ if(!this->Makefile->IsSet("CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG"))
+ {
+ return false;
+ }
+
+ const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+ if(macosx_rpath_str)
+ {
+ return this->GetPropertyAsBool("MACOSX_RPATH");
+ }
+
+ cmPolicies::PolicyStatus cmp0042 = this->GetPolicyStatusCMP0042();
+
+ if(cmp0042 == cmPolicies::WARN)
+ {
+ this->LocalGenerator->GetGlobalGenerator()->
+ AddCMP0042WarnTarget(this->GetName());
+ }
+
+ if(cmp0042 == cmPolicies::NEW)
+ {
+ return true;
+ }
+
+ return false;
+}
//----------------------------------------------------------------------------
std::string cmGeneratorTarget::GetSOName(const std::string& config) const
{
- if(this->Target->IsImported())
+ if(this->IsImported())
{
// Lookup the imported soname.
- if(cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config))
+ if(cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config))
{
if(info->NoSOName)
{
@@ -1060,9 +1601,9 @@ cmGeneratorTarget::GetAppBundleDirectory(const std::string& config,
//----------------------------------------------------------------------------
bool cmGeneratorTarget::IsBundleOnApple() const
{
- return this->Target->IsFrameworkOnApple()
- || this->Target->IsAppBundleOnApple()
- || this->Target->IsCFBundleOnApple();
+ return this->IsFrameworkOnApple()
+ || this->IsAppBundleOnApple()
+ || this->IsCFBundleOnApple();
}
//----------------------------------------------------------------------------
@@ -1072,10 +1613,10 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(const std::string& config,
std::string fpath;
fpath += this->GetOutputName(config, false);
fpath += ".";
- const char *ext = this->Target->GetProperty("BUNDLE_EXTENSION");
+ const char *ext = this->GetProperty("BUNDLE_EXTENSION");
if (!ext)
{
- if (this->Target->IsXCTestOnApple())
+ if (this->IsXCTestOnApple())
{
ext = "xctest";
}
@@ -1105,7 +1646,7 @@ cmGeneratorTarget::GetFrameworkDirectory(const std::string& config,
if(!rootDir && !this->Makefile->PlatformIsAppleIos())
{
fpath += "/Versions/";
- fpath += this->Target->GetFrameworkVersion();
+ fpath += this->GetFrameworkVersion();
}
return fpath;
}
@@ -1114,9 +1655,9 @@ cmGeneratorTarget::GetFrameworkDirectory(const std::string& config,
std::string
cmGeneratorTarget::GetFullName(const std::string& config, bool implib) const
{
- if(this->Target->IsImported())
+ if(this->IsImported())
{
- return this->Target->GetFullNameImported(config, implib);
+ return this->GetFullNameImported(config, implib);
}
else
{
@@ -1142,13 +1683,13 @@ cmGeneratorTarget::GetInstallNameDirForBuildTree(
!this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
{
std::string dir;
- if(this->Target->MacOSXRpathInstallNameDirDefault())
+ if(this->MacOSXRpathInstallNameDirDefault())
{
dir = "@rpath";
}
else
{
- dir = this->Target->GetDirectory(config);
+ dir = this->GetDirectory(config);
}
dir += "/";
return dir;
@@ -1178,7 +1719,7 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
}
if(!install_name_dir)
{
- if(this->Target->MacOSXRpathInstallNameDirDefault())
+ if(this->MacOSXRpathInstallNameDirDefault())
{
dir = "@rpath/";
}
@@ -1191,6 +1732,63 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
}
}
+cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const
+{
+ return this->Target->GetBacktrace();
+}
+
+const std::vector<std::string>&cmGeneratorTarget::GetLinkDirectories() const
+{
+ return this->Target->GetLinkDirectories();
+}
+
+const std::set<std::string>& cmGeneratorTarget::GetUtilities() const
+{
+ return this->Target->GetUtilities();
+}
+
+const cmListFileBacktrace*
+cmGeneratorTarget::GetUtilityBacktrace(const std::string& u) const
+{
+ return this->Target->GetUtilityBacktrace(u);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveWellDefinedOutputFiles() const
+{
+ return
+ this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::EXECUTABLE;
+}
+
+//----------------------------------------------------------------------------
+const char* cmGeneratorTarget::GetExportMacro() const
+{
+ // Define the symbol for targets that export symbols.
+ if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ if(const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL"))
+ {
+ this->ExportMacro = custom_export_name;
+ }
+ else
+ {
+ std::string in = this->GetName();
+ in += "_EXPORTS";
+ this->ExportMacro = cmSystemTools::MakeCidentifier(in);
+ }
+ return this->ExportMacro.c_str();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
//----------------------------------------------------------------------------
class cmTargetCollectLinkLanguages
{
@@ -1198,10 +1796,10 @@ public:
cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
const std::string& config,
UNORDERED_SET<std::string>& languages,
- cmTarget const* head):
+ cmGeneratorTarget const* head):
Config(config), Languages(languages), HeadTarget(head),
- Makefile(target->Target->GetMakefile()), Target(target)
- { this->Visited.insert(target->Target); }
+ Target(target)
+ { this->Visited.insert(target); }
void Visit(cmLinkItem const& item)
{
@@ -1212,7 +1810,8 @@ public:
bool noMessage = false;
cmake::MessageType messageType = cmake::FATAL_ERROR;
std::stringstream e;
- switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0028))
+ switch(this->Target->GetLocalGenerator()
+ ->GetPolicyStatus(cmPolicies::CMP0028))
{
case cmPolicies::WARN:
{
@@ -1236,8 +1835,8 @@ public:
<< "\" but the target was not found. Perhaps a find_package() "
"call is missing for an IMPORTED target, or an ALIAS target is "
"missing?";
- this->Makefile->GetCMakeInstance()->IssueMessage(
- messageType, e.str(), this->Target->Target->GetBacktrace());
+ this->Target->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), this->Target->GetBacktrace());
}
}
return;
@@ -1246,11 +1845,8 @@ public:
{
return;
}
- cmGeneratorTarget* gtgt =
- this->Target->GetLocalGenerator()->GetGlobalGenerator()
- ->GetGeneratorTarget(item.Target);
cmLinkInterface const* iface =
- gtgt->GetLinkInterface(this->Config, this->HeadTarget);
+ item.Target->GetLinkInterface(this->Config, this->HeadTarget);
if(!iface) { return; }
for(std::vector<std::string>::const_iterator
@@ -1268,10 +1864,9 @@ public:
private:
std::string Config;
UNORDERED_SET<std::string>& Languages;
- cmTarget const* HeadTarget;
- cmMakefile* Makefile;
+ cmGeneratorTarget const* HeadTarget;
const cmGeneratorTarget* Target;
- std::set<cmTarget const*> Visited;
+ std::set<cmGeneratorTarget const*> Visited;
};
//----------------------------------------------------------------------------
@@ -1296,14 +1891,12 @@ class cmTargetSelectLinker
{
int Preference;
cmGeneratorTarget const* Target;
- cmMakefile* Makefile;
cmGlobalGenerator* GG;
std::set<std::string> Preferred;
public:
cmTargetSelectLinker(cmGeneratorTarget const* target)
: Preference(0), Target(target)
{
- this->Makefile = this->Target->Makefile;
this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
}
void Consider(const char* lang)
@@ -1337,9 +1930,9 @@ public:
e << " " << *li << "\n";
}
e << "Set the LINKER_LANGUAGE property for this target.";
- cmake* cm = this->Makefile->GetCMakeInstance();
+ cmake* cm = this->Target->GetLocalGenerator()->GetCMakeInstance();
cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
- this->Target->Target->GetBacktrace());
+ this->Target->GetBacktrace());
}
return *this->Preferred.begin();
}
@@ -1361,7 +1954,7 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
}
// Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, this->Target);
+ cmTargetCollectLinkLanguages cll(this, config, languages, this);
for(std::vector<cmLinkImplItem>::const_iterator li = impl->Libraries.begin();
li != impl->Libraries.end(); ++li)
{
@@ -1428,15 +2021,15 @@ cmGeneratorTarget::BuildMacContentDirectory(const std::string& base,
bool contentOnly) const
{
std::string fpath = base;
- if(this->Target->IsAppBundleOnApple())
+ if(this->IsAppBundleOnApple())
{
fpath += this->GetAppBundleDirectory(config, contentOnly);
}
- if(this->Target->IsFrameworkOnApple())
+ if(this->IsFrameworkOnApple())
{
fpath += this->GetFrameworkDirectory(config, contentOnly);
}
- if(this->Target->IsCFBundleOnApple())
+ if(this->IsCFBundleOnApple())
{
fpath += this->GetCFBundleDirectory(config, contentOnly);
}
@@ -1449,10 +2042,10 @@ cmGeneratorTarget::GetMacContentDirectory(const std::string& config,
bool implib) const
{
// Start with the output directory for the target.
- std::string fpath = this->Target->GetDirectory(config, implib);
+ std::string fpath = this->GetDirectory(config, implib);
fpath += "/";
bool contentOnly = true;
- if(this->Target->IsFrameworkOnApple())
+ if(this->IsFrameworkOnApple())
{
// additional files with a framework go into the version specific
// directory
@@ -1473,12 +2066,12 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
return 0;
}
- if(this->GetType() > cmTarget::OBJECT_LIBRARY)
+ if(this->GetType() > cmState::OBJECT_LIBRARY)
{
std::string msg = "cmTarget::GetCompileInfo called for ";
msg += this->GetName();
msg += " which has type ";
- msg += cmTarget::GetTargetTypeName(this->Target->GetType());
+ msg += cmState::GetTargetTypeName(this->GetType());
this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
return 0;
}
@@ -1494,8 +2087,7 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
if(i == this->CompileInfoMap.end())
{
CompileInfo info;
- this->Target
- ->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
+ this->ComputePDBOutputDir("COMPILE_PDB", config, info.CompilePdbDir);
CompileInfoMapType::value_type entry(config_upper, info);
i = this->CompileInfoMap.insert(entry).first;
}
@@ -1503,12 +2095,23 @@ cmGeneratorTarget::CompileInfo const* cmGeneratorTarget::GetCompileInfo(
}
//----------------------------------------------------------------------------
-std::string
+cmSourceFile const*
cmGeneratorTarget::GetModuleDefinitionFile(const std::string& config) const
{
- std::string data;
- IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile, COMMA std::string)
- return data;
+ std::vector<cmSourceFile const*> data;
+ IMPLEMENT_VISIT_IMPL(ModuleDefinitionFile,
+ COMMA std::vector<cmSourceFile const*>)
+ if(!data.empty())
+ {
+ return data.front();
+ }
+
+ return 0;
+}
+
+bool cmGeneratorTarget::IsDLLPlatform() const
+{
+ return this->DLLPlatform;
}
//----------------------------------------------------------------------------
@@ -1518,27 +2121,26 @@ cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs,
{
std::vector<cmSourceFile const*> objectFiles;
this->GetExternalObjects(objectFiles, config);
- std::vector<cmTarget*> objectLibraries;
+ std::vector<cmGeneratorTarget*> objectLibraries;
for(std::vector<cmSourceFile const*>::const_iterator
it = objectFiles.begin(); it != objectFiles.end(); ++it)
{
std::string objLib = (*it)->GetObjectLibrary();
- if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+ if (cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLib))
{
objectLibraries.push_back(tgt);
}
}
- std::vector<cmTarget*>::const_iterator end
+ std::vector<cmGeneratorTarget*>::const_iterator end
= cmRemoveDuplicates(objectLibraries);
- for(std::vector<cmTarget*>::const_iterator
+ for(std::vector<cmGeneratorTarget*>::const_iterator
ti = objectLibraries.begin();
ti != end; ++ti)
{
- cmTarget* objLib = *ti;
- cmGeneratorTarget* ogt =
- this->GlobalGenerator->GetGeneratorTarget(objLib);
+ cmGeneratorTarget* ogt = *ti;
std::vector<cmSourceFile const*> objectSources;
ogt->GetObjectSources(objectSources, config);
for(std::vector<cmSourceFile const*>::const_iterator
@@ -1569,28 +2171,27 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result,
this->GetName(),
"AUTOUIC_OPTIONS", 0, 0);
cmSystemTools::ExpandListArgument(ge.Parse(prop)
- ->Evaluate(this->Makefile,
+ ->Evaluate(this->LocalGenerator,
config,
false,
- this->Target,
+ this,
&dagChecker),
result);
}
//----------------------------------------------------------------------------
void processILibs(const std::string& config,
- cmTarget const* headTarget,
+ cmGeneratorTarget const* headTarget,
cmLinkItem const& item,
cmGlobalGenerator* gg,
- std::vector<cmTarget const*>& tgts,
- std::set<cmTarget const*>& emitted)
+ std::vector<cmGeneratorTarget const*>& tgts,
+ std::set<cmGeneratorTarget const*>& emitted)
{
if (item.Target && emitted.insert(item.Target).second)
{
tgts.push_back(item.Target);
- cmGeneratorTarget* gt = gg->GetGeneratorTarget(item.Target);
if(cmLinkInterfaceLibraries const* iface =
- gt->GetLinkInterfaceLibraries(config, headTarget, true))
+ item.Target->GetLinkInterfaceLibraries(config, headTarget, true))
{
for(std::vector<cmLinkItem>::const_iterator
it = iface->Libraries.begin();
@@ -1603,7 +2204,7 @@ void processILibs(const std::string& config,
}
//----------------------------------------------------------------------------
-const std::vector<const cmTarget*>&
+const std::vector<const cmGeneratorTarget*>&
cmGeneratorTarget::GetLinkImplementationClosure(
const std::string& config) const
{
@@ -1612,16 +2213,16 @@ cmGeneratorTarget::GetLinkImplementationClosure(
if(!tgts.Done)
{
tgts.Done = true;
- std::set<cmTarget const*> emitted;
+ std::set<cmGeneratorTarget const*> emitted;
cmLinkImplementationLibraries const* impl
- = this->Target->GetLinkImplementationLibraries(config);
+ = this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it)
{
- processILibs(config, this->Target, *it,
+ processILibs(config, this, *it,
this->LocalGenerator->GetGlobalGenerator(),
tgts , emitted);
}
@@ -1636,9 +2237,9 @@ public:
cmTargetTraceDependencies(cmGeneratorTarget* target);
void Trace();
private:
- cmTarget* Target;
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
+ cmLocalGenerator* LocalGenerator;
cmGlobalGenerator const* GlobalGenerator;
typedef cmGeneratorTarget::SourceEntry SourceEntry;
SourceEntry* CurrentEntry;
@@ -1662,15 +2263,16 @@ private:
//----------------------------------------------------------------------------
cmTargetTraceDependencies
::cmTargetTraceDependencies(cmGeneratorTarget* target):
- Target(target->Target), GeneratorTarget(target)
+ GeneratorTarget(target)
{
// Convenience.
- this->Makefile = this->Target->GetMakefile();
- this->GlobalGenerator = target->GetLocalGenerator()->GetGlobalGenerator();
+ this->Makefile = target->Target->GetMakefile();
+ this->LocalGenerator = target->GetLocalGenerator();
+ this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
this->CurrentEntry = 0;
// Queue all the source files already specified for the target.
- if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
+ if (target->GetType() != cmState::INTERFACE_LIBRARY)
{
std::vector<std::string> configs;
this->Makefile->GetConfigurations(configs);
@@ -1683,14 +2285,14 @@ cmTargetTraceDependencies
ci != configs.end(); ++ci)
{
std::vector<cmSourceFile*> sources;
- this->Target->GetSourceFiles(sources, *ci);
+ this->GeneratorTarget->GetSourceFiles(sources, *ci);
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
si != sources.end(); ++si)
{
cmSourceFile* sf = *si;
- const std::set<cmTarget const*> tgts =
+ const std::set<cmGeneratorTarget const*> tgts =
this->GlobalGenerator->GetFilenameTargetDepends(sf);
- if (tgts.find(this->Target) != tgts.end())
+ if (tgts.find(this->GeneratorTarget) != tgts.end())
{
std::ostringstream e;
e << "Evaluation output file\n \"" << sf->GetFullPath()
@@ -1709,9 +2311,12 @@ cmTargetTraceDependencies
}
// Queue pre-build, pre-link, and post-build rule dependencies.
- this->CheckCustomCommands(this->Target->GetPreBuildCommands());
- this->CheckCustomCommands(this->Target->GetPreLinkCommands());
- this->CheckCustomCommands(this->Target->GetPostBuildCommands());
+ this->CheckCustomCommands(
+ this->GeneratorTarget->GetPreBuildCommands());
+ this->CheckCustomCommands(
+ this->GeneratorTarget->GetPreLinkCommands());
+ this->CheckCustomCommands(
+ this->GeneratorTarget->GetPostBuildCommands());
}
//----------------------------------------------------------------------------
@@ -1723,7 +2328,7 @@ void cmTargetTraceDependencies::Trace()
// Get the next source from the queue.
cmSourceFile* sf = this->SourceQueue.front();
this->SourceQueue.pop();
- this->CurrentEntry = &this->GeneratorTarget->SourceEntries[sf];
+ this->CurrentEntry = &this->GeneratorTarget->SourceDepends[sf];
// Queue dependencies added explicitly by the user.
if(const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS"))
@@ -1755,7 +2360,7 @@ void cmTargetTraceDependencies::Trace()
}
this->CurrentEntry = 0;
- this->Target->AddTracedSources(this->NewSources);
+ this->GeneratorTarget->AddTracedSources(this->NewSources);
}
//----------------------------------------------------------------------------
@@ -1820,15 +2425,16 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
// Check for a target with this name.
if(cmGeneratorTarget* t
- = this->Makefile->FindGeneratorTargetToUse(util))
+ = this->GeneratorTarget->
+ GetLocalGenerator()->FindGeneratorTargetToUse(util))
{
// If we find the target and the dep was given as a full path,
// then make sure it was not a full path to something else, and
// the fact that the name matched a target was just a coincidence.
if(cmSystemTools::FileIsFullPath(dep.c_str()))
{
- if(t->GetType() >= cmTarget::EXECUTABLE &&
- t->GetType() <= cmTarget::MODULE_LIBRARY)
+ if(t->GetType() >= cmState::EXECUTABLE &&
+ t->GetType() <= cmState::MODULE_LIBRARY)
{
// This is really only for compatibility so we do not need to
// worry about configuration names and output names.
@@ -1839,7 +2445,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
tLocation = cmSystemTools::CollapseFullPath(tLocation);
if(depLocation == tLocation)
{
- this->Target->AddUtility(util);
+ this->GeneratorTarget->Target->AddUtility(util);
return true;
}
}
@@ -1848,7 +2454,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
{
// The original name of the dependency was not a full path. It
// must name a target, so add the target-level dependency.
- this->Target->AddUtility(util);
+ this->GeneratorTarget->Target->AddUtility(util);
return true;
}
}
@@ -1867,22 +2473,23 @@ cmTargetTraceDependencies
cmGeneratorExpression ge(cc.GetBacktrace());
// Add target-level dependencies referenced by generator expressions.
- std::set<cmTarget*> targets;
+ std::set<cmGeneratorTarget*> targets;
for(cmCustomCommandLines::const_iterator cit = cc.GetCommandLines().begin();
cit != cc.GetCommandLines().end(); ++cit)
{
std::string const& command = *cit->begin();
// Check for a target with this name.
- if(cmTarget* t = this->Makefile->FindTargetToUse(command))
+ if(cmGeneratorTarget* t =
+ this->LocalGenerator->FindGeneratorTargetToUse(command))
{
- if(t->GetType() == cmTarget::EXECUTABLE)
+ if(t->GetType() == cmState::EXECUTABLE)
{
// The command refers to an executable target built in
// this project. Add the target-level dependency to make
// sure the executable is up to date before this custom
// command possibly runs.
- this->Target->AddUtility(command);
+ this->GeneratorTarget->Target->AddUtility(command);
}
}
@@ -1892,16 +2499,16 @@ cmTargetTraceDependencies
{
const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge
= ge.Parse(*cli);
- cge->Evaluate(this->Makefile, "", true);
- std::set<cmTarget*> geTargets = cge->GetTargets();
+ cge->Evaluate(this->GeneratorTarget->GetLocalGenerator(), "", true);
+ std::set<cmGeneratorTarget*> geTargets = cge->GetTargets();
targets.insert(geTargets.begin(), geTargets.end());
}
}
- for(std::set<cmTarget*>::iterator ti = targets.begin();
+ for(std::set<cmGeneratorTarget*>::iterator ti = targets.begin();
ti != targets.end(); ++ti)
{
- this->Target->AddUtility((*ti)->GetName());
+ this->GeneratorTarget->Target->AddUtility((*ti)->GetName());
}
// Queue the custom command dependencies.
@@ -1964,7 +2571,7 @@ void cmGeneratorTarget::TraceDependencies()
// would find nothing anyway, but when building CMake itself the "install"
// target command ends up referencing the "cmake" target but we do not
// really want the dependency because "install" depend on "all" anyway.
- if(this->GetType() == cmTarget::GLOBAL_TARGET)
+ if(this->GetType() == cmState::GLOBAL_TARGET)
{
return;
}
@@ -1993,11 +2600,11 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
{
std::string defVarName = "OSX_ARCHITECTURES_";
defVarName += cmSystemTools::UpperCase(config);
- archs = this->Target->GetProperty(defVarName);
+ archs = this->GetProperty(defVarName);
}
if(!archs)
{
- archs = this->Target->GetProperty("OSX_ARCHITECTURES");
+ archs = this->GetProperty("OSX_ARCHITECTURES");
}
if(archs)
{
@@ -2012,7 +2619,7 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
{
switch(this->GetType())
{
- case cmTarget::STATIC_LIBRARY:
+ case cmState::STATIC_LIBRARY:
{
std::string var = "CMAKE_" + lang + "_CREATE_STATIC_LIBRARY";
if(this->GetFeatureAsBool(
@@ -2026,11 +2633,11 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang,
}
return var;
}
- case cmTarget::SHARED_LIBRARY:
+ case cmState::SHARED_LIBRARY:
return "CMAKE_" + lang + "_CREATE_SHARED_LIBRARY";
- case cmTarget::MODULE_LIBRARY:
+ case cmState::MODULE_LIBRARY:
return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
- case cmTarget::EXECUTABLE:
+ case cmState::EXECUTABLE:
return "CMAKE_" + lang + "_LINK_EXECUTABLE";
default:
break;
@@ -2046,8 +2653,6 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
const std::string& config, bool debugIncludes,
const std::string& language)
{
- cmMakefile *mf = tgt->Target->GetMakefile();
-
for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
@@ -2056,10 +2661,11 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
bool const fromImported = item.Target && item.Target->IsImported();
bool const checkCMP0027 = item.FromGenex;
std::vector<std::string> entryIncludes;
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(
+ tgt->GetLocalGenerator(),
config,
false,
- tgt->Target,
+ tgt,
dagChecker, language),
entryIncludes);
@@ -2074,7 +2680,7 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
cmake::MessageType messageType = cmake::FATAL_ERROR;
if (checkCMP0027)
{
- switch(tgt->Target->GetPolicyStatusCMP0027())
+ switch(tgt->GetPolicyStatusCMP0027())
{
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n";
@@ -2113,7 +2719,7 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
}
else
{
- switch(tgt->Target->GetPolicyStatusCMP0021())
+ switch(tgt->GetPolicyStatusCMP0021())
{
case cmPolicies::WARN:
{
@@ -2159,7 +2765,7 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
}
if (!usedIncludes.empty())
{
- mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
std::string("Used includes for target ")
+ tgt->GetName() + ":\n"
+ usedIncludes, (*it)->ge->GetBacktrace());
@@ -2167,34 +2773,6 @@ static void processIncludeDirectories(cmGeneratorTarget const* tgt,
}
}
-
-//----------------------------------------------------------------------------
-static void AddInterfaceEntries(
- cmGeneratorTarget const* thisTarget, std::string const& config,
- std::string const& prop,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
-{
- if(cmLinkImplementationLibraries const* impl =
- thisTarget->Target->GetLinkImplementationLibraries(config))
- {
- for (std::vector<cmLinkImplItem>::const_iterator
- it = impl->Libraries.begin(), end = impl->Libraries.end();
- it != end; ++it)
- {
- if(it->Target)
- {
- std::string genex =
- "$<TARGET_PROPERTY:" + *it + "," + prop + ">";
- cmGeneratorExpression ge(it->Backtrace);
- cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
- cge->SetEvaluateForBuildsystem(true);
- entries.push_back(
- new cmGeneratorTarget::TargetPropertyEntry(cge, *it));
- }
- }
- }
-}
-
//----------------------------------------------------------------------------
std::vector<std::string>
cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
@@ -2243,7 +2821,7 @@ cmGeneratorTarget::GetIncludeDirectories(const std::string& config,
if(this->Makefile->IsOn("APPLE"))
{
cmLinkImplementationLibraries const* impl =
- this->Target->GetLinkImplementationLibraries(config);
+ this->GetLinkImplementationLibraries(config);
for(std::vector<cmLinkImplItem>::const_iterator
it = impl->Libraries.begin();
it != impl->Libraries.end(); ++it)
@@ -2290,16 +2868,15 @@ static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
const std::string& config, bool debugOptions, const char *logName,
std::string const& language)
{
- cmMakefile *mf = tgt->Target->GetMakefile();
-
for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator
it = entries.begin(), end = entries.end(); it != end; ++it)
{
std::vector<std::string> entryOptions;
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf,
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(
+ tgt->GetLocalGenerator(),
config,
false,
- tgt->Target,
+ tgt,
dagChecker,
language),
entryOptions);
@@ -2320,7 +2897,7 @@ static void processCompileOptionsInternal(cmGeneratorTarget const* tgt,
}
if (!usedOptions.empty())
{
- mf->GetCMakeInstance()->IssueMessage(cmake::LOG,
+ tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(cmake::LOG,
std::string("Used compile ") + logName
+ std::string(" for target ")
+ tgt->GetName() + ":\n"
@@ -2528,7 +3105,7 @@ void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list,
{
std::string configPropName = "COMPILE_DEFINITIONS_"
+ cmSystemTools::UpperCase(config);
- const char *configProp = this->Target->GetProperty(configPropName);
+ const char *configProp = this->GetProperty(configPropName);
if (configProp)
{
switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043))
@@ -2573,7 +3150,7 @@ void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list,
void cmGeneratorTarget::ComputeTargetManifest(
const std::string& config) const
{
- if (this->Target->IsImported())
+ if (this->IsImported())
{
return;
}
@@ -2585,13 +3162,13 @@ void cmGeneratorTarget::ComputeTargetManifest(
std::string realName;
std::string impName;
std::string pdbName;
- if(this->GetType() == cmTarget::EXECUTABLE)
+ if(this->GetType() == cmState::EXECUTABLE)
{
this->GetExecutableNames(name, realName, impName, pdbName, config);
}
- else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
- this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
+ else if(this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY)
{
this->GetLibraryNames(name, soName, realName, impName, pdbName,
config);
@@ -2602,7 +3179,7 @@ void cmGeneratorTarget::ComputeTargetManifest(
}
// Get the directory.
- std::string dir = this->Target->GetDirectory(config, false);
+ std::string dir = this->GetDirectory(config, false);
// Add each name.
std::string f;
@@ -2636,7 +3213,7 @@ void cmGeneratorTarget::ComputeTargetManifest(
}
if(!impName.empty())
{
- f = this->Target->GetDirectory(config, true);
+ f = this->GetDirectory(config, true);
f += "/";
f += impName;
gg->AddToManifest(f);
@@ -2647,7 +3224,7 @@ void cmGeneratorTarget::ComputeTargetManifest(
std::string cmGeneratorTarget::GetFullPath(const std::string& config,
bool implib, bool realname) const
{
- if(this->Target->IsImported())
+ if(this->IsImported())
{
return this->Target->ImportedGetFullPath(config, implib);
}
@@ -2661,9 +3238,9 @@ std::string cmGeneratorTarget::NormalGetFullPath(const std::string& config,
bool implib,
bool realname) const
{
- std::string fpath = this->Target->GetDirectory(config, implib);
+ std::string fpath = this->GetDirectory(config, implib);
fpath += "/";
- if(this->Target->IsAppBundleOnApple())
+ if(this->IsAppBundleOnApple())
{
fpath = this->BuildMacContentDirectory(fpath, config, false);
fpath += "/";
@@ -2692,14 +3269,14 @@ cmGeneratorTarget::NormalGetRealName(const std::string& config) const
// This should not be called for imported targets.
// TODO: Split cmTarget into a class hierarchy to get compile-time
// enforcement of the limited imported target API.
- if(this->Target->IsImported())
+ if(this->IsImported())
{
std::string msg = "NormalGetRealName called on imported target: ";
msg += this->GetName();
this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
}
- if(this->GetType() == cmTarget::EXECUTABLE)
+ if(this->GetType() == cmState::EXECUTABLE)
{
// Compute the real name that will be built.
std::string name;
@@ -2734,7 +3311,7 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name,
// This should not be called for imported targets.
// TODO: Split cmTarget into a class hierarchy to get compile-time
// enforcement of the limited imported target API.
- if(this->Target->IsImported())
+ if(this->IsImported())
{
std::string msg = "GetLibraryNames called on imported target: ";
msg += this->GetName();
@@ -2748,7 +3325,7 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name,
const char* soversion = this->GetProperty("SOVERSION");
if(!this->HasSOName(config) ||
this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
- this->Target->IsFrameworkOnApple())
+ this->IsFrameworkOnApple())
{
// Versioning is supported only for shared libraries and modules,
// and then only when the platform supports an soname flag.
@@ -2776,13 +3353,13 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name,
// The library name.
name = prefix+base+suffix;
- if(this->Target->IsFrameworkOnApple())
+ if(this->IsFrameworkOnApple())
{
realName = prefix;
if(!this->Makefile->PlatformIsAppleIos())
{
realName += "Versions/";
- realName += this->Target->GetFrameworkVersion();
+ realName += this->GetFrameworkVersion();
realName += "/";
}
realName += base;
@@ -2791,17 +3368,17 @@ void cmGeneratorTarget::GetLibraryNames(std::string& name,
else
{
// The library's soname.
- this->Target->ComputeVersionedName(soName, prefix, base, suffix,
+ this->ComputeVersionedName(soName, prefix, base, suffix,
name, soversion);
// The library's real name on disk.
- this->Target->ComputeVersionedName(realName, prefix, base, suffix,
+ this->ComputeVersionedName(realName, prefix, base, suffix,
name, version);
}
// The import library name.
- if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->GetType() == cmTarget::MODULE_LIBRARY)
+ if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY)
{
impName = this->GetFullNameInternal(config, true);
}
@@ -2824,7 +3401,7 @@ void cmGeneratorTarget::GetExecutableNames(std::string& name,
// This should not be called for imported targets.
// TODO: Split cmTarget into a class hierarchy to get compile-time
// enforcement of the limited imported target API.
- if(this->Target->IsImported())
+ if(this->IsImported())
{
std::string msg =
"GetExecutableNames called on imported target: ";
@@ -2839,7 +3416,7 @@ void cmGeneratorTarget::GetExecutableNames(std::string& name,
#else
// Check for executable version properties.
const char* version = this->GetProperty("VERSION");
- if(this->GetType() != cmTarget::EXECUTABLE || this->Makefile->IsOn("XCODE"))
+ if(this->GetType() != cmState::EXECUTABLE || this->Makefile->IsOn("XCODE"))
{
version = 0;
}
@@ -2888,6 +3465,24 @@ std::string cmGeneratorTarget::GetFullNameInternal(const std::string& config,
}
//----------------------------------------------------------------------------
+const char*
+cmGeneratorTarget::ImportedGetLocation(const std::string& config) const
+{
+ static std::string location;
+ assert(this->IsImported());
+ location = this->Target->ImportedGetFullPath(config, false);
+ return location.c_str();
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFullNameImported(const std::string& config,
+ bool implib) const
+{
+ return cmSystemTools::GetFilenameName(
+ this->Target->ImportedGetFullPath(config, implib));
+}
+
+//----------------------------------------------------------------------------
void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
bool implib,
std::string& outPrefix,
@@ -2895,10 +3490,10 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
std::string& outSuffix) const
{
// Use just the target name for non-main target types.
- if(this->GetType() != cmTarget::STATIC_LIBRARY &&
- this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- this->GetType() != cmTarget::EXECUTABLE)
+ if(this->GetType() != cmState::STATIC_LIBRARY &&
+ this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY &&
+ this->GetType() != cmState::EXECUTABLE)
{
outPrefix = "";
outBase = this->GetName();
@@ -2919,9 +3514,9 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
// The implib option is only allowed for shared libraries, module
// libraries, and executables.
- if(this->GetType() != cmTarget::SHARED_LIBRARY &&
- this->GetType() != cmTarget::MODULE_LIBRARY &&
- this->GetType() != cmTarget::EXECUTABLE)
+ if(this->GetType() != cmState::SHARED_LIBRARY &&
+ this->GetType() != cmState::MODULE_LIBRARY &&
+ this->GetType() != cmState::EXECUTABLE)
{
implib = false;
}
@@ -2941,8 +3536,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
configPostfix = this->GetProperty(configProp);
// Mac application bundles and frameworks have no postfix.
if(configPostfix &&
- (this->Target->IsAppBundleOnApple()
- || this->Target->IsFrameworkOnApple()))
+ (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
{
configPostfix = 0;
}
@@ -2979,7 +3573,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
// frameworks have directory prefix but no suffix
std::string fw_prefix;
- if(this->Target->IsFrameworkOnApple())
+ if(this->IsFrameworkOnApple())
{
fw_prefix = this->GetOutputName(config, false);
fw_prefix += ".framework/";
@@ -2987,7 +3581,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
targetSuffix = 0;
}
- if(this->Target->IsCFBundleOnApple())
+ if(this->IsCFBundleOnApple())
{
fw_prefix = this->GetCFBundleDirectory(config, false);
fw_prefix += "/";
@@ -3007,7 +3601,7 @@ void cmGeneratorTarget::GetFullNameInternal(const std::string& config,
// Name shared libraries with their version number on some platforms.
if(const char* soversion = this->GetProperty("SOVERSION"))
{
- if(this->GetType() == cmTarget::SHARED_LIBRARY && !implib &&
+ if(this->GetType() == cmState::SHARED_LIBRARY && !implib &&
this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION"))
{
outBase += "-";
@@ -3059,14 +3653,14 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
return prefix+base+".pdb";
}
-bool cmStrictTargetComparison::operator()(cmTarget const* t1,
- cmTarget const* t2) const
+bool cmGeneratorTarget::StrictTargetComparison::operator()(
+ cmGeneratorTarget const* t1, cmGeneratorTarget const* t2) const
{
int nameResult = strcmp(t1->GetName().c_str(), t2->GetName().c_str());
if (nameResult == 0)
{
- return strcmp(t1->GetMakefile()->GetCurrentBinaryDirectory(),
- t2->GetMakefile()->GetCurrentBinaryDirectory()) < 0;
+ return strcmp(t1->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ t2->GetLocalGenerator()->GetCurrentBinaryDirectory()) < 0;
}
return nameResult < 0;
}
@@ -3113,7 +3707,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
this->SourceFileFlagsConstructed = true;
// Process public headers to mark the source files.
- if(const char* files = this->Target->GetProperty("PUBLIC_HEADER"))
+ if(const char* files = this->GetProperty("PUBLIC_HEADER"))
{
std::vector<std::string> relFiles;
cmSystemTools::ExpandListArgument(files, relFiles);
@@ -3131,7 +3725,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// 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"))
+ if(const char* files = this->GetProperty("PRIVATE_HEADER"))
{
std::vector<std::string> relFiles;
cmSystemTools::ExpandListArgument(files, relFiles);
@@ -3148,7 +3742,7 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
}
// Mark sources listed as resources.
- if(const char* files = this->Target->GetProperty("RESOURCE"))
+ if(const char* files = this->GetProperty("RESOURCE"))
{
std::vector<std::string> relFiles;
cmSystemTools::ExpandListArgument(files, relFiles);
@@ -3158,7 +3752,11 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
if(cmSourceFile* sf = this->Makefile->GetSource(*it))
{
SourceFileFlags& flags = this->SourceFlagsMap[sf];
- flags.MacFolder = "Resources";
+ flags.MacFolder = "";
+ if(!this->Makefile->PlatformIsAppleIos())
+ {
+ flags.MacFolder = "Resources";
+ }
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
}
}
@@ -3176,10 +3774,10 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
compat.Done = true;
compat.PropsBool.insert("POSITION_INDEPENDENT_CODE");
compat.PropsString.insert("AUTOUIC_OPTIONS");
- std::vector<cmTarget const*> const& deps =
+ std::vector<cmGeneratorTarget const*> const& deps =
this->GetLinkImplementationClosure(config);
- for(std::vector<cmTarget const*>::const_iterator li = deps.begin();
- li != deps.end(); ++li)
+ for(std::vector<cmGeneratorTarget const*>::const_iterator li =
+ deps.begin(); li != deps.end(); ++li)
{
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
if(const char* prop = (*li)->GetProperty("COMPATIBLE_INTERFACE_" #X)) \
@@ -3202,8 +3800,8 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
bool cmGeneratorTarget::IsLinkInterfaceDependentBoolProperty(
const std::string &p, const std::string& config) const
{
- if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
- || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
{
return false;
}
@@ -3214,8 +3812,8 @@ bool cmGeneratorTarget::IsLinkInterfaceDependentBoolProperty(
bool cmGeneratorTarget::IsLinkInterfaceDependentStringProperty(
const std::string &p, const std::string& config) const
{
- if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
- || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
{
return false;
}
@@ -3226,8 +3824,8 @@ bool cmGeneratorTarget::IsLinkInterfaceDependentStringProperty(
bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMinProperty(
const std::string &p, const std::string& config) const
{
- if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
- || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
{
return false;
}
@@ -3238,8 +3836,8 @@ bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMinProperty(
bool cmGeneratorTarget::IsLinkInterfaceDependentNumberMaxProperty(
const std::string &p, const std::string& config) const
{
- if (this->Target->GetType() == cmTarget::OBJECT_LIBRARY
- || this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
+ if (this->GetType() == cmState::OBJECT_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
{
return false;
}
@@ -3296,7 +3894,7 @@ const char * getLinkInterfaceDependentProperty(cmGeneratorTarget const* tgt,
//----------------------------------------------------------------------------
template<typename PropertyType>
void checkPropertyConsistency(cmGeneratorTarget const* depender,
- cmTarget const* dependee,
+ cmGeneratorTarget const* dependee,
const std::string& propName,
std::set<std::string> &emitted,
const std::string& config,
@@ -3312,7 +3910,7 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
std::vector<std::string> props;
cmSystemTools::ExpandListArgument(prop, props);
std::string pdir =
- dependee->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
+ dependee->Target->GetMakefile()->GetRequiredDefinition("CMAKE_ROOT");
pdir += "/Help/prop_tgt/";
for(std::vector<std::string>::iterator pi = props.begin();
@@ -3525,18 +4123,20 @@ std::string compatibilityAgree(CompatibleType t, bool dominant)
//----------------------------------------------------------------------------
template<typename PropertyType>
-PropertyType getTypedProperty(cmTarget const* tgt, const std::string& prop);
+PropertyType getTypedProperty(cmGeneratorTarget const* tgt,
+ const std::string& prop);
//----------------------------------------------------------------------------
template<>
-bool getTypedProperty<bool>(cmTarget const* tgt, const std::string& prop)
+bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
+ const std::string& prop)
{
return tgt->GetPropertyAsBool(prop);
}
//----------------------------------------------------------------------------
template<>
-const char *getTypedProperty<const char *>(cmTarget const* tgt,
+const char *getTypedProperty<const char *>(cmGeneratorTarget const* tgt,
const std::string& prop)
{
return tgt->GetProperty(prop);
@@ -3666,16 +4266,18 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
CompatibleType t,
PropertyType *)
{
- PropertyType propContent = getTypedProperty<PropertyType>(tgt->Target, p);
- const bool explicitlySet = tgt->Target->GetProperties()
- .find(p)
- != tgt->Target->GetProperties().end();
+ PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
+ std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
+ const bool explicitlySet =
+ std::find(headPropKeys.begin(), headPropKeys.end(),
+ p) != headPropKeys.end();
+
const bool impliedByUse =
- tgt->Target->IsNullImpliedByLinkLibraries(p);
+ tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet)
|| (!impliedByUse && !explicitlySet));
- std::vector<cmTarget const*> const& deps =
+ std::vector<cmGeneratorTarget const*> const& deps =
tgt->GetLinkImplementationClosure(config);
if(deps.empty())
@@ -3702,7 +4304,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
}
std::string interfaceProperty = "INTERFACE_" + p;
- for(std::vector<cmTarget const*>::const_iterator li =
+ for(std::vector<cmGeneratorTarget const*>::const_iterator li =
deps.begin();
li != deps.end(); ++li)
{
@@ -3712,11 +4314,13 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
// target itself has a POSITION_INDEPENDENT_CODE which disagrees
// with a dependency.
- cmTarget const* theTarget = *li;
+ cmGeneratorTarget const* theTarget = *li;
- const bool ifaceIsSet = theTarget->GetProperties()
- .find(interfaceProperty)
- != theTarget->GetProperties().end();
+ std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
+
+ const bool ifaceIsSet =
+ std::find(propKeys.begin(), propKeys.end(),
+ interfaceProperty) != propKeys.end();
PropertyType ifacePropContent =
getTypedProperty<PropertyType>(theTarget,
interfaceProperty);
@@ -3920,6 +4524,93 @@ cmGeneratorTarget::GetLinkInformation(const std::string& config) const
}
//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const
+{
+ int patch;
+ this->GetTargetVersion(false, major, minor, patch);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetTargetVersion(bool soversion,
+ int& major, int& minor, int& patch) const
+{
+ // Set the default values.
+ major = 0;
+ minor = 0;
+ patch = 0;
+
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
+
+ // Look for a VERSION or SOVERSION property.
+ const char* prop = soversion? "SOVERSION" : "VERSION";
+ if(const char* version = this->GetProperty(prop))
+ {
+ // Try to parse the version number and store the results that were
+ // successfully parsed.
+ int parsed_major;
+ int parsed_minor;
+ int parsed_patch;
+ switch(sscanf(version, "%d.%d.%d",
+ &parsed_major, &parsed_minor, &parsed_patch))
+ {
+ case 3: patch = parsed_patch; // no break!
+ case 2: minor = parsed_minor; // no break!
+ case 1: major = parsed_major; // no break!
+ default: break;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetFrameworkVersion() const
+{
+ assert(this->GetType() != cmState::INTERFACE_LIBRARY);
+
+ if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION"))
+ {
+ return fversion;
+ }
+ else if(const char* tversion = this->GetProperty("VERSION"))
+ {
+ return tversion;
+ }
+ else
+ {
+ return "A";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeVersionedName(std::string& vName,
+ std::string const& prefix,
+ std::string const& base,
+ std::string const& suffix,
+ std::string const& name,
+ const char* version) const
+{
+ vName = this->Makefile->IsOn("APPLE") ? (prefix+base) : name;
+ if(version)
+ {
+ vName += ".";
+ vName += version;
+ }
+ vName += this->Makefile->IsOn("APPLE") ? suffix : std::string();
+}
+
+std::vector<std::string> cmGeneratorTarget::GetPropertyKeys() const
+{
+ cmPropertyMap propsObject = this->Target->GetProperties();
+ std::vector<std::string> props;
+ props.reserve(propsObject.size());
+ for (cmPropertyMap::const_iterator it = propsObject.begin();
+ it != propsObject.end(); ++it)
+ {
+ props.push_back(it->first);
+ }
+ return props;
+}
+
+//----------------------------------------------------------------------------
void
cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
const std::string &result,
@@ -3956,7 +4647,7 @@ cmGeneratorTarget::ReportPropertyOrigin(const std::string &p,
areport += result;
areport += "\"):\n" + report;
- this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(cmake::LOG, areport);
}
//----------------------------------------------------------------------------
@@ -3966,12 +4657,12 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
for(std::vector<std::string>::const_iterator i = names.begin();
i != names.end(); ++i)
{
- std::string name = this->Target->CheckCMP0004(*i);
+ std::string name = this->CheckCMP0004(*i);
if(name == this->GetName() || name.empty())
{
continue;
}
- items.push_back(cmLinkItem(name, this->Target->FindTargetToLink(name)));
+ items.push_back(cmLinkItem(name, this->FindTargetToLink(name)));
}
}
@@ -3979,7 +4670,7 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
std::string const& value,
std::string const& config,
- cmTarget const* headTarget,
+ cmGeneratorTarget const* headTarget,
bool usage_requirements_only,
std::vector<cmLinkItem>& items,
bool& hadHeadSensitiveCondition) const
@@ -3995,11 +4686,11 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
std::vector<std::string> libs;
cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
cmSystemTools::ExpandListArgument(cge->Evaluate(
- this->Makefile,
+ this->LocalGenerator,
config,
false,
headTarget,
- this->Target, &dagChecker), libs);
+ this, &dagChecker), libs);
this->LookupLinkItems(libs, items);
hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
}
@@ -4007,7 +4698,7 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
//----------------------------------------------------------------------------
cmLinkInterface const*
cmGeneratorTarget::GetLinkInterface(const std::string& config,
- cmTarget const* head) const
+ cmGeneratorTarget const* head) const
{
// Imported targets have their own link interface.
if(this->IsImported())
@@ -4017,8 +4708,8 @@ cmGeneratorTarget::GetLinkInterface(const std::string& config,
// Link interfaces are not supported for executables that do not
// export symbols.
- if(this->GetType() == cmTarget::EXECUTABLE &&
- !this->Target->IsExecutableWithExports())
+ if(this->GetType() == cmState::EXECUTABLE &&
+ !this->IsExecutableWithExports())
{
return 0;
}
@@ -4056,13 +4747,13 @@ cmGeneratorTarget::GetLinkInterface(const std::string& config,
//----------------------------------------------------------------------------
void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
cmOptionalLinkInterface &iface,
- cmTarget const* headTarget) const
+ cmGeneratorTarget const* headTarget) const
{
if(iface.ExplicitLibraries)
{
- if(this->GetType() == cmTarget::SHARED_LIBRARY
- || this->GetType() == cmTarget::STATIC_LIBRARY
- || this->GetType() == cmTarget::INTERFACE_LIBRARY)
+ if(this->GetType() == cmState::SHARED_LIBRARY
+ || this->GetType() == cmState::STATIC_LIBRARY
+ || this->GetType() == cmState::INTERFACE_LIBRARY)
{
// Shared libraries may have runtime implementation dependencies
// on other shared libraries that are not in the interface.
@@ -4072,7 +4763,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
{
emitted.insert(*li);
}
- if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
+ if (this->GetType() != cmState::INTERFACE_LIBRARY)
{
cmLinkImplementation const* impl =
this->GetLinkImplementation(config);
@@ -4084,7 +4775,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
if(li->Target)
{
// This is a runtime dependency on another shared library.
- if(li->Target->GetType() == cmTarget::SHARED_LIBRARY)
+ if(li->Target->GetType() == cmState::SHARED_LIBRARY)
{
iface.SharedDeps.push_back(*li);
}
@@ -4101,18 +4792,18 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
}
}
}
- else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
- || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
{
// The link implementation is the default link interface.
cmLinkImplementationLibraries const*
- impl = this->Target->GetLinkImplementationLibrariesInternal(config,
- headTarget);
+ impl = this->GetLinkImplementationLibrariesInternal(config,
+ headTarget);
iface.ImplementationIsInterface = true;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
}
- if(this->Target->LinkLanguagePropagatesToDependents())
+ if(this->LinkLanguagePropagatesToDependents())
{
// Targets using this archive need its language runtime libraries.
if(cmLinkImplementation const* impl =
@@ -4122,7 +4813,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
}
}
- if(this->GetType() == cmTarget::STATIC_LIBRARY)
+ if(this->GetType() == cmState::STATIC_LIBRARY)
{
// Construct the property name suffix for this configuration.
std::string suffix = "_";
@@ -4154,7 +4845,7 @@ void cmGeneratorTarget::ComputeLinkInterface(const std::string& config,
//----------------------------------------------------------------------------
const cmLinkInterfaceLibraries *
cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
- cmTarget const* head,
+ cmGeneratorTarget const* head,
bool usage_requirements_only) const
{
// Imported targets have their own link interface.
@@ -4166,8 +4857,8 @@ cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
// Link interfaces are not supported for executables that do not
// export symbols.
- if(this->GetType() == cmTarget::EXECUTABLE &&
- !this->Target->IsExecutableWithExports())
+ if(this->GetType() == cmState::EXECUTABLE &&
+ !this->IsExecutableWithExports())
{
return 0;
}
@@ -4198,11 +4889,261 @@ cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config,
}
//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetDirectory(const std::string& config,
+ bool implib) const
+{
+ if (this->IsImported())
+ {
+ // Return the directory from which the target is imported.
+ return
+ cmSystemTools::GetFilenamePath(
+ this->Target->ImportedGetFullPath(config, implib));
+ }
+ else if(OutputInfo const* info = this->GetOutputInfo(config))
+ {
+ // Return the directory in which the target will be built.
+ return implib? info->ImpDir : info->OutDir;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::UsesDefaultOutputDir(const std::string& config,
+ bool implib) const
+{
+ std::string dir;
+ return this->ComputeOutputDir(config, implib, dir);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo(
+ const std::string& config) const
+{
+ // There is no output information for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Only libraries and executables have well-defined output files.
+ if(!this->HaveWellDefinedOutputFiles())
+ {
+ std::string msg = "cmGeneratorTarget::GetOutputInfo called for ";
+ msg += this->GetName();
+ msg += " which has type ";
+ msg += cmState::GetTargetTypeName(this->GetType());
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ return 0;
+ }
+
+ // Lookup/compute/cache the output information for this configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ OutputInfoMapType::iterator i =
+ this->OutputInfoMap.find(config_upper);
+ if(i == this->OutputInfoMap.end())
+ {
+ // Add empty info in map to detect potential recursion.
+ OutputInfo info;
+ OutputInfoMapType::value_type entry(config_upper, info);
+ i = this->OutputInfoMap.insert(entry).first;
+
+ // Compute output directories.
+ this->ComputeOutputDir(config, false, info.OutDir);
+ this->ComputeOutputDir(config, true, info.ImpDir);
+ if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
+ {
+ info.PdbDir = info.OutDir;
+ }
+
+ // Now update the previously-prepared map entry.
+ i->second = info;
+ }
+ else if(i->second.empty())
+ {
+ // An empty map entry indicates we have been called recursively
+ // from the above block.
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+ this->GetBacktrace());
+ return 0;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
+ bool implib, std::string& out) const
+{
+ bool usesDefaultOutputDir = false;
+ std::string conf = config;
+
+ // Look for a target property defining the target output directory
+ // based on the target type.
+ std::string targetTypeName = this->GetOutputTargetType(implib);
+ const char* propertyName = 0;
+ std::string propertyNameStr = targetTypeName;
+ if(!propertyNameStr.empty())
+ {
+ propertyNameStr += "_OUTPUT_DIRECTORY";
+ propertyName = propertyNameStr.c_str();
+ }
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(conf);
+ const char* configProp = 0;
+ std::string configPropStr = targetTypeName;
+ if(!configPropStr.empty())
+ {
+ configPropStr += "_OUTPUT_DIRECTORY_";
+ configPropStr += configUpper;
+ configProp = configPropStr.c_str();
+ }
+
+ // Select an output directory.
+ if(const char* config_outdir = this->GetProperty(configProp))
+ {
+ // Use the user-specified per-configuration output directory.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(config_outdir);
+ out = cge->Evaluate(this->LocalGenerator, config);
+
+ // Skip per-configuration subdirectory.
+ conf = "";
+ }
+ else if(const char* outdir = this->GetProperty(propertyName))
+ {
+ // Use the user-specified output directory.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(outdir);
+ out = cge->Evaluate(this->LocalGenerator, config);
+
+ // Skip per-configuration subdirectory if the value contained a
+ // generator expression.
+ if (out != outdir)
+ {
+ conf = "";
+ }
+ }
+ else if(this->GetType() == cmState::EXECUTABLE)
+ {
+ // Lookup the output path for executables.
+ out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
+ else if(this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY)
+ {
+ // Lookup the output path for libraries.
+ out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
+ }
+ if(out.empty())
+ {
+ // Default to the current output directory.
+ usesDefaultOutputDir = true;
+ out = ".";
+ }
+
+ // Convert the output path to a full path in case it is
+ // specified as a relative path. Treat a relative path as
+ // relative to the current output directory for this makefile.
+ out = (cmSystemTools::CollapseFullPath
+ (out, this->LocalGenerator->GetCurrentBinaryDirectory()));
+
+ // The generator may add the configuration's subdirectory.
+ if(!conf.empty())
+ {
+ bool iosPlatform = this->Makefile->PlatformIsAppleIos();
+ std::string suffix =
+ usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
+ this->LocalGenerator->GetGlobalGenerator()->
+ AppendDirectoryForConfig("/", conf, suffix, out);
+ }
+
+ return usesDefaultOutputDir;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
+ const std::string& config,
+ std::string& out) const
+{
+ // Look for a target property defining the target output directory
+ // based on the target type.
+ const char* propertyName = 0;
+ std::string propertyNameStr = kind;
+ if(!propertyNameStr.empty())
+ {
+ propertyNameStr += "_OUTPUT_DIRECTORY";
+ propertyName = propertyNameStr.c_str();
+ }
+ std::string conf = config;
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(conf);
+ const char* configProp = 0;
+ std::string configPropStr = kind;
+ if(!configPropStr.empty())
+ {
+ configPropStr += "_OUTPUT_DIRECTORY_";
+ configPropStr += configUpper;
+ configProp = configPropStr.c_str();
+ }
+
+ // Select an output directory.
+ if(const char* config_outdir = this->GetProperty(configProp))
+ {
+ // Use the user-specified per-configuration output directory.
+ out = config_outdir;
+
+ // Skip per-configuration subdirectory.
+ conf = "";
+ }
+ else if(const char* outdir = this->GetProperty(propertyName))
+ {
+ // Use the user-specified output directory.
+ out = outdir;
+ }
+ if(out.empty())
+ {
+ return false;
+ }
+
+ // Convert the output path to a full path in case it is
+ // specified as a relative path. Treat a relative path as
+ // relative to the current output directory for this makefile.
+ out = (cmSystemTools::CollapseFullPath
+ (out, this->LocalGenerator->GetCurrentBinaryDirectory()));
+
+ // The generator may add the configuration's subdirectory.
+ if(!conf.empty())
+ {
+ this->LocalGenerator->GetGlobalGenerator()->
+ AppendDirectoryForConfig("/", conf, "", out);
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HaveInstallTreeRPATH() const
+{
+ const char* install_rpath = this->GetProperty("INSTALL_RPATH");
+ return (install_rpath && *install_rpath) &&
+ !this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
+}
+
+//----------------------------------------------------------------------------
void
cmGeneratorTarget::ComputeLinkInterfaceLibraries(
const std::string& config,
cmOptionalLinkInterface& iface,
- cmTarget const* headTarget,
+ cmGeneratorTarget const* headTarget,
bool usage_requirements_only) const
{
// Construct the property name suffix for this configuration.
@@ -4220,15 +5161,15 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// libraries and executables that export symbols.
const char* explicitLibraries = 0;
std::string linkIfaceProp;
- if(this->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
- this->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN)
+ if(this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+ this->GetPolicyStatusCMP0022() != cmPolicies::WARN)
{
// CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
explicitLibraries = this->GetProperty(linkIfaceProp);
}
- else if(this->GetType() == cmTarget::SHARED_LIBRARY ||
- this->Target->IsExecutableWithExports())
+ else if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
{
// CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a
// shared lib or executable.
@@ -4247,7 +5188,7 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
}
if(explicitLibraries &&
- this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+ this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
!this->PolicyWarnedCMP0022)
{
// Compare the explicitly set old link interface properties to the
@@ -4275,8 +5216,8 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// There is no implicit link interface for executables or modules
// so if none was explicitly set then there is no link interface.
if(!explicitLibraries &&
- (this->GetType() == cmTarget::EXECUTABLE ||
- (this->GetType() == cmTarget::MODULE_LIBRARY)))
+ (this->GetType() == cmState::EXECUTABLE ||
+ (this->GetType() == cmState::MODULE_LIBRARY)))
{
return;
}
@@ -4292,8 +5233,8 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
iface.Libraries,
iface.HadHeadSensitiveCondition);
}
- else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN
- || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN
+ || this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
// If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES, so if we get here then the project
// cleared the property explicitly and we should not fall back
@@ -4301,11 +5242,10 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
{
// The link implementation is the default link interface.
cmLinkImplementationLibraries const* impl =
- this->Target->GetLinkImplementationLibrariesInternal(config,
- headTarget);
+ this->GetLinkImplementationLibrariesInternal(config, headTarget);
iface.Libraries.insert(iface.Libraries.end(),
impl->Libraries.begin(), impl->Libraries.end());
- if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
+ if(this->GetPolicyStatusCMP0022() == cmPolicies::WARN &&
!this->PolicyWarnedCMP0022 && !usage_requirements_only)
{
// Compare the link implementation fallback link interface to the
@@ -4316,8 +5256,9 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
{
bool hadHeadSensitiveConditionDummy = false;
this->ExpandLinkItems(newProp, newExplicitLibraries, config,
- headTarget, usage_requirements_only,
- ifaceLibs, hadHeadSensitiveConditionDummy);
+ headTarget,
+ usage_requirements_only,
+ ifaceLibs, hadHeadSensitiveConditionDummy);
}
if (ifaceLibs != iface.Libraries)
{
@@ -4351,10 +5292,10 @@ cmGeneratorTarget::ComputeLinkInterfaceLibraries(
//----------------------------------------------------------------------------
const cmLinkInterface *
cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
- cmTarget const* headTarget,
+ cmGeneratorTarget const* headTarget,
bool usage_requirements_only) const
{
- cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config);
+ cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config);
if(!info)
{
return 0;
@@ -4392,6 +5333,223 @@ cmGeneratorTarget::GetImportLinkInterface(const std::string& config,
return &iface;
}
+//----------------------------------------------------------------------------
+cmGeneratorTarget::ImportInfo const*
+cmGeneratorTarget::GetImportInfo(const std::string& config) const
+{
+ // There is no imported information for non-imported targets.
+ if(!this->IsImported())
+ {
+ return 0;
+ }
+
+ // Lookup/compute/cache the import information for this
+ // configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ else
+ {
+ config_upper = "NOCONFIG";
+ }
+
+ ImportInfoMapType::const_iterator i =
+ this->ImportInfoMap.find(config_upper);
+ if(i == this->ImportInfoMap.end())
+ {
+ ImportInfo info;
+ this->ComputeImportInfo(config_upper, info);
+ ImportInfoMapType::value_type entry(config_upper, info);
+ i = this->ImportInfoMap.insert(entry).first;
+ }
+
+ if(this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return &i->second;
+ }
+ // If the location is empty then the target is not available for
+ // this configuration.
+ if(i->second.Location.empty() && i->second.ImportLibrary.empty())
+ {
+ return 0;
+ }
+
+ // Return the import information.
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
+ ImportInfo& info) const
+{
+ // This method finds information about an imported target from its
+ // properties. The "IMPORTED_" namespace is reserved for properties
+ // defined by the project exporting the target.
+
+ // Initialize members.
+ info.NoSOName = false;
+
+ const char* loc = 0;
+ const char* imp = 0;
+ std::string suffix;
+ if (!this->Target->GetMappedConfig(desired_config, &loc, &imp, suffix))
+ {
+ return;
+ }
+
+ // Get the link interface.
+ {
+ std::string linkProp = "INTERFACE_LINK_LIBRARIES";
+ const char *propertyLibs = this->GetProperty(linkProp);
+
+ if (this->GetType() != cmState::INTERFACE_LIBRARY)
+ {
+ if(!propertyLibs)
+ {
+ linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+ linkProp += suffix;
+ propertyLibs = this->GetProperty(linkProp);
+ }
+
+ if(!propertyLibs)
+ {
+ linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+ propertyLibs = this->GetProperty(linkProp);
+ }
+ }
+ if(propertyLibs)
+ {
+ info.LibrariesProp = linkProp;
+ info.Libraries = propertyLibs;
+ }
+ }
+ if(this->GetType() == cmState::INTERFACE_LIBRARY)
+ {
+ return;
+ }
+
+ // A provided configuration has been chosen. Load the
+ // configuration's properties.
+
+ // Get the location.
+ if(loc)
+ {
+ info.Location = loc;
+ }
+ else
+ {
+ std::string impProp = "IMPORTED_LOCATION";
+ impProp += suffix;
+ if(const char* config_location = this->GetProperty(impProp))
+ {
+ info.Location = config_location;
+ }
+ else if(const char* location = this->GetProperty("IMPORTED_LOCATION"))
+ {
+ info.Location = location;
+ }
+ }
+
+ // Get the soname.
+ if(this->GetType() == cmState::SHARED_LIBRARY)
+ {
+ std::string soProp = "IMPORTED_SONAME";
+ soProp += suffix;
+ if(const char* config_soname = this->GetProperty(soProp))
+ {
+ info.SOName = config_soname;
+ }
+ else if(const char* soname = this->GetProperty("IMPORTED_SONAME"))
+ {
+ info.SOName = soname;
+ }
+ }
+
+ // Get the "no-soname" mark.
+ if(this->GetType() == cmState::SHARED_LIBRARY)
+ {
+ std::string soProp = "IMPORTED_NO_SONAME";
+ soProp += suffix;
+ if(const char* config_no_soname = this->GetProperty(soProp))
+ {
+ info.NoSOName = cmSystemTools::IsOn(config_no_soname);
+ }
+ else if(const char* no_soname = this->GetProperty("IMPORTED_NO_SONAME"))
+ {
+ info.NoSOName = cmSystemTools::IsOn(no_soname);
+ }
+ }
+
+ // Get the import library.
+ if(imp)
+ {
+ info.ImportLibrary = imp;
+ }
+ else if(this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports())
+ {
+ std::string impProp = "IMPORTED_IMPLIB";
+ impProp += suffix;
+ if(const char* config_implib = this->GetProperty(impProp))
+ {
+ info.ImportLibrary = config_implib;
+ }
+ else if(const char* implib = this->GetProperty("IMPORTED_IMPLIB"))
+ {
+ info.ImportLibrary = implib;
+ }
+ }
+
+ // Get the link dependencies.
+ {
+ std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
+ linkProp += suffix;
+ if(const char* config_libs = this->GetProperty(linkProp))
+ {
+ info.SharedDeps = config_libs;
+ }
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES"))
+ {
+ info.SharedDeps = libs;
+ }
+ }
+
+ // Get the link languages.
+ if(this->LinkLanguagePropagatesToDependents())
+ {
+ std::string linkProp = "IMPORTED_LINK_INTERFACE_LANGUAGES";
+ linkProp += suffix;
+ if(const char* config_libs = this->GetProperty(linkProp))
+ {
+ info.Languages = config_libs;
+ }
+ else if(const char* libs =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES"))
+ {
+ info.Languages = libs;
+ }
+ }
+
+ // Get the cyclic repetition count.
+ if(this->GetType() == cmState::STATIC_LIBRARY)
+ {
+ std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
+ linkProp += suffix;
+ if(const char* config_reps = this->GetProperty(linkProp))
+ {
+ sscanf(config_reps, "%u", &info.Multiplicity);
+ }
+ else if(const char* reps =
+ this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY"))
+ {
+ sscanf(reps, "%u", &info.Multiplicity);
+ }
+ }
+}
+
cmHeadToLinkInterfaceMap&
cmGeneratorTarget::GetHeadToLinkInterfaceMap(const std::string &config) const
{
@@ -4412,17 +5570,17 @@ const cmLinkImplementation *
cmGeneratorTarget::GetLinkImplementation(const std::string& config) const
{
// There is no link implementation for imported targets.
- if(this->Target->IsImported())
+ if(this->IsImported())
{
return 0;
}
- cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config);
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this];
if(!impl.LibrariesDone)
{
impl.LibrariesDone = true;
- this->Target->ComputeLinkImplementationLibraries(config, impl,
- this->Target);
+ this->ComputeLinkImplementationLibraries(config, impl, this);
}
if(!impl.LanguagesDone)
{
@@ -4445,12 +5603,12 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
std::vector<std::string>::const_iterator it = configs.begin();
const std::string& firstConfig = *it;
- this->Target->GetSourceFiles(files, firstConfig);
+ this->GetSourceFiles(files, firstConfig);
for ( ; it != configs.end(); ++it)
{
std::vector<cmSourceFile*> configFiles;
- this->Target->GetSourceFiles(configFiles, *it);
+ this->GetSourceFiles(configFiles, *it);
if (configFiles != files)
{
std::string firstConfigFiles;
@@ -4490,6 +5648,105 @@ bool cmGeneratorTarget::GetConfigCommonSourceFiles(
}
//----------------------------------------------------------------------------
+void cmGeneratorTarget::GetObjectLibrariesCMP0026(
+ std::vector<cmGeneratorTarget*>& objlibs) const
+{
+ // At configure-time, this method can be called as part of getting the
+ // LOCATION property or to export() a file to be include()d. However
+ // there is no cmGeneratorTarget at configure-time, so search the SOURCES
+ // for TARGET_OBJECTS instead for backwards compatibility with OLD
+ // behavior of CMP0024 and CMP0026 only.
+ cmStringRange rng = this->Target->GetSourceEntries();
+ for(std::vector<std::string>::const_iterator
+ i = rng.begin(); i != rng.end(); ++i)
+ {
+ std::string const& entry = *i;
+
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator
+ li = files.begin(); li != files.end(); ++li)
+ {
+ if(cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>')
+ {
+ std::string objLibName = li->substr(17, li->size()-18);
+
+ if (cmGeneratorExpression::Find(objLibName) != std::string::npos)
+ {
+ continue;
+ }
+ cmGeneratorTarget *objLib =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLibName);
+ if(objLib)
+ {
+ objlibs.push_back(objLib);
+ }
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const
+{
+ // Strip whitespace off the library names because we used to do this
+ // in case variables were expanded at generate time. We no longer
+ // do the expansion but users link to libraries like " ${VAR} ".
+ std::string lib = item;
+ std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
+ if(pos != lib.npos)
+ {
+ lib = lib.substr(pos, lib.npos);
+ }
+ pos = lib.find_last_not_of(" \t\r\n");
+ if(pos != lib.npos)
+ {
+ lib = lib.substr(0, pos+1);
+ }
+ if(lib != item)
+ {
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ switch(this->GetPolicyStatusCMP0004())
+ {
+ case cmPolicies::WARN:
+ {
+ std::ostringstream w;
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0004) << "\n"
+ << "Target \"" << this->GetName() << "\" links to item \""
+ << item << "\" which has leading or trailing whitespace.";
+ cm->IssueMessage(cmake::AUTHOR_WARNING, w.str(),
+ this->GetBacktrace());
+ }
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::NEW:
+ {
+ std::ostringstream e;
+ e << "Target \"" << this->GetName() << "\" links to item \""
+ << item << "\" which has leading or trailing whitespace. "
+ << "This is now an error according to policy CMP0004.";
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->GetBacktrace());
+ }
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ {
+ std::ostringstream e;
+ e << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0004) << "\n"
+ << "Target \"" << this->GetName() << "\" links to item \""
+ << item << "\" which has leading or trailing whitespace.";
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->GetBacktrace());
+ }
+ break;
+ }
+ }
+ return lib;
+}
+
+//----------------------------------------------------------------------------
void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
const std::string& config) const
{
@@ -4509,14 +5766,13 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
std::vector<cmSourceFile const*> externalObjects;
if (!this->GlobalGenerator->GetConfigureDoneCMP0026())
{
- std::vector<cmTarget*> objectTargets;
- this->Target->GetObjectLibrariesCMP0026(objectTargets);
+ std::vector<cmGeneratorTarget*> objectTargets;
+ this->GetObjectLibrariesCMP0026(objectTargets);
objectLibraries.reserve(objectTargets.size());
- for (std::vector<cmTarget*>::const_iterator it = objectTargets.begin();
- it != objectTargets.end(); ++it)
+ for (std::vector<cmGeneratorTarget*>::const_iterator it =
+ objectTargets.begin(); it != objectTargets.end(); ++it)
{
- objectLibraries.push_back(this->GlobalGenerator
- ->GetGeneratorTarget(*it));
+ objectLibraries.push_back(*it);
}
}
else
@@ -4526,10 +5782,10 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
i = externalObjects.begin(); i != externalObjects.end(); ++i)
{
std::string objLib = (*i)->GetObjectLibrary();
- if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib))
+ if (cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(objLib))
{
- objectLibraries.push_back(this->GlobalGenerator
- ->GetGeneratorTarget(tgt));
+ objectLibraries.push_back(tgt);
}
}
}
@@ -4557,14 +5813,317 @@ void cmGeneratorTarget::ComputeLinkImplementationLanguages(
//----------------------------------------------------------------------------
bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const
{
- if (this->Target->GetPropertyAsBool("SKIP_BUILD_RPATH"))
+ if (this->GetPropertyAsBool("SKIP_BUILD_RPATH"))
{
return false;
}
if(cmLinkImplementationLibraries const* impl =
- this->Target->GetLinkImplementationLibraries(config))
+ this->GetLinkImplementationLibraries(config))
{
return !impl->Libraries.empty();
}
return false;
}
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibraries(
+ const std::string& config) const
+{
+ return this->GetLinkImplementationLibrariesInternal(config, this);
+}
+
+//----------------------------------------------------------------------------
+cmLinkImplementationLibraries const*
+cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
+ const std::string& config, cmGeneratorTarget const* head) const
+{
+ // There is no link implementation for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Populate the link implementation libraries for this configuration.
+ std::string CONFIG = cmSystemTools::UpperCase(config);
+ HeadToLinkImplementationMap& hm =
+ this->LinkImplMap[CONFIG];
+
+ // If the link implementation does not depend on the head target
+ // then return the one we computed first.
+ if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition)
+ {
+ return &hm.begin()->second;
+ }
+
+ cmOptionalLinkImplementation& impl = hm[head];
+ if(!impl.LibrariesDone)
+ {
+ impl.LibrariesDone = true;
+ this->ComputeLinkImplementationLibraries(config, impl, head);
+ }
+ return &impl;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratorTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
+{
+ return this->LinkImplicitNullProperties.find(p)
+ != this->LinkImplicitNullProperties.end();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorTarget::ComputeLinkImplementationLibraries(
+ const std::string& config,
+ cmOptionalLinkImplementation& impl,
+ cmGeneratorTarget const* head) const
+{
+ cmStringRange entryRange =
+ this->Target->GetLinkImplementationEntries();
+ cmBacktraceRange btRange =
+ this->Target->GetLinkImplementationBacktraces();
+ cmBacktraceRange::const_iterator btIt = btRange.begin();
+ // Collect libraries directly linked in this configuration.
+ for (cmStringRange::const_iterator le = entryRange.begin(),
+ end = entryRange.end(); le != end; ++le, ++btIt)
+ {
+ std::vector<std::string> llibs;
+ cmGeneratorExpressionDAGChecker dagChecker(
+ this->GetName(),
+ "LINK_LIBRARIES", 0, 0);
+ cmGeneratorExpression ge(*btIt);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
+ ge.Parse(*le);
+ std::string const evaluated =
+ cge->Evaluate(this->LocalGenerator, config, false, head, &dagChecker);
+ cmSystemTools::ExpandListArgument(evaluated, llibs);
+ if(cge->GetHadHeadSensitiveCondition())
+ {
+ impl.HadHeadSensitiveCondition = true;
+ }
+
+ for(std::vector<std::string>::const_iterator li = llibs.begin();
+ li != llibs.end(); ++li)
+ {
+ // Skip entries that resolve to the target itself or are empty.
+ std::string name = this->CheckCMP0004(*li);
+ if(name == this->GetName() || name.empty())
+ {
+ if(name == this->GetName())
+ {
+ bool noMessage = false;
+ cmake::MessageType messageType = cmake::FATAL_ERROR;
+ std::ostringstream e;
+ switch(this->GetPolicyStatusCMP0038())
+ {
+ case cmPolicies::WARN:
+ {
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0038) << "\n";
+ messageType = cmake::AUTHOR_WARNING;
+ }
+ break;
+ case cmPolicies::OLD:
+ noMessage = true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Issue the fatal message.
+ break;
+ }
+
+ if(!noMessage)
+ {
+ e << "Target \"" << this->GetName() << "\" links to itself.";
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ messageType, e.str(), this->GetBacktrace());
+ if (messageType == cmake::FATAL_ERROR)
+ {
+ return;
+ }
+ }
+ }
+ continue;
+ }
+
+ // The entry is meant for this configuration.
+ impl.Libraries.push_back(
+ cmLinkImplItem(name, this->FindTargetToLink(name),
+ *btIt, evaluated != *le));
+ }
+
+ std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
+ for (std::set<std::string>::const_iterator it = seenProps.begin();
+ it != seenProps.end(); ++it)
+ {
+ if (!this->GetProperty(*it))
+ {
+ this->LinkImplicitNullProperties.insert(*it);
+ }
+ }
+ cge->GetMaxLanguageStandard(this,
+ this->MaxLanguageStandards);
+ }
+
+ // Get the list of configurations considered to be DEBUG.
+ std::vector<std::string> debugConfigs =
+ this->Makefile->GetCMakeInstance()->GetDebugConfigs();
+
+ cmTargetLinkLibraryType linkType =
+ CMP0003_ComputeLinkType(config, debugConfigs);
+ cmTarget::LinkLibraryVectorType const& oldllibs =
+ this->Target->GetOriginalLinkLibraries();
+ for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
+ li != oldllibs.end(); ++li)
+ {
+ if(li->second != GENERAL_LibraryType && li->second != linkType)
+ {
+ std::string name = this->CheckCMP0004(li->first);
+ if(name == this->GetName() || name.empty())
+ {
+ continue;
+ }
+ // Support OLD behavior for CMP0003.
+ impl.WrongConfigLibraries.push_back(
+ cmLinkItem(name, this->FindTargetToLink(name)));
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget*
+cmGeneratorTarget::FindTargetToLink(std::string const& name) const
+{
+ cmGeneratorTarget* tgt =
+ this->LocalGenerator->FindGeneratorTargetToUse(name);
+
+ // Skip targets that will not really be linked. This is probably a
+ // name conflict between an external library and an executable
+ // within the project.
+ if(tgt && tgt->GetType() == cmState::EXECUTABLE &&
+ !tgt->IsExecutableWithExports())
+ {
+ tgt = 0;
+ }
+
+ if(tgt && tgt->GetType() == cmState::OBJECT_LIBRARY)
+ {
+ std::ostringstream e;
+ e << "Target \"" << this->GetName() << "\" links to "
+ "OBJECT library \"" << tgt->GetName() << "\" but this is not "
+ "allowed. "
+ "One may link only to STATIC or SHARED libraries, or to executables "
+ "with the ENABLE_EXPORTS property set.";
+ cmake* cm = this->LocalGenerator->GetCMakeInstance();
+ cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
+ this->GetBacktrace());
+ tgt = 0;
+ }
+
+ return tgt;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
+{
+ if(OutputInfo const* info = this->GetOutputInfo(config))
+ {
+ // Return the directory in which the target will be built.
+ return info->PdbDir;
+ }
+ return "";
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasImplibGNUtoMS() const
+{
+ return this->HasImportLibrary()
+ && this->GetPropertyAsBool("GNUtoMS");
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& gnuName,
+ std::string& out, const char* newExt) const
+{
+ if(this->HasImplibGNUtoMS() &&
+ gnuName.size() > 6 && gnuName.substr(gnuName.size()-6) == ".dll.a")
+ {
+ out = gnuName.substr(0, gnuName.size()-6);
+ out += newExt? newExt : ".lib";
+ return true;
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsExecutableWithExports() const
+{
+ return (this->GetType() == cmState::EXECUTABLE &&
+ this->GetPropertyAsBool("ENABLE_EXPORTS"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::HasImportLibrary() const
+{
+ return (this->IsDLLPlatform() &&
+ (this->GetType() == cmState::SHARED_LIBRARY ||
+ this->IsExecutableWithExports()));
+}
+
+//----------------------------------------------------------------------------
+std::string cmGeneratorTarget::GetSupportDirectory() const
+{
+ std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory();
+ dir += cmake::GetCMakeFilesDirectory();
+ dir += "/";
+ dir += this->GetName();
+#if defined(__VMS)
+ dir += "_dir";
+#else
+ dir += ".dir";
+#endif
+ return dir;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsLinkable() const
+{
+ return (this->GetType() == cmState::STATIC_LIBRARY ||
+ this->GetType() == cmState::SHARED_LIBRARY ||
+ this->GetType() == cmState::MODULE_LIBRARY ||
+ this->GetType() == cmState::UNKNOWN_LIBRARY ||
+ this->GetType() == cmState::INTERFACE_LIBRARY ||
+ this->IsExecutableWithExports());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsFrameworkOnApple() const
+{
+ return (this->GetType() == cmState::SHARED_LIBRARY &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("FRAMEWORK"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsAppBundleOnApple() const
+{
+ return (this->GetType() == cmState::EXECUTABLE &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("MACOSX_BUNDLE"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsXCTestOnApple() const
+{
+ return (this->IsCFBundleOnApple() &&
+ this->GetPropertyAsBool("XCTEST"));
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::IsCFBundleOnApple() const
+{
+ return (this->GetType() == cmState::MODULE_LIBRARY &&
+ this->Makefile->IsOn("APPLE") &&
+ this->GetPropertyAsBool("BUNDLE"));
+}