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
This commit is contained in:
parent
16705a3e87
commit
021ceea1b0
|
@ -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@_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@_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)
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ ENDIF(CMAKE_COMPILER_IS_MINGW)
|
||||||
SET(CMAKE_C_COMPILER_ID_RUN 1)
|
SET(CMAKE_C_COMPILER_ID_RUN 1)
|
||||||
SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c)
|
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_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
|
# save the size of void* in case where cache is removed
|
||||||
# and the this file is still around
|
# and the this file is still around
|
||||||
|
|
|
@ -21,7 +21,7 @@ ENDIF(CMAKE_COMPILER_IS_MINGW)
|
||||||
SET(CMAKE_CXX_COMPILER_ID_RUN 1)
|
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_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_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
|
# save the size of void* in case where cache is removed
|
||||||
# and the this file is still around
|
# and the this file is still around
|
||||||
|
|
|
@ -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_RUN TRUE)
|
||||||
SET(CMAKE_C_COMPILER_ID ${id})
|
SET(CMAKE_C_COMPILER_ID ${id})
|
||||||
SET(CMAKE_C_COMPILER_WORKS TRUE)
|
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(CMAKE_SIZEOF_VOID_P ${sizeof_void} CACHE STRING "sizeof void")
|
||||||
SET(HAVE_CMAKE_SIZEOF_VOID_P TRUE CACHE INTERNAL "have sizeof void")
|
SET(HAVE_CMAKE_SIZEOF_VOID_P TRUE CACHE INTERNAL "have sizeof void")
|
||||||
ENDMACRO(CMAKE_FORCE_C_COMPILER)
|
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_RUN TRUE)
|
||||||
SET(CMAKE_CXX_COMPILER_ID ${id})
|
SET(CMAKE_CXX_COMPILER_ID ${id})
|
||||||
SET(CMAKE_CXX_COMPILER_WORKS TRUE)
|
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)
|
ENDMACRO(CMAKE_FORCE_CXX_COMPILER)
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ ENDIF(CMAKE_COMPILER_IS_MINGW)
|
||||||
SET(CMAKE_Fortran_COMPILER_ID_RUN 1)
|
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_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_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)
|
IF(UNIX)
|
||||||
SET(CMAKE_Fortran_OUTPUT_EXTENSION .o)
|
SET(CMAKE_Fortran_OUTPUT_EXTENSION .o)
|
||||||
ELSE(UNIX)
|
ELSE(UNIX)
|
||||||
|
|
|
@ -5,7 +5,7 @@ SET(CMAKE_Java_ARCHIVE "@CMAKE_Java_ARCHIVE@")
|
||||||
SET(CMAKE_Java_COMPILER_LOADED 1)
|
SET(CMAKE_Java_COMPILER_LOADED 1)
|
||||||
|
|
||||||
SET(CMAKE_Java_SOURCE_FILE_EXTENSIONS java)
|
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_Java_OUTPUT_EXTENSION .class)
|
||||||
SET(CMAKE_STATIC_LIBRARY_PREFIX_Java "")
|
SET(CMAKE_STATIC_LIBRARY_PREFIX_Java "")
|
||||||
SET(CMAKE_STATIC_LIBRARY_SUFFIX_Java ".jar")
|
SET(CMAKE_STATIC_LIBRARY_SUFFIX_Java ".jar")
|
||||||
|
|
|
@ -570,12 +570,35 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
|
||||||
std::string linkerPrefVar = std::string("CMAKE_") +
|
std::string linkerPrefVar = std::string("CMAKE_") +
|
||||||
std::string(l) + std::string("_LINKER_PREFERENCE");
|
std::string(l) + std::string("_LINKER_PREFERENCE");
|
||||||
const char* linkerPref = mf->GetDefinition(linkerPrefVar.c_str());
|
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 outputExtensionVar = std::string("CMAKE_") +
|
||||||
std::string(l) + std::string("_OUTPUT_EXTENSION");
|
std::string(l) + std::string("_OUTPUT_EXTENSION");
|
||||||
|
@ -752,10 +775,6 @@ void cmGlobalGenerator::Configure()
|
||||||
}
|
}
|
||||||
notFoundVars += "\n";
|
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,
|
// at this point this->LocalGenerators has been filled,
|
||||||
// so create the map from project name to vector of local generators
|
// 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()
|
void cmGlobalGenerator::FillProjectMap()
|
||||||
|
|
|
@ -153,7 +153,7 @@ public:
|
||||||
///! is an extension to be ignored
|
///! is an extension to be ignored
|
||||||
bool IgnoreFile(const char* ext);
|
bool IgnoreFile(const char* ext);
|
||||||
///! What is the preference for linkers and this language (None or Prefered)
|
///! 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?
|
///! What is the object file extension for a given source file?
|
||||||
const char* GetLanguageOutputExtension(cmSourceFile const&);
|
const char* GetLanguageOutputExtension(cmSourceFile const&);
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ private:
|
||||||
std::map<cmStdString, cmStdString> OutputExtensions;
|
std::map<cmStdString, cmStdString> OutputExtensions;
|
||||||
std::map<cmStdString, cmStdString> LanguageToOutputExtension;
|
std::map<cmStdString, cmStdString> LanguageToOutputExtension;
|
||||||
std::map<cmStdString, cmStdString> ExtensionToLanguage;
|
std::map<cmStdString, cmStdString> ExtensionToLanguage;
|
||||||
std::map<cmStdString, cmStdString> LanguageToLinkerPreference;
|
std::map<cmStdString, int> LanguageToLinkerPreference;
|
||||||
|
|
||||||
// this is used to improve performance
|
// this is used to improve performance
|
||||||
std::map<cmStdString,cmTarget *> TotalTargets;
|
std::map<cmStdString,cmTarget *> TotalTargets;
|
||||||
|
|
|
@ -1477,58 +1477,56 @@ const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg)
|
||||||
const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX");
|
const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", "CXX");
|
||||||
}
|
}
|
||||||
const char* linkerLang = this->GetProperty("LINKER_LANGUAGE");
|
const char* linkerLang = this->GetProperty("LINKER_LANGUAGE");
|
||||||
if(linkerLang)
|
if (linkerLang==0)
|
||||||
{
|
{
|
||||||
return linkerLang;
|
// 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;
|
std::set<cmStdString> languages;
|
||||||
for(std::vector<cmSourceFile*>::const_iterator i
|
for(std::vector<cmSourceFile*>::const_iterator
|
||||||
= this->SourceFiles.begin();
|
i = this->SourceFiles.begin(); i != this->SourceFiles.end(); ++i)
|
||||||
i != this->SourceFiles.end(); ++i)
|
|
||||||
{
|
{
|
||||||
if(const char* lang = (*i)->GetLanguage())
|
if(const char* lang = (*i)->GetLanguage())
|
||||||
{
|
{
|
||||||
languages.insert(lang);
|
languages.insert(lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(languages.size() == 0)
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
return 0;
|
int linkerPref = gg->GetLinkerPreference(sit->c_str());
|
||||||
|
if ((linkerPref > maxLinkerPref) || (linkerLang==0))
|
||||||
|
{
|
||||||
|
maxLinkerPref = linkerPref;
|
||||||
|
linkerLang = sit->c_str();
|
||||||
|
linkerLangList = *sit;
|
||||||
|
multiplePreferedLanguages = false;
|
||||||
}
|
}
|
||||||
if(languages.size() == 1)
|
else if (linkerPref == maxLinkerPref)
|
||||||
{
|
{
|
||||||
const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE",
|
linkerLangList += "; ";
|
||||||
languages.begin()->c_str());
|
linkerLangList += *sit;
|
||||||
return this->GetProperty("LINKER_LANGUAGE");
|
multiplePreferedLanguages = true;
|
||||||
}
|
|
||||||
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')
|
|
||||||
{
|
|
||||||
if(prefLang && !(*s == prefLang))
|
|
||||||
{
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prefLang = s->c_str();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(!prefLang)
|
if (linkerLang!=0)
|
||||||
{
|
{
|
||||||
prefLang = languages.begin()->c_str();
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", prefLang);
|
|
||||||
return this->GetProperty("LINKER_LANGUAGE");
|
return this->GetProperty("LINKER_LANGUAGE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue