ENH: Make static library targets depend on targets to which they "link" for the purpose of build ordering. This makes the build order consistent for static and shared library builds. It is also useful when custom command inputs of one library are generated as custom commands outputs of another. It may be useful in the future for Fortran module dependencies. Implemented for Makefiles, Xcode, and VS 8 and above. Added sample code to do it for VS 7.1 and below, but left it disabled with comments explaining why. Likely it will never be needed on VS 7.1 or below anyway.
This commit is contained in:
parent
d2be142e3b
commit
3cf3bb664a
|
@ -903,24 +903,21 @@ cmGlobalUnixMakefileGenerator3
|
||||||
|
|
||||||
// A target should not depend on itself.
|
// A target should not depend on itself.
|
||||||
emitted.insert(target.GetName());
|
emitted.insert(target.GetName());
|
||||||
|
|
||||||
// Loop over all library dependencies but not for static libs
|
// Loop over all library dependencies.
|
||||||
if (target.GetType() != cmTarget::STATIC_LIBRARY)
|
const cmTarget::LinkLibraryVectorType& tlibs = target.GetLinkLibraries();
|
||||||
|
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
|
||||||
|
lib != tlibs.end(); ++lib)
|
||||||
{
|
{
|
||||||
const cmTarget::LinkLibraryVectorType& tlibs = target.GetLinkLibraries();
|
// Don't emit the same library twice for this target.
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
|
if(emitted.insert(lib->first).second)
|
||||||
lib != tlibs.end(); ++lib)
|
|
||||||
{
|
{
|
||||||
// Don't emit the same library twice for this target.
|
// Add this dependency.
|
||||||
if(emitted.insert(lib->first).second)
|
this->AppendAnyGlobalDepend(depends, lib->first.c_str(),
|
||||||
{
|
emitted, target);
|
||||||
// Add this dependency.
|
|
||||||
this->AppendAnyGlobalDepend(depends, lib->first.c_str(),
|
|
||||||
emitted, target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop over all utility dependencies.
|
// Loop over all utility dependencies.
|
||||||
const std::set<cmStdString>& tutils = target.GetUtilities();
|
const std::set<cmStdString>& tutils = target.GetUtilities();
|
||||||
for(std::set<cmStdString>::const_iterator util = tutils.begin();
|
for(std::set<cmStdString>::const_iterator util = tutils.begin();
|
||||||
|
@ -967,24 +964,6 @@ cmGlobalUnixMakefileGenerator3
|
||||||
std::string tgtName = lg3->GetRelativeTargetDirectory(*result);
|
std::string tgtName = lg3->GetRelativeTargetDirectory(*result);
|
||||||
tgtName += "/all";
|
tgtName += "/all";
|
||||||
depends.push_back(tgtName);
|
depends.push_back(tgtName);
|
||||||
if(result->GetType() == cmTarget::STATIC_LIBRARY)
|
|
||||||
{
|
|
||||||
// Since the static library itself does not list dependencies we
|
|
||||||
// need to chain its dependencies here.
|
|
||||||
const cmTarget::LinkLibraryVectorType& tlibs
|
|
||||||
= result->GetLinkLibraries();
|
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
|
|
||||||
lib != tlibs.end(); ++lib)
|
|
||||||
{
|
|
||||||
// Don't emit the same library twice for this target.
|
|
||||||
if(emitted.insert(lib->first).second)
|
|
||||||
{
|
|
||||||
// Add this dependency.
|
|
||||||
this->AppendAnyGlobalDepend(depends, lib->first.c_str(),
|
|
||||||
emitted, *result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,8 +317,14 @@ cmGlobalVisualStudio71Generator
|
||||||
const char* dspname,
|
const char* dspname,
|
||||||
const char*, cmTarget& target)
|
const char*, cmTarget& target)
|
||||||
{
|
{
|
||||||
// insert Begin Project Dependency Project_Dep_Name project stuff here
|
// Create inter-target dependencies in the solution file. For VS
|
||||||
if (target.GetType() != cmTarget::STATIC_LIBRARY)
|
// 7.1 and below we cannot let static libraries depend directly on
|
||||||
|
// targets to which they "link" because the librarian tool will copy
|
||||||
|
// the targets into the static library. See
|
||||||
|
// cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget for a
|
||||||
|
// work-around. VS 8 and above do not have this problem.
|
||||||
|
if (!this->VSLinksDependencies() ||
|
||||||
|
target.GetType() != cmTarget::STATIC_LIBRARY)
|
||||||
{
|
{
|
||||||
cmTarget::LinkLibraryVectorType::const_iterator j, jend;
|
cmTarget::LinkLibraryVectorType::const_iterator j, jend;
|
||||||
j = target.GetLinkLibraries().begin();
|
j = target.GetLinkLibraries().begin();
|
||||||
|
|
|
@ -59,8 +59,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Utility target fix is not needed for VS8.
|
virtual bool VSLinksDependencies() const { return false; }
|
||||||
virtual void FixUtilityDepends() {}
|
|
||||||
|
|
||||||
static cmVS7FlagTable const* GetExtraFlagTableVS8();
|
static cmVS7FlagTable const* GetExtraFlagTableVS8();
|
||||||
virtual void AddPlatformDefinitions(cmMakefile* mf);
|
virtual void AddPlatformDefinitions(cmMakefile* mf);
|
||||||
|
|
|
@ -197,6 +197,12 @@ std::string cmGlobalVisualStudioGenerator::GetUserMacrosDirectory()
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmGlobalVisualStudioGenerator::FixUtilityDepends()
|
void cmGlobalVisualStudioGenerator::FixUtilityDepends()
|
||||||
{
|
{
|
||||||
|
// Skip for VS versions 8 and above.
|
||||||
|
if(!this->VSLinksDependencies())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// For VS versions before 8:
|
// For VS versions before 8:
|
||||||
//
|
//
|
||||||
// When a target that links contains a project-level dependency on a
|
// When a target that links contains a project-level dependency on a
|
||||||
|
@ -232,6 +238,33 @@ cmGlobalVisualStudioGenerator::FixUtilityDependsForTarget(cmTarget& target)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// This feature makes a mess in SLN files for VS 7.1 and below. It
|
||||||
|
// creates an extra target for every target that is "linked" by a
|
||||||
|
// static library. Without this feature static libraries do not
|
||||||
|
// wait until their "link" dependencies are built to build. This is
|
||||||
|
// not a problem 99.9% of the time, and projects that do have the
|
||||||
|
// problem can enable this work-around by using add_dependencies.
|
||||||
|
|
||||||
|
// Static libraries cannot depend directly on the targets to which
|
||||||
|
// they link because VS will copy those targets into the library
|
||||||
|
// (for VS < 8). To work around the problem we copy the
|
||||||
|
// dependencies to be utility dependencies so that the work-around
|
||||||
|
// below is used.
|
||||||
|
if(target.GetType() == cmTarget::STATIC_LIBRARY)
|
||||||
|
{
|
||||||
|
cmTarget::LinkLibraryVectorType const& libs = target.GetLinkLibraries();
|
||||||
|
for(cmTarget::LinkLibraryVectorType::const_iterator i = libs.begin();
|
||||||
|
i != libs.end(); ++i)
|
||||||
|
{
|
||||||
|
if(cmTarget* depTarget = this->FindTarget(0, i->first.c_str(), false))
|
||||||
|
{
|
||||||
|
target.AddUtility(depTarget->GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Look at each utility dependency.
|
// Look at each utility dependency.
|
||||||
for(std::set<cmStdString>::const_iterator ui =
|
for(std::set<cmStdString>::const_iterator ui =
|
||||||
target.GetUtilities().begin();
|
target.GetUtilities().begin();
|
||||||
|
|
|
@ -60,9 +60,14 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void CreateGUID(const char*) {}
|
virtual void CreateGUID(const char*) {}
|
||||||
virtual void FixUtilityDepends();
|
void FixUtilityDepends();
|
||||||
const char* GetUtilityForTarget(cmTarget& target, const char*);
|
const char* GetUtilityForTarget(cmTarget& target, const char*);
|
||||||
|
|
||||||
|
// Does this VS version link targets to each other if there are
|
||||||
|
// dependencies in the SLN file? This was done for VS versions
|
||||||
|
// below 8.
|
||||||
|
virtual bool VSLinksDependencies() const { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FixUtilityDependsForTarget(cmTarget& target);
|
void FixUtilityDependsForTarget(cmTarget& target);
|
||||||
void CreateUtilityDependTarget(cmTarget& target);
|
void CreateUtilityDependTarget(cmTarget& target);
|
||||||
|
|
|
@ -2006,34 +2006,33 @@ void cmGlobalXCodeGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add dependencies on other CMake targets.
|
// Add dependencies on other CMake targets.
|
||||||
if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
|
{
|
||||||
|
// Keep track of dependencies already listed.
|
||||||
|
std::set<cmStdString> emitted;
|
||||||
|
|
||||||
|
// A target should not depend on itself.
|
||||||
|
emitted.insert(cmtarget->GetName());
|
||||||
|
|
||||||
|
// Loop over all library dependencies.
|
||||||
|
const cmTarget::LinkLibraryVectorType& tlibs =
|
||||||
|
cmtarget->GetLinkLibraries();
|
||||||
|
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
|
||||||
|
lib != tlibs.end(); ++lib)
|
||||||
{
|
{
|
||||||
// Keep track of dependencies already listed.
|
// Don't emit the same library twice for this target.
|
||||||
std::set<cmStdString> emitted;
|
if(emitted.insert(lib->first).second)
|
||||||
|
|
||||||
// A target should not depend on itself.
|
|
||||||
emitted.insert(cmtarget->GetName());
|
|
||||||
|
|
||||||
// Loop over all library dependencies.
|
|
||||||
const cmTarget::LinkLibraryVectorType& tlibs =
|
|
||||||
cmtarget->GetLinkLibraries();
|
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin();
|
|
||||||
lib != tlibs.end(); ++lib)
|
|
||||||
{
|
{
|
||||||
// Don't emit the same library twice for this target.
|
// Add this dependency.
|
||||||
if(emitted.insert(lib->first).second)
|
cmTarget* t = this->FindTarget(this->CurrentProject.c_str(),
|
||||||
|
lib->first.c_str(), false);
|
||||||
|
cmXCodeObject* dptarget = this->FindXCodeTarget(t);
|
||||||
|
if(dptarget)
|
||||||
{
|
{
|
||||||
// Add this dependency.
|
this->AddDependTarget(target, dptarget);
|
||||||
cmTarget* t = this->FindTarget(this->CurrentProject.c_str(),
|
|
||||||
lib->first.c_str(), false);
|
|
||||||
cmXCodeObject* dptarget = this->FindXCodeTarget(t);
|
|
||||||
if(dptarget)
|
|
||||||
{
|
|
||||||
this->AddDependTarget(target, dptarget);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// write utility dependencies.
|
// write utility dependencies.
|
||||||
for(std::set<cmStdString>::const_iterator i
|
for(std::set<cmStdString>::const_iterator i
|
||||||
|
|
Loading…
Reference in New Issue