diff options
Diffstat (limited to 'Source/cmGlobalGenerator.cxx')
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 309 |
1 files changed, 244 insertions, 65 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index b12c691..4fe5033 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -18,7 +18,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmake.h" #include "cmMakefile.h" -#include "cmQtAutomoc.h" +#include "cmQtAutoGenerators.h" #include "cmSourceFile.h" #include "cmVersion.h" #include "cmTargetExport.h" @@ -27,6 +27,7 @@ #include "cmGeneratorTarget.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionEvaluationFile.h" +#include "cmExportBuildFileGenerator.h" #include <cmsys/Directory.hxx> @@ -77,6 +78,12 @@ cmGlobalGenerator::~cmGlobalGenerator() { delete *li; } + for(std::map<std::string, cmExportBuildFileGenerator*>::iterator + i = this->BuildExportSets.begin(); + i != this->BuildExportSets.end(); ++i) + { + delete i->second; + } this->LocalGenerators.clear(); if (this->ExtraGenerator) @@ -131,24 +138,24 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, if((path.size() == 0 || !cmSystemTools::FileExists(path.c_str())) && (optional==false)) { - std::string message = "your "; - message += lang; - message += " compiler: \""; - message += name; - message += "\" was not found. Please set "; - message += langComp; - message += " to a valid compiler path or name."; - cmSystemTools::Error(message.c_str()); - path = name; + return; } std::string doc = lang; doc += " compiler."; const char* cname = this->GetCMakeInstance()-> GetCacheManager()->GetCacheValue(langComp.c_str()); std::string changeVars; - if(cname && (path != cname) && (optional==false)) + if(cname && !optional) { - std::string cnameString = cname; + std::string cnameString; + if(!cmSystemTools::FileIsFullPath(cname)) + { + cnameString = cmSystemTools::FindProgram(cname); + } + else + { + cnameString = cname; + } std::string pathString = path; // get rid of potentially multiple slashes: cmSystemTools::ConvertToUnixSlashes(cnameString); @@ -175,6 +182,34 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, doc.c_str(), cmCacheManager::FILEPATH); } +void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen) +{ + this->BuildExportSets[gen->GetMainExportFileName()] = gen; +} + +bool cmGlobalGenerator::GenerateImportFile(const std::string &file) +{ + std::map<std::string, cmExportBuildFileGenerator*>::iterator it + = this->BuildExportSets.find(file); + if (it != this->BuildExportSets.end()) + { + bool result = it->second->GenerateImportFile(); + delete it->second; + it->second = 0; + this->BuildExportSets.erase(it); + return result; + } + return false; +} + +bool +cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const +{ + const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it + = this->BuildExportSets.find(filename); + return it != this->BuildExportSets.end(); +} + // Find the make program for the generator, required for try compiles void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) { @@ -291,7 +326,7 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf) void cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, - cmMakefile *mf, bool) + cmMakefile *mf, bool optional) { if(languages.size() == 0) { @@ -327,6 +362,8 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } } + bool fatalError = false; + mf->AddDefinition("RUN_CONFIGURE", true); std::string rootBin = mf->GetHomeOutputDirectory(); rootBin += cmake::GetCMakeFilesDirectory(); @@ -513,6 +550,65 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, this->SetLanguageEnabled("NONE", mf); continue; } + + // Check that the compiler was found. + std::string compilerName = "CMAKE_"; + compilerName += lang; + compilerName += "_COMPILER"; + std::string compilerEnv = "CMAKE_"; + compilerEnv += lang; + compilerEnv += "_COMPILER_ENV_VAR"; + cmOStringStream noCompiler; + const char* compilerFile = mf->GetDefinition(compilerName.c_str()); + if(!compilerFile || !*compilerFile || + cmSystemTools::IsNOTFOUND(compilerFile)) + { + noCompiler << + "No " << compilerName << " could be found.\n" + ; + } + else if(strcmp(lang, "RC") != 0) + { + if(!cmSystemTools::FileIsFullPath(compilerFile)) + { + noCompiler << + "The " << compilerName << ":\n" + " " << compilerFile << "\n" + "is not a full path and was not found in the PATH.\n" + ; + } + else if(!cmSystemTools::FileExists(compilerFile)) + { + noCompiler << + "The " << compilerName << ":\n" + " " << compilerFile << "\n" + "is not a full path to an existing compiler tool.\n" + ; + } + } + if(!noCompiler.str().empty()) + { + // Skip testing this language since the compiler is not found. + needTestLanguage[lang] = false; + if(!optional) + { + // The compiler was not found and it is not optional. Remove + // CMake(LANG)Compiler.cmake so we try again next time CMake runs. + std::string compilerLangFile = rootBin; + compilerLangFile += "/CMake"; + compilerLangFile += lang; + compilerLangFile += "Compiler.cmake"; + cmSystemTools::RemoveFile(compilerLangFile.c_str()); + if(!this->CMakeInstance->GetIsInTryCompile()) + { + this->PrintCompilerAdvice(noCompiler, lang, + mf->GetDefinition(compilerEnv.c_str())); + mf->IssueMessage(cmake::FATAL_ERROR, noCompiler.str()); + fatalError = true; + } + } + } + std::string langLoadedVar = "CMAKE_"; langLoadedVar += lang; langLoadedVar += "_INFORMATION_LOADED"; @@ -539,26 +635,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, } this->LanguagesReady.insert(lang); - std::string compilerName = "CMAKE_"; - compilerName += lang; - compilerName += "_COMPILER"; - std::string compilerLangFile = rootBin; - compilerLangFile += "/CMake"; - compilerLangFile += lang; - compilerLangFile += "Compiler.cmake"; // Test the compiler for the language just setup // (but only if a compiler has been actually found) // At this point we should have enough info for a try compile // which is used in the backward stuff // If the language is untested then test it now with a try compile. - if (!mf->IsSet(compilerName.c_str())) - { - // if the compiler did not work, then remove the - // CMake(LANG)Compiler.cmake file so that it will get tested the - // next time cmake is run - cmSystemTools::RemoveFile(compilerLangFile.c_str()); - } - else if(needTestLanguage[lang]) + if(needTestLanguage[lang]) { if (!this->CMakeInstance->GetIsInTryCompile()) { @@ -579,31 +661,12 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, // next time cmake is run if(!mf->IsOn(compilerWorks.c_str())) { + std::string compilerLangFile = rootBin; + compilerLangFile += "/CMake"; + compilerLangFile += lang; + compilerLangFile += "Compiler.cmake"; cmSystemTools::RemoveFile(compilerLangFile.c_str()); } - else - { - // load backwards compatibility stuff for C and CXX - // for old versions of CMake ListFiles C and CXX had some - // backwards compatibility files they have to load - // These files have a bunch of try compiles in them so - // should only be done - if (mf->NeedBackwardsCompatibility(1,4)) - { - if(strcmp(lang, "C") == 0) - { - ifpath = - mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake"); - mf->ReadListFile(0,ifpath.c_str()); - } - if(strcmp(lang, "CXX") == 0) - { - ifpath = - mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake"); - mf->ReadListFile(0,ifpath.c_str()); - } - } - } } // end if in try compile } // end need test language // Store the shared library flags so that we can satisfy CMP0018 @@ -616,6 +679,9 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { this->LanguageToOriginalSharedLibFlags[lang] = sharedLibFlags; } + + // Translate compiler ids for compatibility. + this->CheckCompilerIdCompatibility(mf, lang); } // end for each language // Now load files that can override any settings on the platform or for @@ -629,6 +695,71 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { mf->ReadListFile(0,projectCompatibility.c_str()); } + + if(fatalError) + { + cmSystemTools::SetFatalErrorOccured(); + } +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::PrintCompilerAdvice(std::ostream& os, + std::string lang, + const char* envVar) +{ + // Subclasses override this method if they do not support this advice. + os << + "Tell CMake where to find the compiler by setting " + ; + if(envVar) + { + os << + "either the environment variable \"" << envVar << "\" or " + ; + } + os << + "the CMake cache entry CMAKE_" << lang << "_COMPILER " + "to the full path to the compiler, or to the compiler name " + "if it is in the PATH." + ; +} + +//---------------------------------------------------------------------------- +void cmGlobalGenerator::CheckCompilerIdCompatibility(cmMakefile* mf, + std::string lang) +{ + std::string compilerIdVar = "CMAKE_" + lang + "_COMPILER_ID"; + const char* compilerId = mf->GetDefinition(compilerIdVar.c_str()); + if(compilerId && strcmp(compilerId, "AppleClang") == 0) + { + cmPolicies* policies = this->CMakeInstance->GetPolicies(); + switch(mf->GetPolicyStatus(cmPolicies::CMP0025)) + { + case cmPolicies::WARN: + if(!this->CMakeInstance->GetIsInTryCompile()) + { + cmOStringStream w; + w << policies->GetPolicyWarning(cmPolicies::CMP0025) << "\n" + "Converting " << lang << + " compiler id \"AppleClang\" to \"Clang\" for compatibility." + ; + mf->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + } + case cmPolicies::OLD: + // OLD behavior is to convert AppleClang to Clang. + mf->AddDefinition(compilerIdVar.c_str(), "Clang"); + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + mf->IssueMessage( + cmake::FATAL_ERROR, + policies->GetRequiredPolicyError(cmPolicies::CMP0025) + ); + case cmPolicies::NEW: + // NEW behavior is to keep AppleClang. + break; + } + } } //---------------------------------------------------------------------------- @@ -917,6 +1048,14 @@ void cmGlobalGenerator::Configure() } } +cmExportBuildFileGenerator* +cmGlobalGenerator::GetExportedTargetsFile(const std::string &filename) const +{ + std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it + = this->BuildExportSets.find(filename); + return it == this->BuildExportSets.end() ? 0 : it->second; +} + bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { // If the property is not enabled then okay. @@ -957,8 +1096,8 @@ void cmGlobalGenerator::Generate() } // Iterate through all targets and set up automoc for those which have - // the AUTOMOC property set - this->CreateAutomocTargets(); + // the AUTOMOC, AUTOUIC or AUTORCC property set + this->CreateQtAutoGeneratorsTargets(); // For each existing cmLocalGenerator unsigned int i; @@ -989,6 +1128,9 @@ void cmGlobalGenerator::Generate() this->LocalGenerators[i]->AddHelperCommands(); } + // Create per-target generator information. + this->CreateGeneratorTargets(); + // Trace the dependencies, after that no custom commands should be added // because their dependencies might not be handled correctly for (i = 0; i < this->LocalGenerators.size(); ++i) @@ -1002,8 +1144,7 @@ void cmGlobalGenerator::Generate() this->LocalGenerators[i]->GenerateTargetManifest(); } - // Create per-target generator information. - this->CreateGeneratorTargets(); + this->ComputeGeneratorTargetObjects(); this->ProcessEvaluationFiles(); @@ -1042,6 +1183,19 @@ void cmGlobalGenerator::Generate() } this->SetCurrentLocalGenerator(0); + for (std::map<std::string, cmExportBuildFileGenerator*>::iterator + it = this->BuildExportSets.begin(); it != this->BuildExportSets.end(); + ++it) + { + if (!it->second->GenerateImportFile() + && !cmSystemTools::GetErrorOccuredFlag()) + { + this->GetCMakeInstance() + ->IssueMessage(cmake::FATAL_ERROR, "Could not write export file.", + cmListFileBacktrace()); + return; + } + } // Update rule hashes. this->CheckRuleHashes(); @@ -1102,11 +1256,11 @@ bool cmGlobalGenerator::CheckTargets() } //---------------------------------------------------------------------------- -void cmGlobalGenerator::CreateAutomocTargets() +void cmGlobalGenerator::CreateQtAutoGeneratorsTargets() { #ifdef CMAKE_BUILD_WITH_CMAKE - typedef std::vector<std::pair<cmQtAutomoc, cmTarget*> > Automocs; - Automocs automocs; + typedef std::vector<std::pair<cmQtAutoGenerators, cmTarget*> > Autogens; + Autogens autogens; for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { cmTargets& targets = @@ -1121,21 +1275,24 @@ void cmGlobalGenerator::CreateAutomocTargets() target.GetType() == cmTarget::MODULE_LIBRARY || target.GetType() == cmTarget::OBJECT_LIBRARY) { - if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported()) + if((target.GetPropertyAsBool("AUTOMOC") + || target.GetPropertyAsBool("AUTOUIC") + || target.GetPropertyAsBool("AUTORCC")) + && !target.IsImported()) { - cmQtAutomoc automoc; - if(automoc.InitializeMocSourceFile(&target)) + cmQtAutoGenerators autogen; + if(autogen.InitializeMocSourceFile(&target)) { - automocs.push_back(std::make_pair(automoc, &target)); + autogens.push_back(std::make_pair(autogen, &target)); } } } } } - for (Automocs::iterator it = automocs.begin(); it != automocs.end(); + for (Autogens::iterator it = autogens.begin(); it != autogens.end(); ++it) { - it->first.SetupAutomocTarget(it->second); + it->first.SetupAutoGenerateTarget(it->second); } #endif } @@ -1182,7 +1339,6 @@ void cmGlobalGenerator::CreateGeneratorTargets() cmGeneratorTarget* gt = new cmGeneratorTarget(t); this->GeneratorTargets[t] = gt; - this->ComputeTargetObjects(gt); generatorTargets[t] = gt; } @@ -1200,6 +1356,25 @@ void cmGlobalGenerator::CreateGeneratorTargets() } //---------------------------------------------------------------------------- +void cmGlobalGenerator::ComputeGeneratorTargetObjects() +{ + // Construct per-target generator information. + for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) + { + cmMakefile *mf = this->LocalGenerators[i]->GetMakefile(); + cmGeneratorTargetsType targets = mf->GetGeneratorTargets(); + for(cmGeneratorTargetsType::iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + cmGeneratorTarget* gt = ti->second; + gt->ClassifySources(); + gt->LookupObjectLibraries(); + this->ComputeTargetObjects(gt); + } + } +} + +//---------------------------------------------------------------------------- void cmGlobalGenerator::ClearGeneratorTargets() { for(cmGeneratorTargetsType::iterator i = this->GeneratorTargets.begin(); @@ -2556,6 +2731,10 @@ void cmGlobalGenerator::WriteSummary() for(std::map<cmStdString,cmTarget *>::const_iterator ti = this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti) { + if ((ti->second)->GetType() == cmTarget::INTERFACE_LIBRARY) + { + continue; + } this->WriteSummary(ti->second); fout << ti->second->GetSupportDirectory() << "\n"; } |