Refactor target linker language selection
This factors the decision logic out of cmTarget::ComputeLinkClosure into dedicated class cmTargetSelectLinker. We replace several local variables with a single object instance, and organize code into methods.
This commit is contained in:
parent
ace4d5d31d
commit
fd633b33cf
@ -2413,6 +2413,59 @@ cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config)
|
|||||||
return &i->second;
|
return &i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class cmTargetSelectLinker
|
||||||
|
{
|
||||||
|
int Preference;
|
||||||
|
cmTarget* Target;
|
||||||
|
cmMakefile* Makefile;
|
||||||
|
cmGlobalGenerator* GG;
|
||||||
|
std::set<cmStdString> Preferred;
|
||||||
|
public:
|
||||||
|
cmTargetSelectLinker(cmTarget* target): Preference(0), Target(target)
|
||||||
|
{
|
||||||
|
this->Makefile = this->Target->GetMakefile();
|
||||||
|
this->GG = this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
|
||||||
|
}
|
||||||
|
void Consider(const char* lang)
|
||||||
|
{
|
||||||
|
int preference = this->GG->GetLinkerPreference(lang);
|
||||||
|
if(preference > this->Preference)
|
||||||
|
{
|
||||||
|
this->Preference = preference;
|
||||||
|
this->Preferred.clear();
|
||||||
|
}
|
||||||
|
if(preference == this->Preference)
|
||||||
|
{
|
||||||
|
this->Preferred.insert(lang);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string Choose()
|
||||||
|
{
|
||||||
|
if(this->Preferred.empty())
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if(this->Preferred.size() > 1)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Target " << this->Target->GetName()
|
||||||
|
<< " contains multiple languages with the highest linker preference"
|
||||||
|
<< " (" << this->Preference << "):\n";
|
||||||
|
for(std::set<cmStdString>::const_iterator
|
||||||
|
li = this->Preferred.begin(); li != this->Preferred.end(); ++li)
|
||||||
|
{
|
||||||
|
e << " " << *li << "\n";
|
||||||
|
}
|
||||||
|
e << "Set the LINKER_LANGUAGE property for this target.";
|
||||||
|
cmake* cm = this->Makefile->GetCMakeInstance();
|
||||||
|
cm->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||||
|
this->Target->GetBacktrace());
|
||||||
|
}
|
||||||
|
return *this->Preferred.begin();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
|
void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
|
||||||
{
|
{
|
||||||
@ -2452,39 +2505,13 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find the language with the highest preference value.
|
// Find the language with the highest preference value.
|
||||||
cmGlobalGenerator* gg =
|
cmTargetSelectLinker tsl(this);
|
||||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator();
|
|
||||||
std::string linkerLangList; // only used for the error message
|
|
||||||
int maxLinkerPref = 0;
|
|
||||||
bool multiplePreferedLanguages = false;
|
|
||||||
for(std::set<cmStdString>::const_iterator sit = languages.begin();
|
for(std::set<cmStdString>::const_iterator sit = languages.begin();
|
||||||
sit != languages.end(); ++sit)
|
sit != languages.end(); ++sit)
|
||||||
{
|
{
|
||||||
int linkerPref = gg->GetLinkerPreference(sit->c_str());
|
tsl.Consider(sit->c_str());
|
||||||
if (lc.LinkerLanguage.empty() || (linkerPref > maxLinkerPref))
|
|
||||||
{
|
|
||||||
maxLinkerPref = linkerPref;
|
|
||||||
lc.LinkerLanguage = *sit;
|
|
||||||
linkerLangList = *sit;
|
|
||||||
multiplePreferedLanguages = false;
|
|
||||||
}
|
|
||||||
else if (linkerPref == maxLinkerPref)
|
|
||||||
{
|
|
||||||
linkerLangList += "; ";
|
|
||||||
linkerLangList += *sit;
|
|
||||||
multiplePreferedLanguages = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (multiplePreferedLanguages)
|
|
||||||
{
|
|
||||||
cmOStringStream err;
|
|
||||||
err << "Error: Target " << this->Name << " contains multiple languages "
|
|
||||||
<< "with the highest linker preference (" << maxLinkerPref << "): "
|
|
||||||
<< linkerLangList << "\n"
|
|
||||||
<< "You must set the LINKER_LANGUAGE property for this target.";
|
|
||||||
cmSystemTools::Error(err.str().c_str());
|
|
||||||
}
|
}
|
||||||
|
lc.LinkerLanguage = tsl.Choose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user