[cmake-commits] alex committed cmGlobalGenerator.h 1.85 1.86 cmGlobalGenerator.cxx 1.193 1.194 cmTarget.cxx 1.153 1.154

cmake-commits at cmake.org cmake-commits at cmake.org
Wed Jul 11 16:22:06 EDT 2007


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv18643/Source

Modified Files:
	cmGlobalGenerator.h cmGlobalGenerator.cxx cmTarget.cxx 
Log Message:

ENH: CMAKE_<LANG>_LINKER_PREFERENCE is now an integer priority, not a
two-step priority (None or Prefered)
Current order: ASM 0, C 10, Fortran 20, CXX 30, Java 40
This is the same order as automake choses:
http://www.gnu.org/software/automake/manual/html_node/How-the-Linker-is-Chosen.html

This change should be backward compatible:
if there is a project using fortran and CXX, they had to set the
LINKER_LANGUAGE explicitely, otherwise cmake complained (but still generated
the project files). Explicitely setting the linker language still overrides
automatic detection.
If somebody has a custom language for cmake and the PREFERENCE starts with
"P", its changed to 100, which gives it preference over all other languages
(except the other custom languages which have also "Prefered"). "None" is
converted to 0.

Alex


Index: cmGlobalGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmGlobalGenerator.h,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -d -r1.85 -r1.86
--- cmGlobalGenerator.h	28 Jun 2007 13:09:26 -0000	1.85
+++ cmGlobalGenerator.h	11 Jul 2007 20:22:04 -0000	1.86
@@ -153,7 +153,7 @@
   ///! 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 @@
   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;

Index: cmGlobalGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmGlobalGenerator.cxx,v
retrieving revision 1.193
retrieving revision 1.194
diff -u -d -r1.193 -r1.194
--- cmGlobalGenerator.cxx	28 Jun 2007 19:28:00 -0000	1.193
+++ cmGlobalGenerator.cxx	11 Jul 2007 20:22:04 -0000	1.194
@@ -570,12 +570,35 @@
   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;
+        }
+      }
+    }
+
+  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] = linkerPref;
 
+  this->LanguageToLinkerPreference[l] = preference;
 
   std::string outputExtensionVar = std::string("CMAKE_") +
     std::string(l) + std::string("_OUTPUT_EXTENSION");
@@ -752,10 +775,6 @@
         }
       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 @@
     }
 }
 
-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()

Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.153
retrieving revision 1.154
diff -u -d -r1.153 -r1.154
--- cmTarget.cxx	2 Jul 2007 17:32:40 -0000	1.153
+++ cmTarget.cxx	11 Jul 2007 20:22:04 -0000	1.154
@@ -1477,59 +1477,57 @@
     const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX");
     }
   const char* linkerLang = this->GetProperty("LINKER_LANGUAGE");
-  if(linkerLang)
-    {
-    return linkerLang;
-    }
-  std::set<cmStdString> languages;
-  for(std::vector<cmSourceFile*>::const_iterator i
-        = this->SourceFiles.begin();
-      i != this->SourceFiles.end(); ++i)
+  if (linkerLang==0)
     {
-    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;
 }
 
 //----------------------------------------------------------------------------



More information about the Cmake-commits mailing list