Xcode: Sort targets deterministically and with ALL_BUILD first (#15346)

The default target in XCode is the first one in the file.

In commit v3.1.0-rc1~286^2 (cmTarget: use a hash_map for cmTargets
typedef, 2014-06-10) the order of the targets stored in cmMakefile was
made non-deterministic instead of lexicographic.  Teach the Xcode
generator to do its own sorting to restore a predictable order.

While at it, place ALL_BUILD first (as is done in VS IDE generators)
explicitly in the comparison function so that it is the default target
even if other targets sort earlier lexicographically (e.g. "AAA").
This commit is contained in:
Ben Boeckel 2015-01-16 17:37:26 -05:00 committed by Brad King
parent c0ff542c58
commit 9e0176e2b3
1 changed files with 25 additions and 1 deletions

View File

@ -965,6 +965,23 @@ struct cmSourceFilePathCompare
} }
}; };
//----------------------------------------------------------------------------
struct cmCompareTargets
{
bool operator () (std::string const& a, std::string const& b) const
{
if (a == "ALL_BUILD")
{
return true;
}
if (b == "ALL_BUILD")
{
return false;
}
return strcmp(a.c_str(), b.c_str()) < 0;
}
};
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool bool
cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
@ -973,9 +990,16 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
{ {
this->SetCurrentLocalGenerator(gen); this->SetCurrentLocalGenerator(gen);
cmTargets &tgts = this->CurrentMakefile->GetTargets(); cmTargets &tgts = this->CurrentMakefile->GetTargets();
typedef std::map<std::string, cmTarget*, cmCompareTargets> cmSortedTargets;
cmSortedTargets sortedTargets;
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
{ {
cmTarget& cmtarget = l->second; sortedTargets[l->first] = &l->second;
}
for(cmSortedTargets::iterator l = sortedTargets.begin();
l != sortedTargets.end(); l++)
{
cmTarget& cmtarget = *l->second;
cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget); cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget);
// make sure ALL_BUILD, INSTALL, etc are only done once // make sure ALL_BUILD, INSTALL, etc are only done once