summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Neundorf <neundorf@kde.org>2007-07-12 08:37:10 -0400
committerAlexander Neundorf <neundorf@kde.org>2007-07-12 08:37:10 -0400
commit021ceea1b0c841852f8ca3f9f550d966834b4d40 (patch)
tree3b9ea1abca5af7acf346531775369b4fb2aa8176
parent16705a3e87f3f8a877b5fe8dc1e953c7abca4da3 (diff)
downloadcmake-021ceea1b0c841852f8ca3f9f550d966834b4d40.tar.gz
ENH: second try for handling the linker language with integer priority values (returning a pointer to a string on the stack is no good idea)
Alex
-rw-r--r--Modules/CMakeASMCompiler.cmake.in2
-rw-r--r--Modules/CMakeCCompiler.cmake.in2
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in2
-rw-r--r--Modules/CMakeForceCompiler.cmake11
-rw-r--r--Modules/CMakeFortranCompiler.cmake.in2
-rw-r--r--Modules/CMakeJavaCompiler.cmake.in2
-rw-r--r--Source/cmGlobalGenerator.cxx42
-rw-r--r--Source/cmGlobalGenerator.h4
-rw-r--r--Source/cmTarget.cxx82
9 files changed, 89 insertions, 60 deletions
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index f839a3e220..230805bf42 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -7,5 +7,5 @@ SET(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
SET(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@")
SET(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
-SET(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE None)
+SET(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE 0)
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index b746abaf89..6a7fef818c 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -21,7 +21,7 @@ ENDIF(CMAKE_COMPILER_IS_MINGW)
SET(CMAKE_C_COMPILER_ID_RUN 1)
SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
-SET(CMAKE_C_LINKER_PREFERENCE None)
+SET(CMAKE_C_LINKER_PREFERENCE 10)
# save the size of void* in case where cache is removed
# and the this file is still around
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index f2c53d59c0..b3a84dd1dd 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -21,7 +21,7 @@ ENDIF(CMAKE_COMPILER_IS_MINGW)
SET(CMAKE_CXX_COMPILER_ID_RUN 1)
SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;H;o;O;obj;OBJ;def;DEF;rc;RC)
SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm)
-SET(CMAKE_CXX_LINKER_PREFERENCE Prefered)
+SET(CMAKE_CXX_LINKER_PREFERENCE 30)
# save the size of void* in case where cache is removed
# and the this file is still around
diff --git a/Modules/CMakeForceCompiler.cmake b/Modules/CMakeForceCompiler.cmake
index d104ad9c02..751fd7850f 100644
--- a/Modules/CMakeForceCompiler.cmake
+++ b/Modules/CMakeForceCompiler.cmake
@@ -38,6 +38,12 @@ MACRO(CMAKE_FORCE_C_COMPILER compiler id sizeof_void)
SET(CMAKE_C_COMPILER_ID_RUN TRUE)
SET(CMAKE_C_COMPILER_ID ${id})
SET(CMAKE_C_COMPILER_WORKS TRUE)
+
+ # Set old compiler and platform id variables.
+ IF("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+ SET(CMAKE_COMPILER_IS_GNUCC 1)
+ ENDIF("${CMAKE_C_COMPILER_ID}" MATCHES "GNU")
+
SET(CMAKE_SIZEOF_VOID_P ${sizeof_void} CACHE STRING "sizeof void")
SET(HAVE_CMAKE_SIZEOF_VOID_P TRUE CACHE INTERNAL "have sizeof void")
ENDMACRO(CMAKE_FORCE_C_COMPILER)
@@ -47,5 +53,10 @@ MACRO(CMAKE_FORCE_CXX_COMPILER compiler id)
SET(CMAKE_CXX_COMPILER_ID_RUN TRUE)
SET(CMAKE_CXX_COMPILER_ID ${id})
SET(CMAKE_CXX_COMPILER_WORKS TRUE)
+
+ IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+ SET(CMAKE_COMPILER_IS_GNUCXX 1)
+ ENDIF("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+
ENDMACRO(CMAKE_FORCE_CXX_COMPILER)
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index a4f3941bad..67a0c64a16 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -21,7 +21,7 @@ ENDIF(CMAKE_COMPILER_IS_MINGW)
SET(CMAKE_Fortran_COMPILER_ID_RUN 1)
SET(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;f77;F77;f90;F90;for;f95;F95)
SET(CMAKE_Fortran_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
-SET(CMAKE_Fortran_LINKER_PREFERENCE Prefered)
+SET(CMAKE_Fortran_LINKER_PREFERENCE 20)
IF(UNIX)
SET(CMAKE_Fortran_OUTPUT_EXTENSION .o)
ELSE(UNIX)
diff --git a/Modules/CMakeJavaCompiler.cmake.in b/Modules/CMakeJavaCompiler.cmake.in
index c9eeb14c8b..83c1ee44a1 100644
--- a/Modules/CMakeJavaCompiler.cmake.in
+++ b/Modules/CMakeJavaCompiler.cmake.in
@@ -5,7 +5,7 @@ SET(CMAKE_Java_ARCHIVE "@CMAKE_Java_ARCHIVE@")
SET(CMAKE_Java_COMPILER_LOADED 1)
SET(CMAKE_Java_SOURCE_FILE_EXTENSIONS java)
-SET(CMAKE_Java_LINKER_PREFERENCE Prefered)
+SET(CMAKE_Java_LINKER_PREFERENCE 40)
SET(CMAKE_Java_OUTPUT_EXTENSION .class)
SET(CMAKE_STATIC_LIBRARY_PREFIX_Java "")
SET(CMAKE_STATIC_LIBRARY_SUFFIX_Java ".jar")
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cea5b2b04c..31adcf158c 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 959945c984..ccf00d7f5c 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 70d00352fc..3db4add30e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1477,58 +1477,56 @@ 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");
}