diff options
author | Brad King <brad.king@kitware.com> | 2009-07-30 14:59:25 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2009-07-30 14:59:25 (GMT) |
commit | fd633b33cff397b110cc69f82fd522cdf905952a (patch) | |
tree | b17619913c65ba75b68af83b4b86724415697840 /Source/cmTarget.cxx | |
parent | ace4d5d31d7ef553e9900a26afb090178840d38c (diff) | |
download | CMake-fd633b33cff397b110cc69f82fd522cdf905952a.zip CMake-fd633b33cff397b110cc69f82fd522cdf905952a.tar.gz CMake-fd633b33cff397b110cc69f82fd522cdf905952a.tar.bz2 |
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.
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 85 |
1 files changed, 56 insertions, 29 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 22ba81b..52dbb56 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2414,6 +2414,59 @@ cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config) } //---------------------------------------------------------------------------- +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) { // Get languages built in this target. @@ -2452,39 +2505,13 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc) else { // Find the language with the highest preference value. - cmGlobalGenerator* gg = - this->Makefile->GetLocalGenerator()->GetGlobalGenerator(); - std::string linkerLangList; // only used for the error message - int maxLinkerPref = 0; - bool multiplePreferedLanguages = false; + cmTargetSelectLinker tsl(this); for(std::set<cmStdString>::const_iterator sit = languages.begin(); sit != languages.end(); ++sit) { - int linkerPref = gg->GetLinkerPreference(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()); + tsl.Consider(sit->c_str()); } + lc.LinkerLanguage = tsl.Choose(); } } |