diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 42 | ||||
-rw-r--r-- | Source/cmGlobalGenerator.h | 4 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 84 |
3 files changed, 74 insertions, 56 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index cea5b2b..31adcf1 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -570,12 +570,35 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf) std::string linkerPrefVar = std::string("CMAKE_") + std::string(l) + std::string("_LINKER_PREFERENCE"); const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str()); - if(!linkerPref) + int preference = 0; + if(linkerPref) { - linkerPref = "None"; + if (sscanf(linkerPref, "%d", &preference)!=1) + { + // backward compatibility: before 2.6 LINKER_PREFERENCE + // was either "None" or "Prefered", and only the first character was + // tested. So if there is a custom language out there and it is + // "Prefered", set its preference high + if (linkerPref[0]=='P') + { + preference = 100; + } + else + { + preference = 0; + } + } } - this->LanguageToLinkerPreference[l] = linkerPref; + if (preference < 0) + { + std::string msg = linkerPrefVar; + msg += " is negative, adjusting it to 0"; + cmSystemTools::Message(msg.c_str(), "Warning"); + preference = 0; + } + + this->LanguageToLinkerPreference[l] = preference; std::string outputExtensionVar = std::string("CMAKE_") + std::string(l) + std::string("_OUTPUT_EXTENSION"); @@ -752,10 +775,6 @@ void cmGlobalGenerator::Configure() } notFoundVars += "\n"; } - cmSystemTools::Error("This project requires some variables to be set,\n" - "and cmake can not find them.\n" - "Please set the following variables:\n", - notFoundVars.c_str()); } // at this point this->LocalGenerators has been filled, // so create the map from project name to vector of local generators @@ -1120,13 +1139,14 @@ void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang) } } -const char* cmGlobalGenerator::GetLinkerPreference(const char* lang) +int cmGlobalGenerator::GetLinkerPreference(const char* lang) { - if(this->LanguageToLinkerPreference.count(lang)) + std::map<cmStdString, int>::const_iterator it = this->LanguageToLinkerPreference.find(lang); + if (it != this->LanguageToLinkerPreference.end()) { - return this->LanguageToLinkerPreference[lang].c_str(); + return it->second; } - return "None"; + return 0; } void cmGlobalGenerator::FillProjectMap() diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 959945c..ccf00d7 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -153,7 +153,7 @@ public: ///! is an extension to be ignored bool IgnoreFile(const char* ext); ///! What is the preference for linkers and this language (None or Prefered) - const char* GetLinkerPreference(const char* lang); + int GetLinkerPreference(const char* lang); ///! What is the object file extension for a given source file? const char* GetLanguageOutputExtension(cmSourceFile const&); @@ -257,7 +257,7 @@ private: std::map<cmStdString, cmStdString> OutputExtensions; std::map<cmStdString, cmStdString> LanguageToOutputExtension; std::map<cmStdString, cmStdString> ExtensionToLanguage; - std::map<cmStdString, cmStdString> LanguageToLinkerPreference; + std::map<cmStdString, int> LanguageToLinkerPreference; // this is used to improve performance std::map<cmStdString,cmTarget *> TotalTargets; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 70d0035..40132a5 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1477,59 +1477,57 @@ const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg) const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX"); } const char* linkerLang = this->GetProperty("LINKER_LANGUAGE"); - if(linkerLang) + if (linkerLang==0) { - return linkerLang; - } - std::set<cmStdString> languages; - for(std::vector<cmSourceFile*>::const_iterator i - = this->SourceFiles.begin(); - i != this->SourceFiles.end(); ++i) - { - if(const char* lang = (*i)->GetLanguage()) + // if the property has not yet been set, collect all languages in the + // target and then find the language with the highest preference value + std::set<cmStdString> languages; + for(std::vector<cmSourceFile*>::const_iterator + i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i) { - languages.insert(lang); + if(const char* lang = (*i)->GetLanguage()) + { + languages.insert(lang); + } } - } - if(languages.size() == 0) - { - return 0; - } - if(languages.size() == 1) - { - const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", - languages.begin()->c_str()); - return this->GetProperty("LINKER_LANGUAGE"); - } - const char* prefLang = 0; - for(std::set<cmStdString>::const_iterator s = languages.begin(); - s != languages.end(); ++s) - { - const char* lpref = gg->GetLinkerPreference(s->c_str()); - if(lpref[0] == 'P') + + std::string linkerLangList; // only used for the error message + int maxLinkerPref = 0; + bool multiplePreferedLanguages = false; + for(std::set<cmStdString>::const_iterator sit = languages.begin(); + sit != languages.end(); ++sit) { - if(prefLang && !(*s == prefLang)) + int linkerPref = gg->GetLinkerPreference(sit->c_str()); + if ((linkerPref > maxLinkerPref) || (linkerLang==0)) { - std::string m = "Error Target: "; - m += this->Name + " Contains more than one Prefered language: "; - m += *s; - m += " and "; - m += prefLang; - m += "\nYou must set the LINKER_LANGUAGE property for this target."; - cmSystemTools::Error(m.c_str()); + maxLinkerPref = linkerPref; + linkerLang = sit->c_str(); + linkerLangList = *sit; + multiplePreferedLanguages = false; } - else + else if (linkerPref == maxLinkerPref) { - prefLang = s->c_str(); + linkerLangList += "; "; + linkerLangList += *sit; + multiplePreferedLanguages = true; } } + + if (linkerLang!=0) + { + const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", linkerLang); + } + 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()); + } } - if(!prefLang) - { - prefLang = languages.begin()->c_str(); - } - const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", prefLang); - return this->GetProperty("LINKER_LANGUAGE"); + return linkerLang; } //---------------------------------------------------------------------------- |