BUG: Target exclusion-from-all tests should always use the root local generator associated with the all target being tested.

This commit is contained in:
Brad King 2007-08-03 15:44:25 -04:00
parent 11604e72c4
commit d7118006de
6 changed files with 91 additions and 205 deletions

View File

@ -691,7 +691,7 @@ void cmGlobalGenerator::Configure()
this->TargetDependencies.clear(); this->TargetDependencies.clear();
this->TotalTargets.clear(); this->TotalTargets.clear();
this->ImportedTotalTargets.clear(); this->ImportedTotalTargets.clear();
this->ProjectToTargetMap.clear(); this->LocalGeneratorToTargetMap.clear();
this->ProjectMap.clear(); this->ProjectMap.clear();
// start with this directory // start with this directory
@ -779,11 +779,11 @@ void cmGlobalGenerator::Configure()
} }
// at this point this->LocalGenerators has been filled, // at this point this->LocalGenerators has been filled,
// so create the map from project name to vector of local generators // so create the map from project name to vector of local generators
this->FillProjectMap(); this->FillProjectMap();
// now create project to target map
// This will make sure that targets have all the // Create a map from local generator to the complete set of targets
// targets they depend on as part of the build. // it builds by default.
this->FillProjectToTargetMap(); this->FillLocalGeneratorToTargetMap();
if ( !this->CMakeInstance->GetScriptMode() ) if ( !this->CMakeInstance->GetScriptMode() )
{ {
@ -1116,22 +1116,38 @@ void cmGlobalGenerator::GetDocumentation(cmDocumentationEntry& entry) const
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
cmLocalGenerator* gen) cmLocalGenerator* gen)
{ {
if(gen == root) if(!gen || gen == root)
{ {
// No directory excludes itself.
return false; return false;
} }
cmLocalGenerator* cur = gen->GetParent();
while(cur && cur != root) if(gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{ {
if(cur->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL")) // This directory is excluded from its parent.
{ return true;
return true;
}
cur = cur->GetParent();
} }
return gen->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL");
// This directory is included in its parent. Check whether the
// parent is excluded.
return this->IsExcluded(root, gen->GetParent());
} }
bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
cmTarget& target)
{
if(target.GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
// This target is excluded from its directory.
return true;
}
else
{
// This target is included in its directory. Check whether the
// directory is excluded.
return this->IsExcluded(root, target.GetMakefile()->GetLocalGenerator());
}
}
void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang) void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
{ {
@ -1176,88 +1192,40 @@ void cmGlobalGenerator::FillProjectMap()
} }
// Build a map that contains a the set of targets used by each project // Build a map that contains a the set of targets used by each local
void cmGlobalGenerator::FillProjectToTargetMap() // generator directory level.
void cmGlobalGenerator::FillLocalGeneratorToTargetMap()
{ {
// loop over each project in the build // Loop over all targets in all local generators.
for(std::map<cmStdString, for(std::vector<cmLocalGenerator*>::const_iterator
std::vector<cmLocalGenerator*> >::iterator m = lgi = this->LocalGenerators.begin();
this->ProjectMap.begin(); lgi != this->LocalGenerators.end(); ++lgi)
m != this->ProjectMap.end(); ++m)
{ {
std::vector<cmLocalGenerator*>& lgs = m->second; cmLocalGenerator* lg = *lgi;
if(lgs.size() == 0) cmMakefile* mf = lg->GetMakefile();
cmTargets& targets = mf->GetTargets();
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
{ {
continue; cmTarget& target = t->second;
}
cmStdString const & projectName = m->first; // Consider the directory containing the target and all its
cmMakefile* projectMakefile = lgs[0]->GetMakefile(); // parents until something excludes the target.
// get the current EXCLUDE_FROM_ALL value from projectMakefile for(cmLocalGenerator* clg = lg; clg && !this->IsExcluded(clg, target);
const char* exclude = 0; clg = clg->GetParent())
std::string excludeSave;
bool chain = false;
exclude =
projectMakefile->GetProperties().
GetPropertyValue("EXCLUDE_FROM_ALL",
cmProperty::DIRECTORY, chain);
if(exclude)
{
excludeSave = exclude;
}
// Set EXCLUDE_FROM_ALL to FALSE for the top level makefile because
// in the current project nothing is excluded yet
projectMakefile->SetProperty("EXCLUDE_FROM_ALL", "FALSE");
// now loop over all cmLocalGenerators in this project and pull
// out all the targets that depend on each other, even if those
// targets come from a target that is excluded.
for(std::vector<cmLocalGenerator*>::iterator lg =
lgs.begin(); lg != lgs.end(); ++lg)
{
cmMakefile* mf = (*lg)->GetMakefile();
cmTargets& targets = mf->GetTargets();
for(cmTargets::iterator t = targets.begin();
t != targets.end(); ++t)
{ {
cmTarget& target = t->second; // This local generator includes the target.
// if the target is in all then add it to the project std::set<cmTarget*>& targetSet =
if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL")) this->LocalGeneratorToTargetMap[clg];
{ targetSet.insert(&target);
// add this target to the project
this->ProjectToTargetMap[projectName].insert(&target); // Add dependencies of the included target. An excluded
// get the target's dependencies // target may still be included if it is a dependency of a
std::vector<cmTarget *>& tgtdeps = this->GetTargetDepends(target); // non-excluded target.
this->ProjectToTargetMap[projectName].insert(tgtdeps.begin(), std::vector<cmTarget *>& tgtdeps = this->GetTargetDepends(target);
tgtdeps.end()); targetSet.insert(tgtdeps.begin(), tgtdeps.end());
}
} }
} }
// Now restore the EXCLUDE_FROM_ALL property on the project top
// makefile
if(exclude)
{
exclude = excludeSave.c_str();
}
projectMakefile->SetProperty("EXCLUDE_FROM_ALL", exclude);
} }
// dump the map for debug purposes
// right now this map is not being used, but it was
// checked in to avoid constant conflicts.
// It is also the first step to creating sub projects
// that contain all of the targets they need.
#if 0
std::map<cmStdString, std::set<cmTarget*> >::iterator i =
this->ProjectToTargetMap.begin();
for(; i != this->ProjectToTargetMap.end(); ++i)
{
std::cerr << i->first << "\n";
std::set<cmTarget*>::iterator t = i->second.begin();
for(; t != i->second.end(); ++t)
{
cmTarget* target = *t;
std::cerr << "\t" << target->GetName() << "\n";
}
}
#endif
} }

View File

@ -230,7 +230,8 @@ protected:
// has been populated. // has been populated.
void FillProjectMap(); void FillProjectMap();
bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen); bool IsExcluded(cmLocalGenerator* root, cmLocalGenerator* gen);
void FillProjectToTargetMap(); bool IsExcluded(cmLocalGenerator* root, cmTarget& target);
void FillLocalGeneratorToTargetMap();
void CreateDefaultGlobalTargets(cmTargets* targets); void CreateDefaultGlobalTargets(cmTargets* targets);
cmTarget CreateGlobalTarget(const char* name, const char* message, cmTarget CreateGlobalTarget(const char* name, const char* message,
const cmCustomCommandLines* commandLines, const cmCustomCommandLines* commandLines,
@ -247,7 +248,7 @@ protected:
cmLocalGenerator* CurrentLocalGenerator; cmLocalGenerator* CurrentLocalGenerator;
// map from project name to vector of local generators in that project // map from project name to vector of local generators in that project
std::map<cmStdString, std::vector<cmLocalGenerator*> > ProjectMap; std::map<cmStdString, std::vector<cmLocalGenerator*> > ProjectMap;
std::map<cmStdString, std::set<cmTarget*> > ProjectToTargetMap; std::map<cmLocalGenerator*, std::set<cmTarget*> > LocalGeneratorToTargetMap;
// Set of named installation components requested by the project. // Set of named installation components requested by the project.
std::set<cmStdString> InstallComponents; std::set<cmStdString> InstallComponents;

View File

@ -229,19 +229,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
{ {
lg = lg =
static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]); static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[i]);
// are any parents excluded this->WriteConvenienceRules2(makefileStream,lg);
bool exclude = false;
cmLocalGenerator *lg3 = lg;
while (lg3)
{
if (lg3->GetMakefile()->GetPropertyAsBool("EXCLUDE_FROM_ALL"))
{
exclude = true;
break;
}
lg3 = lg3->GetParent();
}
this->WriteConvenienceRules2(makefileStream,lg,exclude);
} }
lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]); lg = static_cast<cmLocalUnixMakefileGenerator3 *>(this->LocalGenerators[0]);
@ -699,8 +687,7 @@ cmGlobalUnixMakefileGenerator3
void void
cmGlobalUnixMakefileGenerator3 cmGlobalUnixMakefileGenerator3
::WriteConvenienceRules2(std::ostream& ruleFileStream, ::WriteConvenienceRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *lg, cmLocalUnixMakefileGenerator3 *lg)
bool exclude)
{ {
std::vector<std::string> depends; std::vector<std::string> depends;
std::vector<std::string> commands; std::vector<std::string> commands;
@ -792,7 +779,7 @@ cmGlobalUnixMakefileGenerator3
localName.c_str(), depends, commands, true); localName.c_str(), depends, commands, true);
// add the all/all dependency // add the all/all dependency
if (!exclude && !t->second.GetPropertyAsBool("EXCLUDE_FROM_ALL")) if(!this->IsExcluded(this->LocalGenerators[0], t->second))
{ {
depends.clear(); depends.clear();
depends.push_back(localName); depends.push_back(localName);
@ -861,11 +848,15 @@ cmGlobalUnixMakefileGenerator3
lg->WriteMakeRule(ruleFileStream, lg->WriteMakeRule(ruleFileStream,
"Pre-install relink rule for target.", "Pre-install relink rule for target.",
localName.c_str(), depends, commands, true); localName.c_str(), depends, commands, true);
depends.clear();
depends.push_back(localName); if(!this->IsExcluded(this->LocalGenerators[0], t->second))
commands.clear(); {
lg->WriteMakeRule(ruleFileStream, "Prepare target for install.", depends.clear();
"preinstall", depends, commands, true); depends.push_back(localName);
commands.clear();
lg->WriteMakeRule(ruleFileStream, "Prepare target for install.",
"preinstall", depends, commands, true);
}
} }
// add the clean rule // add the clean rule
@ -917,89 +908,16 @@ unsigned long cmGlobalUnixMakefileGenerator3
::GetNumberOfProgressActionsInAll(cmLocalUnixMakefileGenerator3 *lg) ::GetNumberOfProgressActionsInAll(cmLocalUnixMakefileGenerator3 *lg)
{ {
unsigned long result = 0; unsigned long result = 0;
std::set<cmTarget*>& targets = this->LocalGeneratorToTargetMap[lg];
// if this is a project for(std::set<cmTarget*>::iterator t = targets.begin();
if (!lg->GetParent() || t != targets.end(); ++t)
strcmp(lg->GetMakefile()->GetProjectName(),
lg->GetParent()->GetMakefile()->GetProjectName()))
{ {
// use the new project to target map cmTarget* target = *t;
std::set<cmTarget*> &targets = cmLocalUnixMakefileGenerator3 *lg3 =
this->ProjectToTargetMap[lg->GetMakefile()->GetProjectName()]; static_cast<cmLocalUnixMakefileGenerator3 *>
std::set<cmTarget*>::iterator t = targets.begin(); (target->GetMakefile()->GetLocalGenerator());
for(; t != targets.end(); ++t) std::vector<int> &progFiles = lg3->ProgressFiles[target->GetName()];
{ result += static_cast<unsigned long>(progFiles.size());
cmTarget* target = *t;
cmLocalUnixMakefileGenerator3 *lg3 =
static_cast<cmLocalUnixMakefileGenerator3 *>
(target->GetMakefile()->GetLocalGenerator());
std::vector<int> &progFiles = lg3->ProgressFiles[target->GetName()];
result += static_cast<unsigned long>(progFiles.size());
}
}
// for subdirectories
else
{
std::deque<cmLocalUnixMakefileGenerator3 *> lg3Stack;
lg3Stack.push_back(lg);
std::vector<cmStdString> targetsInAll;
std::set<cmTarget *> targets;
while (lg3Stack.size())
{
cmLocalUnixMakefileGenerator3 *lg3 = lg3Stack.front();
lg3Stack.pop_front();
for(cmTargets::iterator l = lg3->GetMakefile()->GetTargets().begin();
l != lg3->GetMakefile()->GetTargets().end(); ++l)
{
if((l->second.GetType() == cmTarget::EXECUTABLE) ||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
(l->second.GetType() == cmTarget::UTILITY))
{
// Add this to the list of depends rules in this directory.
if (!l->second.GetPropertyAsBool("EXCLUDE_FROM_ALL") &&
targets.find(&l->second) == targets.end())
{
std::deque<cmTarget *> activeTgts;
activeTgts.push_back(&(l->second));
// trace depth of target dependencies
while (activeTgts.size())
{
if (targets.find(activeTgts.front()) == targets.end())
{
targets.insert(activeTgts.front());
cmLocalUnixMakefileGenerator3 *lg4 =
static_cast<cmLocalUnixMakefileGenerator3 *>
(activeTgts.front()->GetMakefile()->GetLocalGenerator());
std::vector<int> &progFiles2 =
lg4->ProgressFiles[activeTgts.front()->GetName()];
result += static_cast<unsigned long>(progFiles2.size());
std::vector<cmTarget *> deps2 =
this->GetTargetDepends(*activeTgts.front());
for (std::vector<cmTarget *>::const_iterator di =
deps2.begin(); di != deps2.end(); ++di)
{
activeTgts.push_back(*di);
}
}
activeTgts.pop_front();
}
}
}
}
// The directory-level rule depends on the directory-level
// rules of the subdirectories.
for(std::vector<cmLocalGenerator*>::iterator sdi =
lg3->GetChildren().begin();
sdi != lg3->GetChildren().end(); ++sdi)
{
cmLocalUnixMakefileGenerator3* slg =
static_cast<cmLocalUnixMakefileGenerator3*>(*sdi);
lg3Stack.push_back(slg);
}
}
} }
return result; return result;
} }

View File

@ -145,10 +145,9 @@ public:
protected: protected:
void WriteMainMakefile2(); void WriteMainMakefile2();
void WriteMainCMakefile(); void WriteMainCMakefile();
void WriteConvenienceRules2(std::ostream& ruleFileStream, void WriteConvenienceRules2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3 *, cmLocalUnixMakefileGenerator3*);
bool exclude);
void WriteDirectoryRule2(std::ostream& ruleFileStream, void WriteDirectoryRule2(std::ostream& ruleFileStream,
cmLocalUnixMakefileGenerator3* lg, cmLocalUnixMakefileGenerator3* lg,

View File

@ -2847,10 +2847,10 @@ void cmMakefile::DefineProperties(cmake *cm)
cm->DefineProperty cm->DefineProperty
("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY, ("EXCLUDE_FROM_ALL", cmProperty::DIRECTORY,
"Exclude the target from the all target.", "Exclude the directory from the all target of its parent.",
"A property on a target that indicates if the target is excluded " "A property on a directory that indicates if its targets are excluded "
"from the default build target. If it is not, then with a Makefile " "from the default build target. If it is not, then with a Makefile "
"for example typing make will couse this target to be built as well. " "for example typing make will cause the targets to be built. "
"The same concept applies to the default build of other generators.", "The same concept applies to the default build of other generators.",
true); false);
} }

View File

@ -122,9 +122,9 @@ void cmTarget::DefineProperties(cmake *cm)
"Exclude the target from the all target.", "Exclude the target from the all target.",
"A property on a target that indicates if the target is excluded " "A property on a target that indicates if the target is excluded "
"from the default build target. If it is not, then with a Makefile " "from the default build target. If it is not, then with a Makefile "
"for example typing make will couse this target to be built as well. " "for example typing make will cause this target to be built. "
"The same concept applies to the default build of other generators.", "The same concept applies to the default build of other generators.",
true); false);
cm->DefineProperty cm->DefineProperty
("INSTALL_NAME_DIR", cmProperty::TARGET, ("INSTALL_NAME_DIR", cmProperty::TARGET,