try_compile: Allow only languages loaded in caller (#11469)

During a try_compile cmGlobalGenerator::EnableLanguage uses results from
the outer project.  Reject attempts to enable languages in the test
project that are not "ready" in the outer project.  Mark a language as
"ready" when all its information has been loaded and we are ready to
generate build rules.

This also avoids infinite recursion introduced by commit 295b5b60 (Honor
CMAKE_USER_MAKE_RULES_OVERRIDE in try_compile, 2010-06-29) for projects
that set CMAKE_USER_MAKE_RULES_OVERRIDE to a file that uses try_compile.
The file is loaded along with the information for a given langauge so
the language is not yet "ready".
This commit is contained in:
Brad King 2011-01-24 10:00:45 -05:00
parent 5792d3a38a
commit c83a834d29
3 changed files with 39 additions and 12 deletions

View File

@ -56,6 +56,7 @@ cmGlobalGenerator::cmGlobalGenerator()
this->ExtraGenerator = 0;
this->CurrentLocalGenerator = 0;
this->TryCompileOuterMakefile = 0;
}
cmGlobalGenerator::~cmGlobalGenerator()
@ -199,6 +200,34 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
cmSystemTools::SetFatalErrorOccured();
return;
}
if(this->TryCompileOuterMakefile)
{
// In a try-compile we can only enable languages provided by caller.
for(std::vector<std::string>::const_iterator li = languages.begin();
li != languages.end(); ++li)
{
if(*li == "NONE")
{
this->SetLanguageEnabled("NONE", mf);
}
else
{
const char* lang = li->c_str();
if(this->LanguagesReady.find(lang) == this->LanguagesReady.end())
{
cmOStringStream e;
e << "The test project needs language "
<< lang << " which is not enabled.";
this->TryCompileOuterMakefile
->IssueMessage(cmake::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return;
}
}
}
}
mf->AddDefinition("RUN_CONFIGURE", true);
std::string rootBin = mf->GetHomeOutputDirectory();
rootBin += cmake::GetCMakeFilesDirectory();
@ -208,15 +237,6 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
// files from the parent cmake bin dir, into the try compile bin dir
if(this->ConfiguredFilesPath.size())
{
for(std::vector<std::string>::const_iterator l = languages.begin();
l != languages.end(); ++l)
{
if(*l == "NONE")
{
this->SetLanguageEnabled("NONE", mf);
break;
}
}
rootBin = this->ConfiguredFilesPath;
}
@ -421,6 +441,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
{
this->SetLanguageEnabledMaps(lang, mf);
}
this->LanguagesReady.insert(lang);
std::string compilerName = "CMAKE_";
compilerName += lang;
@ -1339,9 +1360,11 @@ cmLocalGenerator *cmGlobalGenerator::CreateLocalGenerator()
return lg;
}
void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen )
void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
cmMakefile* mf)
{
this->SetConfiguredFilesPath(gen);
this->TryCompileOuterMakefile = mf;
const char* make =
gen->GetCMakeInstance()->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM", make,
@ -1349,6 +1372,7 @@ void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator *gen )
cmCacheManager::FILEPATH);
// copy the enabled languages
this->LanguageEnabled = gen->LanguageEnabled;
this->LanguagesReady = gen->LanguagesReady;
this->ExtensionToLanguage = gen->ExtensionToLanguage;
this->IgnoreExtensions = gen->IgnoreExtensions;
this->LanguageToOutputExtension = gen->LanguageToOutputExtension;

View File

@ -78,7 +78,8 @@ public:
/**
* Try to determine system infomation, get it from another generator
*/
virtual void EnableLanguagesFromGenerator(cmGlobalGenerator *gen);
virtual void EnableLanguagesFromGenerator(cmGlobalGenerator *gen,
cmMakefile* mf);
/**
* Try running cmake and building a file. This is used for dynalically
@ -321,11 +322,13 @@ protected:
std::map<cmStdString,cmTarget *> TotalTargets;
private:
cmMakefile* TryCompileOuterMakefile;
float FirstTimeProgress;
// If you add a new map here, make sure it is copied
// in EnableLanguagesFromGenerator
std::map<cmStdString, bool> IgnoreExtensions;
std::map<cmStdString, bool> LanguageEnabled;
std::set<cmStdString> LanguagesReady; // Ready for try_compile
std::map<cmStdString, cmStdString> OutputExtensions;
std::map<cmStdString, cmStdString> LanguageToOutputExtension;
std::map<cmStdString, cmStdString> ExtensionToLanguage;

View File

@ -2691,7 +2691,7 @@ int cmMakefile::TryCompile(const char *srcdir, const char *bindir,
}
// to save time we pass the EnableLanguage info directly
gg->EnableLanguagesFromGenerator
(this->LocalGenerator->GetGlobalGenerator());
(this->LocalGenerator->GetGlobalGenerator(), this);
if(this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS"))
{
cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS",