diff options
Diffstat (limited to 'Source/cmGlobalGenerator.cxx')
-rw-r--r-- | Source/cmGlobalGenerator.cxx | 238 |
1 files changed, 134 insertions, 104 deletions
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 386a3f7..6964b62 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -7,6 +7,7 @@ #include <algorithm> #include <assert.h> #include <cstring> +#include <initializer_list> #include <iterator> #include <sstream> #include <stdio.h> @@ -34,6 +35,7 @@ #include "cmMakefile.h" #include "cmMessageType.h" #include "cmPolicies.h" +#include "cmRange.h" #include "cmSourceFile.h" #include "cmState.h" #include "cmStateDirectory.h" @@ -211,7 +213,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang, if (!mf->GetDefinition(langComp)) { if (!optional) { - cmSystemTools::Error(langComp.c_str(), " not set, after EnableLanguage"); + cmSystemTools::Error(langComp + " not set, after EnableLanguage"); } return; } @@ -314,9 +316,11 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const if (configs.empty()) { target->GetSourceFiles(srcs, ""); } else { - for (std::vector<std::string>::const_iterator ci = configs.begin(); - ci != configs.end() && srcs.empty(); ++ci) { - target->GetSourceFiles(srcs, *ci); + for (std::string const& config : configs) { + target->GetSourceFiles(srcs, config); + if (srcs.empty()) { + break; + } } } if (srcs.empty()) { @@ -635,8 +639,7 @@ void cmGlobalGenerator::EnableLanguage( // to avoid duplicate compiler tests. if (cmSystemTools::FileExists(fpath)) { if (!mf->ReadListFile(fpath)) { - cmSystemTools::Error("Could not find cmake module file: ", - fpath.c_str()); + cmSystemTools::Error("Could not find cmake module file: " + fpath); } // if this file was found then the language was already determined // to be working @@ -661,8 +664,8 @@ void cmGlobalGenerator::EnableLanguage( determineCompiler += "Compiler.cmake"; std::string determineFile = mf->GetModulesFile(determineCompiler); if (!mf->ReadListFile(determineFile)) { - cmSystemTools::Error("Could not find cmake module file: ", - determineCompiler.c_str()); + cmSystemTools::Error("Could not find cmake module file: " + + determineCompiler); } if (cmSystemTools::GetFatalErrorOccured()) { return; @@ -680,8 +683,9 @@ void cmGlobalGenerator::EnableLanguage( std::string compilerEnv = "CMAKE_"; compilerEnv += lang; compilerEnv += "_COMPILER_ENV_VAR"; - std::string envVar = mf->GetRequiredDefinition(compilerEnv); - std::string envVarValue = mf->GetRequiredDefinition(compilerName); + const std::string& envVar = mf->GetRequiredDefinition(compilerEnv); + const std::string& envVarValue = + mf->GetRequiredDefinition(compilerName); std::string env = envVar; env += "="; env += envVarValue; @@ -695,8 +699,7 @@ void cmGlobalGenerator::EnableLanguage( fpath += lang; fpath += "Compiler.cmake"; if (!mf->ReadListFile(fpath)) { - cmSystemTools::Error("Could not find cmake module file: ", - fpath.c_str()); + cmSystemTools::Error("Could not find cmake module file: " + fpath); } this->SetLanguageEnabledFlag(lang, mf); needSetLanguageEnabledMaps[lang] = true; @@ -788,11 +791,10 @@ void cmGlobalGenerator::EnableLanguage( fpath += "Information.cmake"; std::string informationFile = mf->GetModulesFile(fpath); if (informationFile.empty()) { - cmSystemTools::Error("Could not find cmake module file: ", - fpath.c_str()); + cmSystemTools::Error("Could not find cmake module file: " + fpath); } else if (!mf->ReadListFile(informationFile)) { - cmSystemTools::Error("Could not process cmake module file: ", - informationFile.c_str()); + cmSystemTools::Error("Could not process cmake module file: " + + informationFile); } } if (needSetLanguageEnabledMaps[lang]) { @@ -812,8 +814,8 @@ void cmGlobalGenerator::EnableLanguage( testLang += "Compiler.cmake"; std::string ifpath = mf->GetModulesFile(testLang); if (!mf->ReadListFile(ifpath)) { - cmSystemTools::Error("Could not find cmake module file: ", - testLang.c_str()); + cmSystemTools::Error("Could not find cmake module file: " + + testLang); } std::string compilerWorks = "CMAKE_"; compilerWorks += lang; @@ -954,6 +956,36 @@ void cmGlobalGenerator::CheckCompilerIdCompatibility( break; } } + + if (strcmp(compilerId, "XLClang") == 0) { + switch (mf->GetPolicyStatus(cmPolicies::CMP0089)) { + case cmPolicies::WARN: + if (!this->CMakeInstance->GetIsInTryCompile() && + mf->PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0089")) { + std::ostringstream w; + /* clang-format off */ + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0089) << "\n" + "Converting " << lang << + " compiler id \"XLClang\" to \"XL\" for compatibility." + ; + /* clang-format on */ + mf->IssueMessage(MessageType::AUTHOR_WARNING, w.str()); + } + CM_FALLTHROUGH; + case cmPolicies::OLD: + // OLD behavior is to convert XLClang to XL. + mf->AddDefinition(compilerIdVar, "XL"); + break; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + mf->IssueMessage( + MessageType::FATAL_ERROR, + cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0089)); + case cmPolicies::NEW: + // NEW behavior is to keep AppleClang. + break; + } + } } std::string cmGlobalGenerator::GetLanguageOutputExtension( @@ -1222,7 +1254,7 @@ void cmGlobalGenerator::Configure() } else { msg << "Configuring done"; } - this->CMakeInstance->UpdateProgress(msg.str().c_str(), -1); + this->CMakeInstance->UpdateProgress(msg.str(), -1); } } @@ -1702,8 +1734,8 @@ void cmGlobalGenerator::CheckTargetProperties() cmSystemTools::Error("The following variables are used in this project, " "but they are set to NOTFOUND.\n" "Please set them or make sure they are set and " - "tested correctly in the CMake files:\n", - notFoundVars.c_str()); + "tested correctly in the CMake files:\n" + + notFoundVars); } } @@ -1731,20 +1763,9 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, this->FirstTimeProgress); } - std::string newTarget; + std::vector<std::string> newTarget = {}; if (!target.empty()) { - newTarget += target; -#if 0 -# if defined(_WIN32) || defined(__CYGWIN__) - std::string tmp = target; - // if the target does not already end in . something - // then assume .exe - if(tmp.size() < 4 || tmp[tmp.size()-4] != '.') - { - newTarget += ".exe"; - } -# endif // WIN32 -#endif + newTarget = { target }; } std::string config = mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); @@ -1752,14 +1773,16 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, config, false, fast, false, this->TryCompileTimeout); } -void cmGlobalGenerator::GenerateBuildCommand( - GeneratedMakeCommand& makeCommand, const std::string& /*unused*/, - const std::string& /*unused*/, const std::string& /*unused*/, +std::vector<cmGlobalGenerator::GeneratedMakeCommand> +cmGlobalGenerator::GenerateBuildCommand( const std::string& /*unused*/, const std::string& /*unused*/, - bool /*unused*/, int /*unused*/, bool /*unused*/, - std::vector<std::string> const& /*unused*/) + const std::string& /*unused*/, std::vector<std::string> const& /*unused*/, + const std::string& /*unused*/, bool /*unused*/, int /*unused*/, + bool /*unused*/, std::vector<std::string> const& /*unused*/) { - makeCommand.add("cmGlobalGenerator::GenerateBuildCommand not implemented"); + GeneratedMakeCommand makeCommand; + makeCommand.Add("cmGlobalGenerator::GenerateBuildCommand not implemented"); + return { std::move(makeCommand) }; } void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, @@ -1769,15 +1792,13 @@ void cmGlobalGenerator::PrintBuildCommandAdvice(std::ostream& /*os*/, // they do not support certain build command line options } -int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, - const std::string& bindir, - const std::string& projectName, - const std::string& target, std::string& output, - const std::string& makeCommandCSTR, - const std::string& config, bool clean, bool fast, - bool verbose, cmDuration timeout, - cmSystemTools::OutputOption outputflag, - std::vector<std::string> const& nativeOptions) +int cmGlobalGenerator::Build( + int jobs, const std::string& /*unused*/, const std::string& bindir, + const std::string& projectName, const std::vector<std::string>& targets, + std::string& output, const std::string& makeCommandCSTR, + const std::string& config, bool clean, bool fast, bool verbose, + cmDuration timeout, cmSystemTools::OutputOption outputflag, + std::vector<std::string> const& nativeOptions) { bool hideconsole = cmSystemTools::GetRunCommandHideConsole(); @@ -1798,32 +1819,37 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, return 1; } - int retVal; + int retVal = 0; cmSystemTools::SetRunCommandHideConsole(true); std::string outputBuffer; std::string* outputPtr = &outputBuffer; - GeneratedMakeCommand makeCommand; - this->GenerateBuildCommand(makeCommand, makeCommandCSTR, projectName, bindir, - target, config, fast, jobs, verbose, - nativeOptions); + std::vector<GeneratedMakeCommand> makeCommand = + this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets, + config, fast, jobs, verbose, nativeOptions); // Workaround to convince some commands to produce output. if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && - makeCommand.RequiresOutputForward) { + makeCommand.back().RequiresOutputForward) { outputflag = cmSystemTools::OUTPUT_FORWARD; } // should we do a clean first? if (clean) { - GeneratedMakeCommand cleanCommand; - this->GenerateBuildCommand(cleanCommand, makeCommandCSTR, projectName, - bindir, "clean", config, fast, jobs, verbose); + std::vector<GeneratedMakeCommand> cleanCommand = + this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, + { "clean" }, config, fast, jobs, verbose); output += "\nRun Clean Command:"; - output += cleanCommand.printable(); + output += cleanCommand.front().Printable(); output += "\n"; - - if (!cmSystemTools::RunSingleCommand(cleanCommand.PrimaryCommand, + if (cleanCommand.size() != 1) { + this->GetCMakeInstance()->IssueMessage(MessageType::INTERNAL_ERROR, + "The generator did not produce " + "exactly one command for the " + "'clean' target"); + return 1; + } + if (!cmSystemTools::RunSingleCommand(cleanCommand.front().PrimaryCommand, outputPtr, outputPtr, &retVal, nullptr, outputflag, timeout)) { cmSystemTools::SetRunCommandHideConsole(hideconsole); @@ -1837,33 +1863,34 @@ int cmGlobalGenerator::Build(int jobs, const std::string& /*unused*/, } // now build - std::string makeCommandStr = makeCommand.printable(); + std::string makeCommandStr; output += "\nRun Build Command(s):"; - output += makeCommandStr; - output += "\n"; - if (!cmSystemTools::RunSingleCommand(makeCommand.PrimaryCommand, outputPtr, - outputPtr, &retVal, nullptr, outputflag, - timeout)) { - cmSystemTools::SetRunCommandHideConsole(hideconsole); - cmSystemTools::Error( - "Generator: execution of make failed. Make command was: ", - makeCommandStr.c_str()); - output += *outputPtr; - output += "\nGenerator: execution of make failed. Make command was: " + - makeCommandStr + "\n"; + for (auto command = makeCommand.begin(); command != makeCommand.end(); + ++command) { + makeCommandStr = command->Printable(); + if (command != makeCommand.end()) { + makeCommandStr += " && "; + } - return 1; - } - output += *outputPtr; - cmSystemTools::SetRunCommandHideConsole(hideconsole); + output += makeCommandStr; + if (!cmSystemTools::RunSingleCommand(command->PrimaryCommand, outputPtr, + outputPtr, &retVal, nullptr, + outputflag, timeout)) { + cmSystemTools::SetRunCommandHideConsole(hideconsole); + cmSystemTools::Error( + "Generator: execution of make failed. Make command was: " + + makeCommandStr); + output += *outputPtr; + output += "\nGenerator: execution of make failed. Make command was: " + + makeCommandStr + "\n"; - // The SGI MipsPro 7.3 compiler does not return an error code when - // the source has a #error in it! This is a work-around for such - // compilers. - if ((retVal == 0) && (output.find("#error") != std::string::npos)) { - retVal = 1; + return 1; + } + output += *outputPtr; } + output += "\n"; + cmSystemTools::SetRunCommandHideConsole(hideconsole); // The OpenWatcom tools do not return an error code when a link // library is not found! @@ -2114,17 +2141,24 @@ void cmGlobalGenerator::IndexGeneratorTarget(cmGeneratorTarget* gt) } } +static char const hexDigits[] = "0123456789abcdef"; + std::string cmGlobalGenerator::IndexGeneratorTargetUniquely( cmGeneratorTarget const* gt) { // Use the pointer value to uniquely identify the target instance. - // Use a "T" prefix to indicate that this identifier is for a target. + // Use a ":" prefix to avoid conflict with project-defined targets. // We must satisfy cmGeneratorExpression::IsValidTargetName so use no // other special characters. - char buf[64]; - sprintf(buf, "::T%p", - static_cast<void const*>(gt)); // cast avoids format warning - std::string id = gt->GetName() + buf; + char buf[1 + sizeof(gt) * 2]; + char* b = buf; + *b++ = ':'; + for (size_t i = 0; i < sizeof(gt); ++i) { + unsigned char const c = reinterpret_cast<unsigned char const*>(>)[i]; + *b++ = hexDigits[(c & 0xf0) >> 4]; + *b++ = hexDigits[(c & 0x0f)]; + } + std::string id(buf, sizeof(buf)); // We internally index pointers to non-const generator targets // but our callers only have pointers to const generator targets. // They will give up non-const privileges when looking up anyway. @@ -2196,7 +2230,7 @@ cmGeneratorTarget* cmGlobalGenerator::FindGeneratorTarget( bool cmGlobalGenerator::NameResolvesToFramework( const std::string& libname) const { - if (cmSystemTools::IsPathToFramework(libname.c_str())) { + if (cmSystemTools::IsPathToFramework(libname)) { return true; } @@ -2277,10 +2311,9 @@ void cmGlobalGenerator::AddGlobalTarget_Package( return; } - const char* reservedTargets[] = { "package", "PACKAGE" }; - for (const char* const* tn = cm::cbegin(reservedTargets); - tn != cm::cend(reservedTargets); ++tn) { - if (!this->CheckCMP0037(*tn, "when CPack packaging is enabled")) { + static const auto reservedTargets = { "package", "PACKAGE" }; + for (auto const& target : reservedTargets) { + if (!this->CheckCMP0037(target, "when CPack packaging is enabled")) { return; } } @@ -2327,10 +2360,10 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource( return; } - const char* reservedTargets[] = { "package_source" }; - for (const char* const* tn = cm::cbegin(reservedTargets); - tn != cm::cend(reservedTargets); ++tn) { - if (!this->CheckCMP0037(*tn, "when CPack source packaging is enabled")) { + static const auto reservedTargets = { "package_source" }; + for (auto const& target : reservedTargets) { + if (!this->CheckCMP0037(target, + "when CPack source packaging is enabled")) { return; } } @@ -2357,10 +2390,9 @@ void cmGlobalGenerator::AddGlobalTarget_Test( return; } - const char* reservedTargets[] = { "test", "RUN_TESTS" }; - for (const char* const* tn = cm::cbegin(reservedTargets); - tn != cm::cend(reservedTargets); ++tn) { - if (!this->CheckCMP0037(*tn, "when CTest testing is enabled")) { + static const auto reservedTargets = { "test", "RUN_TESTS" }; + for (auto const& target : reservedTargets) { + if (!this->CheckCMP0037(target, "when CTest testing is enabled")) { return; } } @@ -2983,10 +3015,8 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target) } std::vector<cmSourceFile*>::const_iterator sourcesEnd = cmRemoveDuplicates(sources); - for (std::vector<cmSourceFile*>::const_iterator si = sources.begin(); - si != sourcesEnd; ++si) { + for (cmSourceFile* sf : cmMakeRange(sources.cbegin(), sourcesEnd)) { Json::Value& lj_source = lj_sources.append(Json::objectValue); - cmSourceFile* sf = *si; std::string const& sfp = sf->GetFullPath(); fout << sfp << "\n"; lj_source["file"] = sfp; |