Xcode: Fix parallel build depends with universal binaries (#11844)
A post-build phase of each target invokes the XCODE_DEPEND_HELPER.make file to erase any targets that link to it. Narrow the set of targets tested by each post-build phase to those that depend on the newly completed target. This avoids removing files from partially built unrelated targets that happen to be building in parallel.
This commit is contained in:
parent
4b652ad0d9
commit
44cdae921d
|
@ -322,6 +322,19 @@ void cmGlobalXCodeGenerator::SetGenerationRoot(cmLocalGenerator* root)
|
||||||
this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
|
this->CurrentXCodeHackMakefile += "/XCODE_DEPEND_HELPER.make";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string
|
||||||
|
cmGlobalXCodeGenerator::PostBuildMakeTarget(std::string const& tName,
|
||||||
|
std::string const& configName)
|
||||||
|
{
|
||||||
|
std::string out = "PostBuild." + tName;
|
||||||
|
if(this->XcodeVersion > 20)
|
||||||
|
{
|
||||||
|
out += "." + configName;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
||||||
|
@ -351,12 +364,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
||||||
makecommand.push_back(dir.c_str());
|
makecommand.push_back(dir.c_str());
|
||||||
makecommand.push_back("-f");
|
makecommand.push_back("-f");
|
||||||
makecommand.push_back(this->CurrentXCodeHackMakefile.c_str());
|
makecommand.push_back(this->CurrentXCodeHackMakefile.c_str());
|
||||||
if(this->XcodeVersion > 20)
|
makecommand.push_back(""); // placeholder, see below
|
||||||
{
|
|
||||||
makecommand.push_back("all.$(CONFIGURATION)");
|
|
||||||
}
|
|
||||||
cmCustomCommandLines commandLines;
|
|
||||||
commandLines.push_back(makecommand);
|
|
||||||
// Add Re-Run CMake rules
|
// Add Re-Run CMake rules
|
||||||
this->CreateReRunCMakeFile(root, gens);
|
this->CreateReRunCMakeFile(root, gens);
|
||||||
|
|
||||||
|
@ -383,6 +392,10 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
||||||
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
target.GetType() == cmTarget::MODULE_LIBRARY))
|
target.GetType() == cmTarget::MODULE_LIBRARY))
|
||||||
{
|
{
|
||||||
|
makecommand[makecommand.size()-1] =
|
||||||
|
this->PostBuildMakeTarget(target.GetName(), "$(CONFIGURATION)");
|
||||||
|
cmCustomCommandLines commandLines;
|
||||||
|
commandLines.push_back(makecommand);
|
||||||
lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
|
lg->GetMakefile()->AddCustomCommandToTarget(target.GetName(),
|
||||||
no_depends,
|
no_depends,
|
||||||
commandLines,
|
commandLines,
|
||||||
|
@ -2437,6 +2450,10 @@ void cmGlobalXCodeGenerator
|
||||||
{
|
{
|
||||||
linkLibs += li->Value;
|
linkLibs += li->Value;
|
||||||
}
|
}
|
||||||
|
if(li->Target && !li->Target->IsImported())
|
||||||
|
{
|
||||||
|
target->AddDependTarget(configName, li->Target->GetName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
|
this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
|
||||||
linkLibs.c_str(), configName);
|
linkLibs.c_str(), configName);
|
||||||
|
@ -2882,41 +2899,10 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
|
||||||
// correctly by xcode
|
// correctly by xcode
|
||||||
makefileStream << "# DO NOT EDIT\n";
|
makefileStream << "# DO NOT EDIT\n";
|
||||||
makefileStream << "# This makefile makes sure all linkable targets are\n";
|
makefileStream << "# This makefile makes sure all linkable targets are\n";
|
||||||
makefileStream << "# up-to-date with anything they link to, avoiding a "
|
makefileStream << "# up-to-date with anything they link to\n"
|
||||||
"bug in Xcode 1.5\n";
|
"default:\n"
|
||||||
for(std::vector<std::string>::const_iterator
|
"\techo \"Do not invoke directly\"\n"
|
||||||
ct = this->CurrentConfigurationTypes.begin();
|
"\n";
|
||||||
ct != this->CurrentConfigurationTypes.end(); ++ct)
|
|
||||||
{
|
|
||||||
if(this->XcodeVersion < 21 || ct->empty())
|
|
||||||
{
|
|
||||||
makefileStream << "all: ";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
makefileStream << "all." << *ct << ": ";
|
|
||||||
}
|
|
||||||
const char* configName = 0;
|
|
||||||
if(!ct->empty())
|
|
||||||
{
|
|
||||||
configName = ct->c_str();
|
|
||||||
}
|
|
||||||
for(std::vector<cmXCodeObject*>::iterator i = targets.begin();
|
|
||||||
i != targets.end(); ++i)
|
|
||||||
{
|
|
||||||
cmXCodeObject* target = *i;
|
|
||||||
cmTarget* t =target->GetTarget();
|
|
||||||
if(t->GetType() == cmTarget::EXECUTABLE ||
|
|
||||||
t->GetType() == cmTarget::SHARED_LIBRARY ||
|
|
||||||
t->GetType() == cmTarget::MODULE_LIBRARY)
|
|
||||||
{
|
|
||||||
std::string tfull = t->GetFullPath(configName);
|
|
||||||
makefileStream << "\\\n\t" <<
|
|
||||||
this->ConvertToRelativeForMake(tfull.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
makefileStream << "\n\n";
|
|
||||||
}
|
|
||||||
makefileStream
|
makefileStream
|
||||||
<< "# For each target create a dummy rule "
|
<< "# For each target create a dummy rule "
|
||||||
"so the target does not have to exist\n";
|
"so the target does not have to exist\n";
|
||||||
|
@ -2962,14 +2948,40 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
|
||||||
{
|
{
|
||||||
cmXCodeObject* target = *i;
|
cmXCodeObject* target = *i;
|
||||||
cmTarget* t =target->GetTarget();
|
cmTarget* t =target->GetTarget();
|
||||||
|
|
||||||
|
if(t->GetType() == cmTarget::EXECUTABLE ||
|
||||||
|
t->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||||
|
t->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
t->GetType() == cmTarget::MODULE_LIBRARY)
|
||||||
|
{
|
||||||
|
// Declare an entry point for the target post-build phase.
|
||||||
|
makefileStream << this->PostBuildMakeTarget(t->GetName(), *ct)
|
||||||
|
<< ":\n";
|
||||||
|
}
|
||||||
|
|
||||||
if(t->GetType() == cmTarget::EXECUTABLE ||
|
if(t->GetType() == cmTarget::EXECUTABLE ||
|
||||||
t->GetType() == cmTarget::SHARED_LIBRARY ||
|
t->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
t->GetType() == cmTarget::MODULE_LIBRARY)
|
t->GetType() == cmTarget::MODULE_LIBRARY)
|
||||||
{
|
{
|
||||||
// Create a rule for this target.
|
|
||||||
std::string tfull = t->GetFullPath(configName);
|
std::string tfull = t->GetFullPath(configName);
|
||||||
makefileStream << this->ConvertToRelativeForMake(tfull.c_str())
|
std::string trel = this->ConvertToRelativeForMake(tfull.c_str());
|
||||||
<< ":";
|
|
||||||
|
// Add this target to the post-build phases of its dependencies.
|
||||||
|
std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
|
||||||
|
y = target->GetDependTargets().find(*ct);
|
||||||
|
if(y != target->GetDependTargets().end())
|
||||||
|
{
|
||||||
|
std::vector<cmStdString> const& deptgts = y->second;
|
||||||
|
for(std::vector<cmStdString>::const_iterator d = deptgts.begin();
|
||||||
|
d != deptgts.end(); ++d)
|
||||||
|
{
|
||||||
|
makefileStream << this->PostBuildMakeTarget(*d, *ct) << ": "
|
||||||
|
<< trel << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a rule for this target.
|
||||||
|
makefileStream << trel << ":";
|
||||||
|
|
||||||
// List dependencies if any exist.
|
// List dependencies if any exist.
|
||||||
std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
|
std::map<cmStdString, cmXCodeObject::StringVec>::const_iterator
|
||||||
|
|
|
@ -198,6 +198,8 @@ protected:
|
||||||
std::vector<cmXCodeObject*> XCodeObjects;
|
std::vector<cmXCodeObject*> XCodeObjects;
|
||||||
cmXCodeObject* RootObject;
|
cmXCodeObject* RootObject;
|
||||||
private:
|
private:
|
||||||
|
std::string PostBuildMakeTarget(std::string const& tName,
|
||||||
|
std::string const& configName);
|
||||||
cmXCodeObject* MainGroupChildren;
|
cmXCodeObject* MainGroupChildren;
|
||||||
cmXCodeObject* SourcesGroupChildren;
|
cmXCodeObject* SourcesGroupChildren;
|
||||||
cmXCodeObject* ResourcesGroupChildren;
|
cmXCodeObject* ResourcesGroupChildren;
|
||||||
|
|
|
@ -139,6 +139,19 @@ public:
|
||||||
{
|
{
|
||||||
return this->DependLibraries;
|
return this->DependLibraries;
|
||||||
}
|
}
|
||||||
|
void AddDependTarget(const char* configName,
|
||||||
|
const char* tName)
|
||||||
|
{
|
||||||
|
if(!configName)
|
||||||
|
{
|
||||||
|
configName = "";
|
||||||
|
}
|
||||||
|
this->DependTargets[configName].push_back(tName);
|
||||||
|
}
|
||||||
|
std::map<cmStdString, StringVec> const& GetDependTargets()
|
||||||
|
{
|
||||||
|
return this->DependTargets;
|
||||||
|
}
|
||||||
std::vector<cmXCodeObject*> const& GetObjectList() { return this->List;}
|
std::vector<cmXCodeObject*> const& GetObjectList() { return this->List;}
|
||||||
void SetComment(const char* c) { this->Comment = c;}
|
void SetComment(const char* c) { this->Comment = c;}
|
||||||
static void PrintString(std::ostream& os,cmStdString String);
|
static void PrintString(std::ostream& os,cmStdString String);
|
||||||
|
@ -156,6 +169,7 @@ protected:
|
||||||
cmXCodeObject* PBXTargetDependencyValue;
|
cmXCodeObject* PBXTargetDependencyValue;
|
||||||
std::vector<cmXCodeObject*> List;
|
std::vector<cmXCodeObject*> List;
|
||||||
std::map<cmStdString, StringVec> DependLibraries;
|
std::map<cmStdString, StringVec> DependLibraries;
|
||||||
|
std::map<cmStdString, StringVec> DependTargets;
|
||||||
std::map<cmStdString, cmXCodeObject*> ObjectAttributes;
|
std::map<cmStdString, cmXCodeObject*> ObjectAttributes;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue