Merge topic 'use-generator-target'

1c1c2a12 cmGeneratorTarget: Port ExpandLinkItems away from cmTarget.
c66084f5 cmGeneratorTarget: Port GetImportLinkInterface away from cmTarget.
83c29e39 cmGeneratorTarget: Port ComputeLinkImplementationLibraries away from cmTarget.
19882554 cmGeneratorTarget: Port handleSystemIncludesDep away from cmTarget.
c1f687b1 cmGeneratorTarget: Port GetLinkImplementationLibrariesInternal.
a6e1f05c cmGeneratorTarget: Port ComputeLinkInterface away from cmTarget.
654002fe cmGeneratorTarget: Port ComputeLinkInterfaceLibraries away from cmTarget.
922c8901 cmGeneratorTarget: Port GetLinkInterface away from cmTarget.
eaa5b9cb cmGeneratorTarget: Port cmTargetCollectLinkLanguages away from cmTarget.
f539da12 cmGeneratorTarget: Port GetLinkInterfaceLibraries away from cmTarget.
1c5d70f9 cmGeneratorTarget: Port processILibs away from cmTarget.
064c2488 cmComputeLinkDepends: Port some API to cmGeneratorTarget.
3e428fdc cmGeneratorTarget: Move IsImportedSharedLibWithoutSOName from cmTarget.
110fd2fb cmGeneratorTarget: Move GetOutputTargetType from cmTarget.
e7391699 cmGeneratorTarget: Move HasMacOSXRpathInstallNameDir from cmTarget.
c5718217 cmGeneratorTarget: Move HaveInstallTreeRPATH from cmTarget.
...
This commit is contained in:
Brad King 2015-10-12 10:26:20 -04:00 committed by CMake Topic Stage
commit aad0e62060
25 changed files with 870 additions and 884 deletions

View File

@ -268,7 +268,7 @@ cmComputeLinkDepends::Compute()
{ {
int i = *li; int i = *li;
LinkEntry const& e = this->EntryList[i]; LinkEntry const& e = this->EntryList[i];
cmTarget const* t = e.Target; cmGeneratorTarget const* t = e.Target;
// Entries that we know the linker will re-use do not need to be repeated. // Entries that we know the linker will re-use do not need to be repeated.
bool uniquify = t && t->GetType() == cmTarget::SHARED_LIBRARY; bool uniquify = t && t->GetType() == cmTarget::SHARED_LIBRARY;
if(!uniquify || emmitted.insert(i).second) if(!uniquify || emmitted.insert(i).second)
@ -320,7 +320,8 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item)
int index = lei->second; int index = lei->second;
LinkEntry& entry = this->EntryList[index]; LinkEntry& entry = this->EntryList[index];
entry.Item = item; entry.Item = item;
entry.Target = item.Target; entry.Target =
item.Target ? this->GlobalGenerator->GetGeneratorTarget(item.Target) : 0;
entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' && entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' &&
item.substr(0, 10) != "-framework"); item.substr(0, 10) != "-framework");
@ -362,11 +363,9 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
// Follow the item's dependencies. // Follow the item's dependencies.
if(entry.Target) if(entry.Target)
{ {
cmGeneratorTarget* gtgt =
this->GlobalGenerator->GetGeneratorTarget(entry.Target);
// Follow the target dependencies. // Follow the target dependencies.
if(cmLinkInterface const* iface = if(cmLinkInterface const* iface =
gtgt->GetLinkInterface(this->Config, this->Target->Target)) entry.Target->GetLinkInterface(this->Config, this->Target))
{ {
const bool isIface = const bool isIface =
entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY; entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
@ -444,7 +443,9 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Initialize the item entry. // Initialize the item entry.
LinkEntry& entry = this->EntryList[lei->second]; LinkEntry& entry = this->EntryList[lei->second];
entry.Item = dep.Item; entry.Item = dep.Item;
entry.Target = dep.Item.Target; entry.Target =
dep.Item.Target ?
this->GlobalGenerator->GetGeneratorTarget(dep.Item.Target) : 0;
// This item was added specifically because it is a dependent // This item was added specifically because it is a dependent
// shared library. It may get special treatment // shared library. It may get special treatment
@ -463,10 +464,8 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// Target items may have their own dependencies. // Target items may have their own dependencies.
if(entry.Target) if(entry.Target)
{ {
cmGeneratorTarget* gtgt =
this->GlobalGenerator->GetGeneratorTarget(entry.Target);
if(cmLinkInterface const* iface = if(cmLinkInterface const* iface =
gtgt->GetLinkInterface(this->Config, this->Target->Target)) entry.Target->GetLinkInterface(this->Config, this->Target))
{ {
// Follow public and private dependencies transitively. // Follow public and private dependencies transitively.
this->FollowSharedDeps(index, iface, true); this->FollowSharedDeps(index, iface, true);
@ -639,15 +638,16 @@ cmTarget const* cmComputeLinkDepends::FindTargetToLink(int depender_index,
const std::string& name) const std::string& name)
{ {
// Look for a target in the scope of the depender. // Look for a target in the scope of the depender.
cmTarget const* from = this->Target->Target; cmGeneratorTarget const* from = this->Target;
if(depender_index >= 0) if(depender_index >= 0)
{ {
if(cmTarget const* depender = this->EntryList[depender_index].Target) if(cmGeneratorTarget const* depender =
this->EntryList[depender_index].Target)
{ {
from = depender; from = depender;
} }
} }
return from->FindTargetToLink(name); return from->Target->FindTargetToLink(name);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -934,12 +934,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl)
int count = 2; int count = 2;
for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni)
{ {
if(cmTarget const* target = this->EntryList[*ni].Target) if(cmGeneratorTarget const* target = this->EntryList[*ni].Target)
{ {
cmGeneratorTarget* gtgt =
this->GlobalGenerator->GetGeneratorTarget(target);
if(cmLinkInterface const* iface = if(cmLinkInterface const* iface =
gtgt->GetLinkInterface(this->Config, this->Target->Target)) target->GetLinkInterface(this->Config, this->Target))
{ {
if(iface->Multiplicity > count) if(iface->Multiplicity > count)
{ {

View File

@ -23,7 +23,6 @@ class cmComputeComponentGraph;
class cmGlobalGenerator; class cmGlobalGenerator;
class cmMakefile; class cmMakefile;
class cmGeneratorTarget; class cmGeneratorTarget;
class cmTarget;
class cmake; class cmake;
/** \class cmComputeLinkDepends /** \class cmComputeLinkDepends
@ -40,7 +39,7 @@ public:
struct LinkEntry struct LinkEntry
{ {
std::string Item; std::string Item;
cmTarget const* Target; cmGeneratorTarget const* Target;
bool IsSharedDep; bool IsSharedDep;
bool IsFlag; bool IsFlag;
LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {} LinkEntry(): Item(), Target(0), IsSharedDep(false), IsFlag(false) {}

View File

@ -632,11 +632,11 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmComputeLinkInformation::AddItem(std::string const& item, void cmComputeLinkInformation::AddItem(std::string const& item,
cmTarget const* tgt) cmGeneratorTarget const* tgt)
{ {
// Compute the proper name to use to link this library. // Compute the proper name to use to link this library.
const std::string& config = this->Config; const std::string& config = this->Config;
bool impexe = (tgt && tgt->IsExecutableWithExports()); bool impexe = (tgt && tgt->Target->IsExecutableWithExports());
if(impexe && !this->UseImportLibrary && !this->LoaderFlag) if(impexe && !this->UseImportLibrary && !this->LoaderFlag)
{ {
// Skip linking to executables on platforms with no import // Skip linking to executables on platforms with no import
@ -644,9 +644,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
return; return;
} }
if(tgt && tgt->IsLinkable()) if(tgt && tgt->Target->IsLinkable())
{ {
cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt);
// This is a CMake target. Ask the target for its real name. // This is a CMake target. Ask the target for its real name.
if(impexe && this->LoaderFlag) if(impexe && this->LoaderFlag)
{ {
@ -656,10 +655,10 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
std::string linkItem; std::string linkItem;
linkItem = this->LoaderFlag; linkItem = this->LoaderFlag;
std::string exe = gtgt->GetFullPath(config, this->UseImportLibrary, std::string exe = tgt->GetFullPath(config, this->UseImportLibrary,
true); true);
linkItem += exe; linkItem += exe;
this->Items.push_back(Item(linkItem, true, tgt)); this->Items.push_back(Item(linkItem, true, tgt->Target));
this->Depends.push_back(exe); this->Depends.push_back(exe);
} }
else if(tgt->GetType() == cmTarget::INTERFACE_LIBRARY) else if(tgt->GetType() == cmTarget::INTERFACE_LIBRARY)
@ -667,7 +666,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
// Add the interface library as an item so it can be considered as part // Add the interface library as an item so it can be considered as part
// of COMPATIBLE_INTERFACE_ enforcement. The generators will ignore // of COMPATIBLE_INTERFACE_ enforcement. The generators will ignore
// this for the actual link line. // this for the actual link line.
this->Items.push_back(Item(std::string(), true, tgt)); this->Items.push_back(Item(std::string(), true, tgt->Target));
} }
else else
{ {
@ -677,15 +676,15 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
(impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY)); (impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
// Pass the full path to the target file. // Pass the full path to the target file.
std::string lib = gtgt->GetFullPath(config, implib, true); std::string lib = tgt->GetFullPath(config, implib, true);
if(!this->LinkDependsNoShared || if(!this->LinkDependsNoShared ||
tgt->GetType() != cmTarget::SHARED_LIBRARY) tgt->GetType() != cmTarget::SHARED_LIBRARY)
{ {
this->Depends.push_back(lib); this->Depends.push_back(lib);
} }
this->AddTargetItem(lib, tgt); this->AddTargetItem(lib, tgt->Target);
this->AddLibraryRuntimeInfo(lib, tgt); this->AddLibraryRuntimeInfo(lib, tgt->Target);
} }
} }
else else
@ -716,7 +715,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmComputeLinkInformation::AddSharedDepItem(std::string const& item, void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
cmTarget const* tgt) const cmGeneratorTarget* tgt)
{ {
// If dropping shared library dependencies, ignore them. // If dropping shared library dependencies, ignore them.
if(this->SharedDependencyMode == SharedDepModeNone) if(this->SharedDependencyMode == SharedDepModeNone)
@ -760,18 +759,14 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
return; return;
} }
cmGeneratorTarget *gtgt = 0;
// Get a full path to the dependent shared library. // Get a full path to the dependent shared library.
// Add it to the runtime path computation so that the target being // Add it to the runtime path computation so that the target being
// linked will be able to find it. // linked will be able to find it.
std::string lib; std::string lib;
if(tgt) if(tgt)
{ {
gtgt = this->GlobalGenerator->GetGeneratorTarget(tgt); lib = tgt->GetFullPath(this->Config, this->UseImportLibrary);
this->AddLibraryRuntimeInfo(lib, tgt->Target);
lib = gtgt->GetFullPath(this->Config, this->UseImportLibrary);
this->AddLibraryRuntimeInfo(lib, tgt);
} }
else else
{ {
@ -795,9 +790,9 @@ void cmComputeLinkInformation::AddSharedDepItem(std::string const& item,
} }
if(order) if(order)
{ {
if(gtgt) if(tgt)
{ {
std::string soName = gtgt->GetSOName(this->Config); std::string soName = tgt->GetSOName(this->Config);
const char* soname = soName.empty()? 0 : soName.c_str(); const char* soname = soName.empty()? 0 : soName.c_str();
order->AddRuntimeLibrary(lib, soname); order->AddRuntimeLibrary(lib, soname);
} }
@ -1101,9 +1096,10 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item,
this->SharedLibrariesLinked.insert(target); this->SharedLibrariesLinked.insert(target);
} }
cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
// Handle case of an imported shared library with no soname. // Handle case of an imported shared library with no soname.
if(this->NoSONameUsesPath && if(this->NoSONameUsesPath &&
target->IsImportedSharedLibWithoutSOName(this->Config)) gtgt->IsImportedSharedLibWithoutSOName(this->Config))
{ {
this->AddSharedLibNoSOName(item); this->AddSharedLibNoSOName(item);
return; return;
@ -1783,12 +1779,13 @@ void
cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath, cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
cmTarget const* target) cmTarget const* target)
{ {
cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
// Ignore targets on Apple where install_name is not @rpath. // Ignore targets on Apple where install_name is not @rpath.
// The dependenty library can be found with other means such as // The dependenty library can be found with other means such as
// @loader_path or full paths. // @loader_path or full paths.
if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) if(this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME"))
{ {
if(!target->HasMacOSXRpathInstallNameDir(this->Config)) if(!gtgt->HasMacOSXRpathInstallNameDir(this->Config))
{ {
return; return;
} }
@ -1810,7 +1807,6 @@ cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath,
// Try to get the soname of the library. Only files with this name // Try to get the soname of the library. Only files with this name
// could possibly conflict. // could possibly conflict.
cmGeneratorTarget *gtgt = this->GlobalGenerator->GetGeneratorTarget(target);
std::string soName = gtgt->GetSOName(this->Config); std::string soName = gtgt->GetSOName(this->Config);
const char* soname = soName.empty()? 0 : soName.c_str(); const char* soname = soName.empty()? 0 : soName.c_str();
@ -1920,7 +1916,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
(for_install || (for_install ||
this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")); this->Target->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH"));
bool use_install_rpath = bool use_install_rpath =
(outputRuntime && this->Target->Target->HaveInstallTreeRPATH() && (outputRuntime && this->Target->HaveInstallTreeRPATH() &&
linking_for_install); linking_for_install);
bool use_build_rpath = bool use_build_rpath =
(outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) && (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) &&

View File

@ -62,8 +62,8 @@ public:
std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; } std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
std::string GetRPathLinkString(); std::string GetRPathLinkString();
private: private:
void AddItem(std::string const& item, cmTarget const* tgt); void AddItem(std::string const& item, const cmGeneratorTarget* tgt);
void AddSharedDepItem(std::string const& item, cmTarget const* tgt); void AddSharedDepItem(std::string const& item, cmGeneratorTarget const* tgt);
// Output information. // Output information.
ItemVector Items; ItemVector Items;

View File

@ -297,7 +297,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index,
cmGeneratorTarget const* depender = this->Targets[depender_index]; cmGeneratorTarget const* depender = this->Targets[depender_index];
if(cmLinkInterface const* iface = if(cmLinkInterface const* iface =
dependee->GetLinkInterface(config, dependee->GetLinkInterface(config,
depender->Target)) depender))
{ {
for(std::vector<cmLinkItem>::const_iterator for(std::vector<cmLinkItem>::const_iterator
lib = iface->Libraries.begin(); lib = iface->Libraries.begin();

View File

@ -803,7 +803,7 @@ cmExportFileGenerator
{ {
// Add the transitive link dependencies for this configuration. // Add the transitive link dependencies for this configuration.
cmLinkInterface const* iface = target->GetLinkInterface(config, cmLinkInterface const* iface = target->GetLinkInterface(config,
target->Target); target);
if (!iface) if (!iface)
{ {
return; return;
@ -915,7 +915,7 @@ cmExportFileGenerator
// Add the transitive link dependencies for this configuration. // Add the transitive link dependencies for this configuration.
if(cmLinkInterface const* iface = if(cmLinkInterface const* iface =
target->GetLinkInterface(config, target->Target)) target->GetLinkInterface(config, target))
{ {
this->SetImportLinkProperty(suffix, target, this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LANGUAGES", "IMPORTED_LINK_INTERFACE_LANGUAGES",

View File

@ -1109,8 +1109,11 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if(isInterfaceProperty) if(isInterfaceProperty)
{ {
cmGeneratorTarget* gHeadTarget =
context->Makefile->GetGlobalGenerator()
->GetGeneratorTarget(headTarget);
if(cmLinkInterfaceLibraries const* iface = if(cmLinkInterfaceLibraries const* iface =
gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true)) gtgt->GetLinkInterfaceLibraries(context->Config, gHeadTarget, true))
{ {
linkedTargetsContent = linkedTargetsContent =
getLinkedTargetsContent(iface->Libraries, target, getLinkedTargetsContent(iface->Libraries, target,
@ -1122,7 +1125,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
else if(!interfacePropertyName.empty()) else if(!interfacePropertyName.empty())
{ {
if(cmLinkImplementationLibraries const* impl = if(cmLinkImplementationLibraries const* impl =
target->GetLinkImplementationLibraries(context->Config)) gtgt->GetLinkImplementationLibraries(context->Config))
{ {
linkedTargetsContent = linkedTargetsContent =
getLinkedTargetsContent(impl->Libraries, target, getLinkedTargetsContent(impl->Libraries, target,
@ -1586,7 +1589,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
"SHARED libraries."); "SHARED libraries.");
return std::string(); return std::string();
} }
std::string result = target->Target->GetDirectory(context->Config); std::string result = target->GetDirectory(context->Config);
result += "/"; result += "/";
result += target->GetSOName(context->Config); result += target->GetSOName(context->Config);
return result; return result;
@ -1631,7 +1634,7 @@ struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
return std::string(); return std::string();
} }
std::string result = target->Target->GetPDBDirectory(context->Config); std::string result = target->GetPDBDirectory(context->Config);
result += "/"; result += "/";
result += target->GetPDBName(context->Config); result += target->GetPDBName(context->Config);
return result; return result;

File diff suppressed because it is too large Load Diff

View File

@ -109,19 +109,19 @@ public:
const std::string& config) const; const std::string& config) const;
cmLinkInterface const* GetLinkInterface(const std::string& config, cmLinkInterface const* GetLinkInterface(const std::string& config,
cmTarget const* headTarget) const; const cmGeneratorTarget* headTarget) const;
void ComputeLinkInterface(const std::string& config, void ComputeLinkInterface(const std::string& config,
cmOptionalLinkInterface& iface, cmOptionalLinkInterface& iface,
cmTarget const* head) const; const cmGeneratorTarget* head) const;
cmLinkInterfaceLibraries const* cmLinkInterfaceLibraries const*
GetLinkInterfaceLibraries(const std::string& config, GetLinkInterfaceLibraries(const std::string& config,
cmTarget const* headTarget, const cmGeneratorTarget* headTarget,
bool usage_requirements_only) const; bool usage_requirements_only) const;
void ComputeLinkInterfaceLibraries(const std::string& config, void ComputeLinkInterfaceLibraries(const std::string& config,
cmOptionalLinkInterface &iface, cmOptionalLinkInterface &iface,
cmTarget const* head, const cmGeneratorTarget* head,
bool usage_requirements_only) const; bool usage_requirements_only) const;
/** Get the full path to the target according to the settings in its /** Get the full path to the target according to the settings in its
@ -207,6 +207,13 @@ public:
cmOptionalLinkImplementation& impl cmOptionalLinkImplementation& impl
) const; ) const;
cmLinkImplementationLibraries const*
GetLinkImplementationLibraries(const std::string& config) const;
void ComputeLinkImplementationLibraries(const std::string& config,
cmOptionalLinkImplementation& impl,
const cmGeneratorTarget* head) const;
// Compute the set of languages compiled by the target. This is // Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change // computed every time it is called because the languages can change
// when source file properties are changed and we do not have enough // when source file properties are changed and we do not have enough
@ -261,6 +268,13 @@ public:
*/ */
void TraceDependencies(); void TraceDependencies();
/** Get the directory in which this target will be built. If the
configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
output directory is given. */
std::string GetDirectory(const std::string& config = "",
bool implib = false) const;
/** Get the directory in which to place the target compiler .pdb file. /** Get the directory in which to place the target compiler .pdb file.
If the configuration name is given then the generator will add its If the configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical subdirectory for that configuration. Otherwise just the canonical
@ -271,6 +285,22 @@ public:
std::vector<cmSourceFile*> const* std::vector<cmSourceFile*> const*
GetSourceDepends(cmSourceFile const* sf) const; GetSourceDepends(cmSourceFile const* sf) const;
/** Return whether this target uses the default value for its output
directory. */
bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
// Cache target output paths for each configuration.
struct OutputInfo
{
std::string OutDir;
std::string ImpDir;
std::string PdbDir;
bool empty() const
{ return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
};
OutputInfo const* GetOutputInfo(const std::string& config) const;
/** Get the name of the pdb file for the target. */ /** Get the name of the pdb file for the target. */
std::string GetPDBName(const std::string& config="") const; std::string GetPDBName(const std::string& config="") const;
@ -287,6 +317,8 @@ public:
typedef std::map<std::string, CompileInfo> CompileInfoMapType; typedef std::map<std::string, CompileInfo> CompileInfoMapType;
mutable CompileInfoMapType CompileInfoMap; mutable CompileInfoMapType CompileInfoMap;
bool IsNullImpliedByLinkLibraries(const std::string &p) const;
/** Get the name of the compiler pdb file for the target. */ /** Get the name of the compiler pdb file for the target. */
std::string GetCompilePDBName(const std::string& config="") const; std::string GetCompilePDBName(const std::string& config="") const;
@ -345,6 +377,12 @@ public:
/** Return true if builtin chrpath will work for this target */ /** Return true if builtin chrpath will work for this target */
bool IsChrpathUsed(const std::string& config) const; bool IsChrpathUsed(const std::string& config) const;
/** Get the directory in which this targets .pdb files will be placed.
If the configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
pdb output directory is given. */
std::string GetPDBDirectory(const std::string& config) const;
///! Return the preferred linker language for this target ///! Return the preferred linker language for this target
std::string GetLinkerLanguage(const std::string& config = "") const; std::string GetLinkerLanguage(const std::string& config = "") const;
@ -369,6 +407,18 @@ public:
class TargetPropertyEntry; class TargetPropertyEntry;
bool HaveInstallTreeRPATH() const;
/** Whether this library has \@rpath and platform supports it. */
bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
/** Whether this library defaults to \@rpath. */
bool MacOSXRpathInstallNameDirDefault() const;
/** Test for special case of a third-party shared library that has
no soname at all. */
bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
private: private:
friend class cmTargetTraceDependencies; friend class cmTargetTraceDependencies;
struct SourceEntry { std::vector<cmSourceFile*> Depends; }; struct SourceEntry { std::vector<cmSourceFile*> Depends; };
@ -393,6 +443,9 @@ private:
typedef std::map<std::string, LinkClosure> LinkClosureMapType; typedef std::map<std::string, LinkClosure> LinkClosureMapType;
mutable LinkClosureMapType LinkClosureMap; mutable LinkClosureMapType LinkClosureMap;
// Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
const char* GetOutputTargetType(bool implib) const;
struct CompatibleInterfacesBase struct CompatibleInterfacesBase
{ {
std::set<std::string> PropsBool; std::set<std::string> PropsBool;
@ -438,7 +491,8 @@ private:
std::string const& config) const; std::string const& config) const;
cmLinkInterface const* cmLinkInterface const*
GetImportLinkInterface(const std::string& config, cmTarget const* head, GetImportLinkInterface(const std::string& config,
const cmGeneratorTarget* head,
bool usage_requirements_only) const; bool usage_requirements_only) const;
typedef std::map<std::string, std::vector<cmSourceFile*> > typedef std::map<std::string, std::vector<cmSourceFile*> >
@ -450,9 +504,11 @@ private:
std::vector<TargetPropertyEntry*> CompileFeaturesEntries; std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries; std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
std::vector<TargetPropertyEntry*> SourceEntries; std::vector<TargetPropertyEntry*> SourceEntries;
mutable std::set<std::string> LinkImplicitNullProperties;
void ExpandLinkItems(std::string const& prop, std::string const& value, void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config, cmTarget const* headTarget, std::string const& config,
const cmGeneratorTarget* headTarget,
bool usage_requirements_only, bool usage_requirements_only,
std::vector<cmLinkItem>& items, std::vector<cmLinkItem>& items,
bool& hadHeadSensitiveCondition) const; bool& hadHeadSensitiveCondition) const;
@ -462,6 +518,22 @@ private:
void GetSourceFiles(std::vector<std::string>& files, void GetSourceFiles(std::vector<std::string>& files,
const std::string& config) const; const std::string& config) const;
struct HeadToLinkImplementationMap:
public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
typedef std::map<std::string,
HeadToLinkImplementationMap> LinkImplMapType;
mutable LinkImplMapType LinkImplMap;
cmLinkImplementationLibraries const*
GetLinkImplementationLibrariesInternal(const std::string& config,
const cmGeneratorTarget* head) const;
bool
ComputeOutputDir(const std::string& config,
bool implib, std::string& out) const;
typedef std::map<std::string, OutputInfo> OutputInfoMapType;
mutable OutputInfoMapType OutputInfoMap;
typedef std::pair<std::string, bool> OutputNameKey; typedef std::pair<std::string, bool> OutputNameKey;
typedef std::map<OutputNameKey, std::string> OutputNameMapType; typedef std::map<OutputNameKey, std::string> OutputNameMapType;
mutable OutputNameMapType OutputNameMap; mutable OutputNameMapType OutputNameMap;
@ -473,10 +545,19 @@ private:
mutable bool DebugSourcesDone; mutable bool DebugSourcesDone;
mutable bool LinkImplementationLanguageIsContextDependent; mutable bool LinkImplementationLanguageIsContextDependent;
bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
std::string& out) const;
public: public:
std::vector<cmTarget const*> const& std::vector<cmTarget const*> const&
GetLinkImplementationClosure(const std::string& config) const; GetLinkImplementationClosure(const std::string& config) const;
mutable std::map<std::string, std::string> MaxLanguageStandards;
std::map<std::string, std::string> const&
GetMaxLanguageStandards() const
{
return this->MaxLanguageStandards;
}
}; };
struct cmStrictTargetComparison { struct cmStrictTargetComparison {

View File

@ -1976,9 +1976,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{ {
if(this->XcodeVersion >= 21) if(this->XcodeVersion >= 21)
{ {
if(!target.UsesDefaultOutputDir(configName, false)) if(!gtgt->UsesDefaultOutputDir(configName, false))
{ {
std::string pncdir = target.GetDirectory(configName); std::string pncdir = gtgt->GetDirectory(configName);
buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR", buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
this->CreateString(pncdir.c_str())); this->CreateString(pncdir.c_str()));
} }
@ -1987,7 +1987,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
{ {
buildSettings->AddAttribute("OBJROOT", buildSettings->AddAttribute("OBJROOT",
this->CreateString(pndir.c_str())); this->CreateString(pndir.c_str()));
pndir = target.GetDirectory(configName); pndir = gtgt->GetDirectory(configName);
} }
if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple()) if(target.IsFrameworkOnApple() || target.IsCFBundleOnApple())

View File

@ -83,7 +83,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
else else
{ {
fromDirConfig = fromDirConfig =
this->Target->Target->GetDirectory(config, this->ImportLibrary); this->Target->GetDirectory(config, this->ImportLibrary);
fromDirConfig += "/"; fromDirConfig += "/";
} }
std::string toDir = std::string toDir =

View File

@ -111,13 +111,4 @@ struct cmListFile
std::vector<cmListFileFunction> Functions; std::vector<cmListFileFunction> Functions;
}; };
struct cmValueWithOrigin {
cmValueWithOrigin(const std::string &value,
const cmListFileBacktrace &bt)
: Value(value), Backtrace(bt)
{}
std::string Value;
cmListFileBacktrace Backtrace;
};
#endif #endif

View File

@ -1152,8 +1152,8 @@ void cmLocalGenerator::AddCompileOptions(
} }
for(std::map<std::string, std::string>::const_iterator it for(std::map<std::string, std::string>::const_iterator it
= target->GetMaxLanguageStandards().begin(); = gtgt->GetMaxLanguageStandards().begin();
it != target->GetMaxLanguageStandards().end(); ++it) it != gtgt->GetMaxLanguageStandards().end(); ++it)
{ {
const char* standard = target->GetProperty(it->first + "_STANDARD"); const char* standard = target->GetProperty(it->first + "_STANDARD");
if(!standard) if(!standard)

View File

@ -805,7 +805,11 @@ cmLocalVisualStudio6Generator::MaybeCreateOutputDir(cmTarget& target,
// VS6 forgets to create the output directory for archives if it // VS6 forgets to create the output directory for archives if it
// differs from the intermediate directory. // differs from the intermediate directory.
if(target.GetType() != cmTarget::STATIC_LIBRARY) { return pcc; } if(target.GetType() != cmTarget::STATIC_LIBRARY) { return pcc; }
std::string outDir = target.GetDirectory(config, false);
cmGeneratorTarget* gt =
this->GlobalGenerator->GetGeneratorTarget(&target);
std::string outDir = gt->GetDirectory(config, false);
// Add a pre-link event to create the directory. // Add a pre-link event to create the directory.
cmCustomCommandLine command; cmCustomCommandLine command;
@ -1363,20 +1367,20 @@ void cmLocalVisualStudio6Generator
#ifdef CM_USE_OLD_VS6 #ifdef CM_USE_OLD_VS6
outputDirOld = outputDirOld =
removeQuotes(this->ConvertToOutputFormat removeQuotes(this->ConvertToOutputFormat
(target.GetDirectory().c_str(), SHELL)); (gt->GetDirectory().c_str(), SHELL));
#endif #endif
outputDirDebug = outputDirDebug =
removeQuotes(this->ConvertToOutputFormat( removeQuotes(this->ConvertToOutputFormat(
target.GetDirectory("Debug").c_str(), SHELL)); gt->GetDirectory("Debug").c_str(), SHELL));
outputDirRelease = outputDirRelease =
removeQuotes(this->ConvertToOutputFormat( removeQuotes(this->ConvertToOutputFormat(
target.GetDirectory("Release").c_str(), SHELL)); gt->GetDirectory("Release").c_str(), SHELL));
outputDirMinSizeRel = outputDirMinSizeRel =
removeQuotes(this->ConvertToOutputFormat( removeQuotes(this->ConvertToOutputFormat(
target.GetDirectory("MinSizeRel").c_str(), SHELL)); gt->GetDirectory("MinSizeRel").c_str(), SHELL));
outputDirRelWithDebInfo = outputDirRelWithDebInfo =
removeQuotes(this->ConvertToOutputFormat( removeQuotes(this->ConvertToOutputFormat(
target.GetDirectory("RelWithDebInfo").c_str(), SHELL)); gt->GetDirectory("RelWithDebInfo").c_str(), SHELL));
} }
else if(target.GetType() == cmTarget::OBJECT_LIBRARY) else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
{ {
@ -1424,12 +1428,12 @@ void cmLocalVisualStudio6Generator
target.GetType() == cmTarget::MODULE_LIBRARY || target.GetType() == cmTarget::MODULE_LIBRARY ||
target.GetType() == cmTarget::EXECUTABLE) target.GetType() == cmTarget::EXECUTABLE)
{ {
std::string fullPathImpDebug = target.GetDirectory("Debug", true); std::string fullPathImpDebug = gt->GetDirectory("Debug", true);
std::string fullPathImpRelease = target.GetDirectory("Release", true); std::string fullPathImpRelease = gt->GetDirectory("Release", true);
std::string fullPathImpMinSizeRel = std::string fullPathImpMinSizeRel =
target.GetDirectory("MinSizeRel", true); gt->GetDirectory("MinSizeRel", true);
std::string fullPathImpRelWithDebInfo = std::string fullPathImpRelWithDebInfo =
target.GetDirectory("RelWithDebInfo", true); gt->GetDirectory("RelWithDebInfo", true);
fullPathImpDebug += "/"; fullPathImpDebug += "/";
fullPathImpRelease += "/"; fullPathImpRelease += "/";
fullPathImpMinSizeRel += "/"; fullPathImpMinSizeRel += "/";

View File

@ -792,7 +792,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
{ {
std::string const& outDir = std::string const& outDir =
target.GetType() == cmTarget::OBJECT_LIBRARY? target.GetType() == cmTarget::OBJECT_LIBRARY?
intermediateDir : target.GetDirectory(configName); intermediateDir : gt->GetDirectory(configName);
fout << "\t\t\tOutputDirectory=\"" fout << "\t\t\tOutputDirectory=\""
<< this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n"; << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
} }
@ -1004,7 +1004,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
// Check if we need the FAT32 workaround. // Check if we need the FAT32 workaround.
// Check the filesystem type where the target will be written. // Check the filesystem type where the target will be written.
if (cmLVS6G_IsFAT(target.GetDirectory(configName).c_str())) if (cmLVS6G_IsFAT(gt->GetDirectory(configName).c_str()))
{ {
// Add a flag telling the manifest tool to use a workaround // Add a flag telling the manifest tool to use a workaround
// for FAT32 file systems, which can cause an empty manifest // for FAT32 file systems, which can cause an empty manifest
@ -1130,7 +1130,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
case cmTarget::STATIC_LIBRARY: case cmTarget::STATIC_LIBRARY:
{ {
std::string targetNameFull = gt->GetFullName(configName); std::string targetNameFull = gt->GetFullName(configName);
std::string libpath = target.GetDirectory(configName); std::string libpath = gt->GetDirectory(configName);
libpath += "/"; libpath += "/";
libpath += targetNameFull; libpath += targetNameFull;
const char* tool = "VCLibrarianTool"; const char* tool = "VCLibrarianTool";
@ -1210,7 +1210,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << " "; fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems()); this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n"; fout << "\"\n";
temp = target.GetDirectory(configName); temp = gt->GetDirectory(configName);
temp += "/"; temp += "/";
temp += targetNameFull; temp += targetNameFull;
fout << "\t\t\t\tOutputFile=\"" fout << "\t\t\t\tOutputFile=\""
@ -1220,7 +1220,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tAdditionalLibraryDirectories=\""; fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories()); this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n"; fout << "\"\n";
temp = target.GetPDBDirectory(configName); temp = gt->GetPDBDirectory(configName);
temp += "/"; temp += "/";
temp += targetNamePDB; temp += targetNamePDB;
fout << "\t\t\t\tProgramDatabaseFile=\"" << fout << "\t\t\t\tProgramDatabaseFile=\"" <<
@ -1248,7 +1248,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{ {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n"; fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
} }
temp = target.GetDirectory(configName, true); temp = gt->GetDirectory(configName, true);
temp += "/"; temp += "/";
temp += targetNameImport; temp += targetNameImport;
fout << "\t\t\t\tImportLibrary=\"" fout << "\t\t\t\tImportLibrary=\""
@ -1309,7 +1309,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << " "; fout << " ";
this->Internal->OutputLibraries(fout, cli.GetItems()); this->Internal->OutputLibraries(fout, cli.GetItems());
fout << "\"\n"; fout << "\"\n";
temp = target.GetDirectory(configName); temp = gt->GetDirectory(configName);
temp += "/"; temp += "/";
temp += targetNameFull; temp += targetNameFull;
fout << "\t\t\t\tOutputFile=\"" fout << "\t\t\t\tOutputFile=\""
@ -1320,7 +1320,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
this->OutputLibraryDirectories(fout, cli.GetDirectories()); this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n"; fout << "\"\n";
std::string path = this->ConvertToXMLOutputPathSingle( std::string path = this->ConvertToXMLOutputPathSingle(
target.GetPDBDirectory(configName).c_str()); gt->GetPDBDirectory(configName).c_str());
fout << "\t\t\t\tProgramDatabaseFile=\"" fout << "\t\t\t\tProgramDatabaseFile=\""
<< path << "/" << targetNamePDB << path << "/" << targetNamePDB
<< "\"\n"; << "\"\n";
@ -1367,7 +1367,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
{ {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\""; fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
} }
temp = target.GetDirectory(configName, true); temp = gt->GetDirectory(configName, true);
temp += "/"; temp += "/";
temp += targetNameImport; temp += targetNameImport;
fout << "\t\t\t\tImportLibrary=\"" fout << "\t\t\t\tImportLibrary=\""

View File

@ -92,8 +92,10 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
if(target.GetType() != cmTarget::EXECUTABLE && if(target.GetType() != cmTarget::EXECUTABLE &&
!(isFortran && target.GetType() == cmTarget::SHARED_LIBRARY)) !(isFortran && target.GetType() == cmTarget::SHARED_LIBRARY))
{ return pcc; } { return pcc; }
std::string outDir = target.GetDirectory(config, false); cmGeneratorTarget* gt =
std::string impDir = target.GetDirectory(config, true); this->GetGlobalGenerator()->GetGeneratorTarget(&target);
std::string outDir = gt->GetDirectory(config, false);
std::string impDir = gt->GetDirectory(config, true);
if(impDir == outDir) { return pcc; } if(impDir == outDir) { return pcc; }
// Add a pre-build event to create the directory. // Add a pre-build event to create the directory.

View File

@ -56,7 +56,8 @@ void cmLocalXCodeGenerator::Generate()
iter != targets.end(); ++iter) iter != targets.end(); ++iter)
{ {
cmTarget* t = &iter->second; cmTarget* t = &iter->second;
t->HasMacOSXRpathInstallNameDir(""); cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(t);
gt->HasMacOSXRpathInstallNameDir("");
} }
} }
@ -70,7 +71,8 @@ void cmLocalXCodeGenerator::GenerateInstallRules()
iter != targets.end(); ++iter) iter != targets.end(); ++iter)
{ {
cmTarget* t = &iter->second; cmTarget* t = &iter->second;
t->HasMacOSXRpathInstallNameDir(""); cmGeneratorTarget* gt = this->GlobalGenerator->GetGeneratorTarget(t);
gt->HasMacOSXRpathInstallNameDir("");
} }
} }

View File

@ -99,7 +99,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->ConfigName); this->ConfigName);
// Construct the full path version of the names. // Construct the full path version of the names.
std::string outpath = this->Target->GetDirectory(this->ConfigName); std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
if(this->Target->IsAppBundleOnApple()) if(this->Target->IsAppBundleOnApple())
{ {
this->OSXBundleGenerator->CreateAppBundle(targetName, outpath); this->OSXBundleGenerator->CreateAppBundle(targetName, outpath);
@ -123,7 +123,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmSystemTools::MakeDirectory(outpath.c_str()); cmSystemTools::MakeDirectory(outpath.c_str());
if(!targetNameImport.empty()) if(!targetNameImport.empty())
{ {
outpathImp = this->Target->GetDirectory(this->ConfigName, true); outpathImp = this->GeneratorTarget->GetDirectory(this->ConfigName, true);
cmSystemTools::MakeDirectory(outpathImp.c_str()); cmSystemTools::MakeDirectory(outpathImp.c_str());
outpathImp += "/"; outpathImp += "/";
} }
@ -133,7 +133,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName); this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str()); cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName); std::string pdbOutputPath =
this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
pdbOutputPath += "/"; pdbOutputPath += "/";

View File

@ -275,13 +275,13 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
std::string outpathImp; std::string outpathImp;
if(this->Target->IsFrameworkOnApple()) if(this->Target->IsFrameworkOnApple())
{ {
outpath = this->Target->GetDirectory(this->ConfigName); outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
this->OSXBundleGenerator->CreateFramework(targetName, outpath); this->OSXBundleGenerator->CreateFramework(targetName, outpath);
outpath += "/"; outpath += "/";
} }
else if(this->Target->IsCFBundleOnApple()) else if(this->Target->IsCFBundleOnApple())
{ {
outpath = this->Target->GetDirectory(this->ConfigName); outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
this->OSXBundleGenerator->CreateCFBundle(targetName, outpath); this->OSXBundleGenerator->CreateCFBundle(targetName, outpath);
outpath += "/"; outpath += "/";
} }
@ -299,12 +299,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
} }
else else
{ {
outpath = this->Target->GetDirectory(this->ConfigName); outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(outpath.c_str()); cmSystemTools::MakeDirectory(outpath.c_str());
outpath += "/"; outpath += "/";
if(!targetNameImport.empty()) if(!targetNameImport.empty())
{ {
outpathImp = this->Target->GetDirectory(this->ConfigName, true); outpathImp = this->GeneratorTarget->GetDirectory(this->ConfigName, true);
cmSystemTools::MakeDirectory(outpathImp.c_str()); cmSystemTools::MakeDirectory(outpathImp.c_str());
outpathImp += "/"; outpathImp += "/";
} }
@ -314,7 +314,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules
this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName); this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str()); cmSystemTools::MakeDirectory(compilePdbOutputPath.c_str());
std::string pdbOutputPath = this->Target->GetPDBDirectory(this->ConfigName); std::string pdbOutputPath =
this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
cmSystemTools::MakeDirectory(pdbOutputPath.c_str()); cmSystemTools::MakeDirectory(pdbOutputPath.c_str());
pdbOutputPath += "/"; pdbOutputPath += "/";

View File

@ -546,7 +546,8 @@ cmMakefileTargetGenerator
{ {
targetFullPathReal = targetFullPathReal =
this->GeneratorTarget->GetFullPath(this->ConfigName, false, true); this->GeneratorTarget->GetFullPath(this->ConfigName, false, true);
targetFullPathPDB = this->Target->GetPDBDirectory(this->ConfigName); targetFullPathPDB =
this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
targetFullPathPDB += "/"; targetFullPathPDB += "/";
targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName); targetFullPathPDB += this->GeneratorTarget->GetPDBName(this->ConfigName);
} }

View File

@ -59,7 +59,7 @@ cmNinjaNormalTargetGenerator(cmGeneratorTarget* target)
{ {
// on Windows the output dir is already needed at compile time // on Windows the output dir is already needed at compile time
// ensure the directory exists (OutDir test) // ensure the directory exists (OutDir test)
EnsureDirectoryExists(target->Target->GetDirectory(this->GetConfigName())); EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
} }
this->OSXBundleGenerator = new cmOSXBundleGenerator(target, this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
@ -413,7 +413,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
if (target.IsAppBundleOnApple()) if (target.IsAppBundleOnApple())
{ {
// Create the app bundle // Create the app bundle
std::string outpath = target.GetDirectory(cfgName); std::string outpath = gt.GetDirectory(cfgName);
this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath); this->OSXBundleGenerator->CreateAppBundle(this->TargetNameOut, outpath);
// Calculate the output path // Calculate the output path
@ -430,13 +430,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
{ {
// Create the library framework. // Create the library framework.
this->OSXBundleGenerator->CreateFramework(this->TargetNameOut, this->OSXBundleGenerator->CreateFramework(this->TargetNameOut,
target.GetDirectory(cfgName)); gt.GetDirectory(cfgName));
} }
else if(target.IsCFBundleOnApple()) else if(target.IsCFBundleOnApple())
{ {
// Create the core foundation bundle. // Create the core foundation bundle.
this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut, this->OSXBundleGenerator->CreateCFBundle(this->TargetNameOut,
target.GetDirectory(cfgName)); gt.GetDirectory(cfgName));
} }
// Write comments. // Write comments.

View File

@ -253,7 +253,7 @@ cmNinjaTargetGenerator
std::string cmNinjaTargetGenerator::GetTargetOutputDir() const std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
{ {
std::string dir = this->Target->GetDirectory(this->GetConfigName()); std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
return ConvertToNinjaPath(dir); return ConvertToNinjaPath(dir);
} }
@ -288,7 +288,7 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
this->Target->GetType() == cmTarget::SHARED_LIBRARY || this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
this->Target->GetType() == cmTarget::MODULE_LIBRARY) this->Target->GetType() == cmTarget::MODULE_LIBRARY)
{ {
pdbPath = this->Target->GetPDBDirectory(this->GetConfigName()); pdbPath = this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
pdbPath += "/"; pdbPath += "/";
pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName()); pdbPath += this->GeneratorTarget->GetPDBName(this->GetConfigName());
} }

View File

@ -60,16 +60,6 @@ const char* cmTarget::GetTargetTypeName(TargetType targetType)
return 0; return 0;
} }
//----------------------------------------------------------------------------
struct cmTarget::OutputInfo
{
std::string OutDir;
std::string ImpDir;
std::string PdbDir;
bool empty() const
{ return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
};
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
class cmTargetInternals class cmTargetInternals
{ {
@ -89,18 +79,9 @@ public:
// The backtrace when the target was created. // The backtrace when the target was created.
cmListFileBacktrace Backtrace; cmListFileBacktrace Backtrace;
typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType;
OutputInfoMapType OutputInfoMap;
typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType; typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType;
ImportInfoMapType ImportInfoMap; ImportInfoMapType ImportInfoMap;
struct HeadToLinkImplementationMap:
public std::map<cmTarget const*, cmOptionalLinkImplementation> {};
typedef std::map<std::string,
HeadToLinkImplementationMap> LinkImplMapType;
LinkImplMapType LinkImplMap;
std::set<cmLinkItem> UtilityItems; std::set<cmLinkItem> UtilityItems;
bool UtilityItemsDone; bool UtilityItemsDone;
@ -114,7 +95,8 @@ public:
std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces; std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
std::vector<std::string> SourceEntries; std::vector<std::string> SourceEntries;
std::vector<cmListFileBacktrace> SourceBacktraces; std::vector<cmListFileBacktrace> SourceBacktraces;
std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries; std::vector<std::string> LinkImplementationPropertyEntries;
std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
}; };
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -404,7 +386,6 @@ void cmTarget::FinishConfigure()
// on-demand during the configuration. This ensures that build // on-demand during the configuration. This ensures that build
// system generation uses up-to-date information even if other cache // system generation uses up-to-date information even if other cache
// invalidation code in this source file is buggy. // invalidation code in this source file is buggy.
this->ClearLinkMaps();
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
// Do old-style link dependency analysis only for CM_USE_OLD_VS6. // Do old-style link dependency analysis only for CM_USE_OLD_VS6.
@ -415,12 +396,6 @@ void cmTarget::FinishConfigure()
#endif #endif
} }
//----------------------------------------------------------------------------
void cmTarget::ClearLinkMaps()
{
this->Internal->LinkImplMap.clear();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmListFileBacktrace const& cmTarget::GetBacktrace() const cmListFileBacktrace const& cmTarget::GetBacktrace() const
{ {
@ -883,7 +858,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
this->LinkLibrariesForVS6.push_back( tmp ); this->LinkLibrariesForVS6.push_back( tmp );
#endif #endif
this->OriginalLinkLibraries.push_back(tmp); this->OriginalLinkLibraries.push_back(tmp);
this->ClearLinkMaps();
// Add the explicit dependency information for this target. This is // Add the explicit dependency information for this target. This is
// simply a set of libraries separated by ";". There should always // simply a set of libraries separated by ";". There should always
@ -982,6 +956,16 @@ cmBacktraceRange cmTarget::GetSourceBacktraces() const
return cmMakeRange(this->Internal->SourceBacktraces); return cmMakeRange(this->Internal->SourceBacktraces);
} }
cmStringRange cmTarget::GetLinkImplementationEntries() const
{
return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
}
cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
{
return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
}
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void
@ -1380,11 +1364,12 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
else if (prop == "LINK_LIBRARIES") else if (prop == "LINK_LIBRARIES")
{ {
this->Internal->LinkImplementationPropertyEntries.clear(); this->Internal->LinkImplementationPropertyEntries.clear();
this->Internal->LinkImplementationPropertyBacktraces.clear();
if (value) if (value)
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmValueWithOrigin entry(value, lfbt); this->Internal->LinkImplementationPropertyEntries.push_back(value);
this->Internal->LinkImplementationPropertyEntries.push_back(entry); this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
} }
} }
else if (prop == "SOURCES") else if (prop == "SOURCES")
@ -1482,8 +1467,8 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
if (value && *value) if (value && *value)
{ {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
cmValueWithOrigin entry(value, lfbt); this->Internal->LinkImplementationPropertyEntries.push_back(value);
this->Internal->LinkImplementationPropertyEntries.push_back(entry); this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
} }
} }
else if (prop == "SOURCES") else if (prop == "SOURCES")
@ -1609,10 +1594,6 @@ void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop)
{ {
this->Internal->ImportInfoMap.clear(); this->Internal->ImportInfoMap.clear();
} }
if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_"))
{
this->ClearLinkMaps();
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1725,97 +1706,6 @@ bool cmTarget::HaveWellDefinedOutputFiles() const
this->GetType() == cmTarget::EXECUTABLE; this->GetType() == cmTarget::EXECUTABLE;
} }
//----------------------------------------------------------------------------
cmTarget::OutputInfo const* cmTarget::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 = "cmTarget::GetOutputInfo called for ";
msg += this->GetName();
msg += " which has type ";
msg += cmTarget::GetTargetTypeName(this->GetType());
this->GetMakefile()->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);
}
typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType;
OutputInfoMapType::iterator i =
this->Internal->OutputInfoMap.find(config_upper);
if(i == this->Internal->OutputInfoMap.end())
{
// Add empty info in map to detect potential recursion.
OutputInfo info;
OutputInfoMapType::value_type entry(config_upper, info);
i = this->Internal->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->Makefile->GetCMakeInstance()->IssueMessage(
cmake::FATAL_ERROR,
"Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
this->GetBacktrace());
return 0;
}
return &i->second;
}
//----------------------------------------------------------------------------
std::string cmTarget::GetDirectory(const std::string& config,
bool implib) const
{
if (this->IsImported())
{
// Return the directory from which the target is imported.
return
cmSystemTools::GetFilenamePath(
this->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 "";
}
//----------------------------------------------------------------------------
std::string cmTarget::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 "";
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const char* cmTarget::ImportedGetLocation(const std::string& config) const const char* cmTarget::ImportedGetLocation(const std::string& config) const
{ {
@ -2048,17 +1938,7 @@ const char *cmTarget::GetProperty(const std::string& prop,
} }
static std::string output; static std::string output;
output = ""; output = cmJoin(this->Internal->LinkImplementationPropertyEntries, ";");
std::string sep;
for (std::vector<cmValueWithOrigin>::const_iterator
it = this->Internal->LinkImplementationPropertyEntries.begin(),
end = this->Internal->LinkImplementationPropertyEntries.end();
it != end; ++it)
{
output += sep;
output += it->Value;
sep = ";";
}
return output.c_str(); return output.c_str();
} }
// the type property returns what type the target is // the type property returns what type the target is
@ -2297,132 +2177,6 @@ const char* cmTarget::GetPrefixVariableInternal(bool implib) const
return ""; return "";
} }
//----------------------------------------------------------------------------
bool cmTarget::HasMacOSXRpathInstallNameDir(const std::string& config) const
{
bool install_name_is_rpath = false;
bool macosx_rpath = false;
if(!this->IsImportedTarget)
{
if(this->GetType() != cmTarget::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(cmTarget::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->Makefile->GetCMakeInstance();
cm->IssueMessage(cmake::FATAL_ERROR, w.str(), this->GetBacktrace());
}
return true;
}
//----------------------------------------------------------------------------
bool cmTarget::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->Makefile->GetGlobalGenerator()->
AddCMP0042WarnTarget(this->GetName());
}
if(cmp0042 == cmPolicies::NEW)
{
return true;
}
return false;
}
//----------------------------------------------------------------------------
bool cmTarget::IsImportedSharedLibWithoutSOName(
const std::string& config) const
{
if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY)
{
if(cmTarget::ImportInfo const* info = this->GetImportInfo(config))
{
return info->NoSOName;
}
}
return false;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string std::string
cmTarget::GetFullNameImported(const std::string& config, bool implib) const cmTarget::GetFullNameImported(const std::string& config, bool implib) const
@ -2503,233 +2257,6 @@ void cmTarget::SetPropertyDefault(const std::string& property,
} }
} }
//----------------------------------------------------------------------------
bool cmTarget::HaveInstallTreeRPATH() const
{
const char* install_rpath = this->GetProperty("INSTALL_RPATH");
return (install_rpath && *install_rpath) &&
!this->Makefile->IsOn("CMAKE_SKIP_INSTALL_RPATH");
}
//----------------------------------------------------------------------------
const char* cmTarget::GetOutputTargetType(bool implib) const
{
switch(this->GetType())
{
case cmTarget::SHARED_LIBRARY:
if(this->DLLPlatform)
{
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 cmTarget::STATIC_LIBRARY:
// Static libraries are always treated as archive targets.
return "ARCHIVE";
case cmTarget::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 cmTarget::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 "";
}
//----------------------------------------------------------------------------
bool cmTarget::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->Makefile, 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->Makefile, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
if (out != outdir)
{
conf = "";
}
}
else if(this->GetType() == cmTarget::EXECUTABLE)
{
// Lookup the output path for executables.
out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
}
else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
this->GetType() == cmTarget::SHARED_LIBRARY ||
this->GetType() == cmTarget::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->Makefile->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->Makefile->GetGlobalGenerator()->
AppendDirectoryForConfig("/", conf, suffix, out);
}
return usesDefaultOutputDir;
}
//----------------------------------------------------------------------------
bool cmTarget::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->Makefile->GetCurrentBinaryDirectory()));
// The generator may add the configuration's subdirectory.
if(!conf.empty())
{
this->Makefile->GetGlobalGenerator()->
AppendDirectoryForConfig("/", conf, "", out);
}
return true;
}
//----------------------------------------------------------------------------
bool cmTarget::UsesDefaultOutputDir(const std::string& config,
bool implib) const
{
std::string dir;
return this->ComputeOutputDir(config, implib, dir);
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string cmTarget::GetFrameworkVersion() const std::string cmTarget::GetFrameworkVersion() const
{ {
@ -2775,13 +2302,6 @@ const char* cmTarget::GetExportMacro() const
} }
} }
//----------------------------------------------------------------------------
bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) const
{
return this->LinkImplicitNullProperties.find(p)
!= this->LinkImplicitNullProperties.end();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void
cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const
@ -3170,161 +2690,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
} }
} }
cmOptionalLinkImplementation&
cmTarget::GetLinkImplMap(std::string const& config) const
{
// Populate the link implementation for this configuration.
std::string CONFIG = cmSystemTools::UpperCase(config);
return Internal->LinkImplMap[CONFIG][this];
}
//----------------------------------------------------------------------------
cmLinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibraries(const std::string& config) const
{
return this->GetLinkImplementationLibrariesInternal(config, this);
}
//----------------------------------------------------------------------------
cmLinkImplementationLibraries const*
cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget 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);
cmTargetInternals::HeadToLinkImplementationMap& hm =
this->Internal->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;
}
//----------------------------------------------------------------------------
void cmTarget::ComputeLinkImplementationLibraries(
const std::string& config,
cmOptionalLinkImplementation& impl,
cmTarget const* head) const
{
// Collect libraries directly linked in this configuration.
for (std::vector<cmValueWithOrigin>::const_iterator
le = this->Internal->LinkImplementationPropertyEntries.begin(),
end = this->Internal->LinkImplementationPropertyEntries.end();
le != end; ++le)
{
std::vector<std::string> llibs;
cmGeneratorExpressionDAGChecker dagChecker(
this->GetName(),
"LINK_LIBRARIES", 0, 0);
cmGeneratorExpression ge(le->Backtrace);
cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge =
ge.Parse(le->Value);
std::string const evaluated =
cge->Evaluate(this->Makefile, 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->Makefile->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),
le->Backtrace, evaluated != le->Value));
}
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);
}
cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config);
cmTarget::LinkLibraryVectorType const& oldllibs =
this->GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin();
li != oldllibs.end(); ++li)
{
if(li->second != cmTarget::GENERAL && 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)));
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const
{ {

View File

@ -225,35 +225,12 @@ public:
void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const; void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const;
cmLinkImplementationLibraries const*
GetLinkImplementationLibraries(const std::string& config) const;
void ComputeLinkImplementationLibraries(const std::string& config,
cmOptionalLinkImplementation& impl,
cmTarget const* head) const;
cmOptionalLinkImplementation&
GetLinkImplMap(std::string const& config) const;
cmTarget const* FindTargetToLink(std::string const& name) const; cmTarget const* FindTargetToLink(std::string const& name) const;
/** Strip off leading and trailing whitespace from an item named in /** Strip off leading and trailing whitespace from an item named in
the link dependencies of this target. */ the link dependencies of this target. */
std::string CheckCMP0004(std::string const& item) const; std::string CheckCMP0004(std::string const& item) const;
/** Get the directory in which this target will be built. If the
configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
output directory is given. */
std::string GetDirectory(const std::string& config = "",
bool implib = false) const;
/** Get the directory in which this targets .pdb files will be placed.
If the configuration name is given then the generator will add its
subdirectory for that configuration. Otherwise just the canonical
pdb output directory is given. */
std::string GetPDBDirectory(const std::string& config) const;
const char* ImportedGetLocation(const std::string& config) const; const char* ImportedGetLocation(const std::string& config) const;
/** Get the target major and minor version numbers interpreted from /** Get the target major and minor version numbers interpreted from
@ -267,16 +244,6 @@ public:
void void
GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const; GetTargetVersion(bool soversion, int& major, int& minor, int& patch) const;
/** Whether this library has \@rpath and platform supports it. */
bool HasMacOSXRpathInstallNameDir(const std::string& config) const;
/** Whether this library defaults to \@rpath. */
bool MacOSXRpathInstallNameDirDefault() const;
/** Test for special case of a third-party shared library that has
no soname at all. */
bool IsImportedSharedLibWithoutSOName(const std::string& config) const;
/** Does this target have a GNU implib to convert to MS format? */ /** Does this target have a GNU implib to convert to MS format? */
bool HasImplibGNUtoMS() const; bool HasImplibGNUtoMS() const;
@ -285,8 +252,6 @@ public:
bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out, bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
const char* newExt = 0) const; const char* newExt = 0) const;
bool HaveInstallTreeRPATH() const;
// Get the properties // Get the properties
cmPropertyMap &GetProperties() const { return this->Properties; } cmPropertyMap &GetProperties() const { return this->Properties; }
@ -335,10 +300,6 @@ public:
/** Get a build-tree directory in which to place target support files. */ /** Get a build-tree directory in which to place target support files. */
std::string GetSupportDirectory() const; std::string GetSupportDirectory() const;
/** Return whether this target uses the default value for its output
directory. */
bool UsesDefaultOutputDir(const std::string& config, bool implib) const;
/** @return whether this target have a well defined output file name. */ /** @return whether this target have a well defined output file name. */
bool HaveWellDefinedOutputFiles() const; bool HaveWellDefinedOutputFiles() const;
@ -353,8 +314,6 @@ public:
void AppendBuildInterfaceIncludes(); void AppendBuildInterfaceIncludes();
bool IsNullImpliedByLinkLibraries(const std::string &p) const;
std::string GetDebugGeneratorExpressions(const std::string &value, std::string GetDebugGeneratorExpressions(const std::string &value,
cmTarget::LinkLibraryType llt) const; cmTarget::LinkLibraryType llt) const;
@ -365,12 +324,6 @@ public:
bool LinkLanguagePropagatesToDependents() const bool LinkLanguagePropagatesToDependents() const
{ return this->TargetTypeValue == STATIC_LIBRARY; } { return this->TargetTypeValue == STATIC_LIBRARY; }
std::map<std::string, std::string> const&
GetMaxLanguageStandards() const
{
return this->MaxLanguageStandards;
}
cmStringRange GetIncludeDirectoriesEntries() const; cmStringRange GetIncludeDirectoriesEntries() const;
cmBacktraceRange GetIncludeDirectoriesBacktraces() const; cmBacktraceRange GetIncludeDirectoriesBacktraces() const;
@ -385,6 +338,9 @@ public:
cmStringRange GetSourceEntries() const; cmStringRange GetSourceEntries() const;
cmBacktraceRange GetSourceBacktraces() const; cmBacktraceRange GetSourceBacktraces() const;
cmStringRange GetLinkImplementationEntries() const;
cmBacktraceRange GetLinkImplementationBacktraces() const;
#if defined(_WIN32) && !defined(__CYGWIN__) #if defined(_WIN32) && !defined(__CYGWIN__)
const LinkLibraryVectorType &GetLinkLibrariesForVS6() const { const LinkLibraryVectorType &GetLinkLibrariesForVS6() const {
@ -455,9 +411,6 @@ private:
void SetPropertyDefault(const std::string& property, void SetPropertyDefault(const std::string& property,
const char* default_value); const char* default_value);
// Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
const char* GetOutputTargetType(bool implib) const;
std::string GetFullNameImported(const std::string& config, std::string GetFullNameImported(const std::string& config,
bool implib) const; bool implib) const;
@ -469,9 +422,7 @@ private:
std::set<std::string> SystemIncludeDirectories; std::set<std::string> SystemIncludeDirectories;
std::set<std::string> LinkDirectoriesEmmitted; std::set<std::string> LinkDirectoriesEmmitted;
std::set<std::string> Utilities; std::set<std::string> Utilities;
mutable std::set<std::string> LinkImplicitNullProperties;
std::map<std::string, cmListFileBacktrace> UtilityBacktraces; std::map<std::string, cmListFileBacktrace> UtilityBacktraces;
mutable std::map<std::string, std::string> MaxLanguageStandards;
cmPolicies::PolicyMap PolicyMap; cmPolicies::PolicyMap PolicyMap;
std::string Name; std::string Name;
std::string InstallPath; std::string InstallPath;
@ -501,15 +452,6 @@ private:
bool LinkLibrariesForVS6Analyzed; bool LinkLibrariesForVS6Analyzed;
#endif #endif
// Cache target output paths for each configuration.
struct OutputInfo;
OutputInfo const* GetOutputInfo(const std::string& config) const;
bool
ComputeOutputDir(const std::string& config,
bool implib, std::string& out) const;
bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
std::string& out) const;
// Cache import information from properties for each configuration. // Cache import information from properties for each configuration.
struct ImportInfo struct ImportInfo
{ {
@ -529,14 +471,8 @@ private:
void ComputeImportInfo(std::string const& desired_config, void ComputeImportInfo(std::string const& desired_config,
ImportInfo& info) const; ImportInfo& info) const;
cmLinkImplementationLibraries const*
GetLinkImplementationLibrariesInternal(const std::string& config,
cmTarget const* head) const;
std::string ProcessSourceItemCMP0049(const std::string& s); std::string ProcessSourceItemCMP0049(const std::string& s);
void ClearLinkMaps();
void MaybeInvalidatePropertyCache(const std::string& prop); void MaybeInvalidatePropertyCache(const std::string& prop);
// Internal representation details. // Internal representation details.

View File

@ -1779,7 +1779,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
} }
else else
{ {
outDir = this->Target->GetDirectory(config->c_str()) + "/"; outDir = this->GeneratorTarget->GetDirectory(config->c_str()) + "/";
targetNameFull = this->GeneratorTarget->GetFullName(config->c_str()); targetNameFull = this->GeneratorTarget->GetFullName(config->c_str());
} }
this->ConvertToWindowsSlash(intermediateDir); this->ConvertToWindowsSlash(intermediateDir);
@ -2580,10 +2580,11 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
{ {
linkOptions.AddFlag("GenerateDebugInformation", "false"); linkOptions.AddFlag("GenerateDebugInformation", "false");
} }
std::string pdb = this->Target->GetPDBDirectory(config.c_str()); std::string pdb = this->GeneratorTarget->GetPDBDirectory(config.c_str());
pdb += "/"; pdb += "/";
pdb += targetNamePDB; pdb += targetNamePDB;
std::string imLib = this->Target->GetDirectory(config.c_str(), true); std::string imLib =
this->GeneratorTarget->GetDirectory(config.c_str(), true);
imLib += "/"; imLib += "/";
imLib += targetNameImport; imLib += targetNameImport;