diff options
Diffstat (limited to 'Source/cmake.cxx')
-rw-r--r-- | Source/cmake.cxx | 201 |
1 files changed, 143 insertions, 58 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx index fd7151f..5620723 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -7,6 +7,7 @@ #include "cmDocumentation.h" #include "cmDocumentationEntry.h" #include "cmDocumentationFormatter.h" +#include "cmDuration.h" #include "cmExternalMakefileProjectGenerator.h" #include "cmFileTimeComparison.h" #include "cmGeneratorTarget.h" @@ -34,14 +35,6 @@ #include <unordered_map> #endif -// only build kdevelop generator on non-windows platforms -// when not bootstrapping cmake -#if !defined(_WIN32) -#if defined(CMAKE_BUILD_WITH_CMAKE) -#define CMAKE_USE_KDEVELOP -#endif -#endif - #if defined(CMAKE_BUILD_WITH_CMAKE) #define CMAKE_USE_ECLIPSE #endif @@ -87,10 +80,6 @@ #include "cmExtraKateGenerator.h" #include "cmExtraSublimeTextGenerator.h" -#ifdef CMAKE_USE_KDEVELOP -#include "cmGlobalKdevelopGenerator.h" -#endif - #ifdef CMAKE_USE_ECLIPSE #include "cmExtraEclipseCDT4Generator.h" #endif @@ -110,6 +99,7 @@ #include "cmsys/RegularExpression.hxx" #include <algorithm> #include <iostream> +#include <iterator> #include <memory> // IWYU pragma: keep #include <sstream> #include <stdio.h> @@ -195,10 +185,16 @@ cmake::cmake(Role role) this->SourceFileExtensions.push_back("cc"); this->SourceFileExtensions.push_back("cpp"); this->SourceFileExtensions.push_back("cxx"); + this->SourceFileExtensions.push_back("cu"); this->SourceFileExtensions.push_back("m"); this->SourceFileExtensions.push_back("M"); this->SourceFileExtensions.push_back("mm"); + std::copy(this->SourceFileExtensions.begin(), + this->SourceFileExtensions.end(), + std::inserter(this->SourceFileExtensionsSet, + this->SourceFileExtensionsSet.end())); + this->HeaderFileExtensions.push_back("h"); this->HeaderFileExtensions.push_back("hh"); this->HeaderFileExtensions.push_back("h++"); @@ -207,6 +203,11 @@ cmake::cmake(Role role) this->HeaderFileExtensions.push_back("hxx"); this->HeaderFileExtensions.push_back("in"); this->HeaderFileExtensions.push_back("txx"); + + std::copy(this->HeaderFileExtensions.begin(), + this->HeaderFileExtensions.end(), + std::inserter(this->HeaderFileExtensionsSet, + this->HeaderFileExtensionsSet.end())); } cmake::~cmake() @@ -486,7 +487,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args, if (this->GetWorkingMode() != NORMAL_MODE) { std::string file(cmSystemTools::CollapseFullPath(path)); cmSystemTools::ConvertToUnixSlashes(file); - mf.SetScriptModeFile(file.c_str()); + mf.SetScriptModeFile(file); mf.SetArgcArgv(args); } @@ -744,8 +745,13 @@ void cmake::SetArgs(const std::vector<std::string>& args, } cmGlobalGenerator* gen = this->CreateGlobalGenerator(value); if (!gen) { + const char* kdevError = nullptr; + if (value.find("KDevelop3", 0) != std::string::npos) { + kdevError = "\nThe KDevelop3 generator is not supported anymore."; + } + cmSystemTools::Error("Could not create named generator ", - value.c_str()); + value.c_str(), kdevError); this->PrintGeneratorList(); } else { this->SetGlobalGenerator(gen); @@ -777,10 +783,10 @@ void cmake::SetDirectoriesFromFile(const char* arg) cacheFile += "/CMakeCache.txt"; std::string listFile = path; listFile += "/CMakeLists.txt"; - if (cmSystemTools::FileExists(cacheFile.c_str())) { + if (cmSystemTools::FileExists(cacheFile)) { cachePath = path; } - if (cmSystemTools::FileExists(listFile.c_str())) { + if (cmSystemTools::FileExists(listFile)) { listPath = path; } } else if (cmSystemTools::FileExists(arg)) { @@ -863,7 +869,7 @@ int cmake::AddCMakePaths() "Path to cpack program executable.", cmStateEnums::INTERNAL); #endif if (!cmSystemTools::FileExists( - (cmSystemTools::GetCMakeRoot() + "/Modules/CMake.cmake").c_str())) { + (cmSystemTools::GetCMakeRoot() + "/Modules/CMake.cmake"))) { // couldn't find modules cmSystemTools::Error( "Could not find CMAKE_ROOT !!!\n" @@ -890,9 +896,6 @@ void cmake::AddDefaultExtraGenerators() this->ExtraGenerators.push_back(cmExtraEclipseCDT4Generator::GetFactory()); #endif -#ifdef CMAKE_USE_KDEVELOP - this->ExtraGenerators.push_back(cmGlobalKdevelopGenerator::GetFactory()); -#endif #endif } @@ -910,7 +913,7 @@ void cmake::GetRegisteredGenerators( info.name = name; info.baseName = name; info.isAlias = false; - generators.push_back(info); + generators.push_back(std::move(info)); } } @@ -926,7 +929,7 @@ void cmake::GetRegisteredGenerators( info.supportsPlatform = false; info.supportsToolset = false; info.isAlias = false; - generators.push_back(info); + generators.push_back(std::move(info)); } for (std::string const& a : eg->Aliases) { GeneratorInfo info; @@ -938,7 +941,7 @@ void cmake::GetRegisteredGenerators( info.supportsPlatform = false; info.supportsToolset = false; info.isAlias = true; - generators.push_back(info); + generators.push_back(std::move(info)); } } } @@ -1000,7 +1003,7 @@ void cmake::SetHomeDirectory(const std::string& dir) } } -const char* cmake::GetHomeDirectory() const +std::string const& cmake::GetHomeDirectory() const { return this->State->GetSourceDirectory(); } @@ -1013,7 +1016,7 @@ void cmake::SetHomeOutputDirectory(const std::string& dir) } } -const char* cmake::GetHomeOutputDirectory() const +std::string const& cmake::GetHomeOutputDirectory() const { return this->State->GetBinaryDirectory(); } @@ -1024,11 +1027,11 @@ std::string cmake::FindCacheFile(const std::string& binaryDir) cmSystemTools::ConvertToUnixSlashes(cachePath); std::string cacheFile = cachePath; cacheFile += "/CMakeCache.txt"; - if (!cmSystemTools::FileExists(cacheFile.c_str())) { + if (!cmSystemTools::FileExists(cacheFile)) { // search in parent directories for cache std::string cmakeFiles = cachePath; cmakeFiles += "/CMakeFiles"; - if (cmSystemTools::FileExists(cmakeFiles.c_str())) { + if (cmSystemTools::FileExists(cmakeFiles)) { std::string cachePathFound = cmSystemTools::FileExistsInParentDirectories("CMakeCache.txt", cachePath.c_str(), "/"); @@ -1084,7 +1087,7 @@ int cmake::DoPreConfigureChecks() // Make sure the Source directory contains a CMakeLists.txt file. std::string srcList = this->GetHomeDirectory(); srcList += "/CMakeLists.txt"; - if (!cmSystemTools::FileExists(srcList.c_str())) { + if (!cmSystemTools::FileExists(srcList)) { std::ostringstream err; if (cmSystemTools::FileIsDirectory(this->GetHomeDirectory())) { err << "The source directory \"" << this->GetHomeDirectory() @@ -1165,7 +1168,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var) save.help = help; } } - saved.push_back(save); + saved.push_back(std::move(save)); } // remove the cache @@ -1269,7 +1272,7 @@ int cmake::ActualConfigure() } if (!res) { this->AddCacheEntry( - "CMAKE_HOME_DIRECTORY", this->GetHomeDirectory(), + "CMAKE_HOME_DIRECTORY", this->GetHomeDirectory().c_str(), "Source directory with the top level CMakeLists.txt file for this " "project", cmStateEnums::INTERNAL); @@ -1326,6 +1329,25 @@ int cmake::ActualConfigure() cmStateEnums::INTERNAL); } + if (const char* instance = + this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) { + if (!this->GeneratorInstance.empty() && + this->GeneratorInstance != instance) { + std::string message = "Error: generator instance: "; + message += this->GeneratorInstance; + message += "\nDoes not match the instance used previously: "; + message += instance; + message += "\nEither remove the CMakeCache.txt file and CMakeFiles " + "directory or choose a different binary directory."; + cmSystemTools::Error(message.c_str()); + return -2; + } + } else { + this->AddCacheEntry( + "CMAKE_GENERATOR_INSTANCE", this->GeneratorInstance.c_str(), + "Generator instance identifier.", cmStateEnums::INTERNAL); + } + if (const char* platformName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) { if (!this->GeneratorPlatform.empty() && @@ -1453,12 +1475,12 @@ void cmake::CreateDefaultGlobalGenerator() if (vsSetupAPIHelper.IsVS2017Installed()) { found = "Visual Studio 15 2017"; } else { - for (VSVersionedGenerator const* g = cmArrayBegin(vsGenerators); - found.empty() && g != cmArrayEnd(vsGenerators); ++g) { - for (const char* const* v = cmArrayBegin(vsVariants); - found.empty() && v != cmArrayEnd(vsVariants); ++v) { - for (const char* const* e = cmArrayBegin(vsEntries); - found.empty() && e != cmArrayEnd(vsEntries); ++e) { + for (VSVersionedGenerator const* g = cm::cbegin(vsGenerators); + found.empty() && g != cm::cend(vsGenerators); ++g) { + for (const char* const* v = cm::cbegin(vsVariants); + found.empty() && v != cm::cend(vsVariants); ++v) { + for (const char* const* e = cm::cbegin(vsEntries); + found.empty() && e != cm::cend(vsEntries); ++e) { std::string const reg = vsregBase + *v + g->MSVersion + *e; std::string dir; if (cmSystemTools::ReadRegistryValue(reg, dir, @@ -1487,14 +1509,14 @@ void cmake::PreLoadCMakeFiles() std::string pre_load = this->GetHomeDirectory(); if (!pre_load.empty()) { pre_load += "/PreLoad.cmake"; - if (cmSystemTools::FileExists(pre_load.c_str())) { + if (cmSystemTools::FileExists(pre_load)) { this->ReadListFile(args, pre_load.c_str()); } } pre_load = this->GetHomeOutputDirectory(); if (!pre_load.empty()) { pre_load += "/PreLoad.cmake"; - if (cmSystemTools::FileExists(pre_load.c_str())) { + if (cmSystemTools::FileExists(pre_load)) { this->ReadListFile(args, pre_load.c_str()); } } @@ -1627,6 +1649,21 @@ void cmake::AddCacheEntry(const std::string& key, const char* value, this->UnwatchUnusedCli(key); } +std::string cmake::StripExtension(const std::string& file) const +{ + auto dotpos = file.rfind('.'); + if (dotpos != std::string::npos) { + auto ext = file.substr(dotpos + 1); +#if defined(_WIN32) || defined(__APPLE__) + ext = cmSystemTools::LowerCase(ext); +#endif + if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) { + return file.substr(0, dotpos); + } + } + return file; +} + const char* cmake::GetCacheDefinition(const std::string& name) const { return this->State->GetInitializedCacheValue(name); @@ -1687,7 +1724,7 @@ int cmake::LoadCache() // if it does exist, but isn't readable then warn the user std::string cacheFile = this->GetHomeOutputDirectory(); cacheFile += "/CMakeCache.txt"; - if (cmSystemTools::FileExists(cacheFile.c_str())) { + if (cmSystemTools::FileExists(cacheFile)) { cmSystemTools::Error( "There is a CMakeCache.txt file for the current binary tree but " "cmake does not have permission to read it. Please check the " @@ -1716,8 +1753,8 @@ bool cmake::LoadCache(const std::string& path, bool internal, bool result = this->State->LoadCache(path, internal, excludes, includes); static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION", "CMAKE_CACHE_MINOR_VERSION" }; - for (const char* const* nameIt = cmArrayBegin(entries); - nameIt != cmArrayEnd(entries); ++nameIt) { + for (const char* const* nameIt = cm::cbegin(entries); + nameIt != cm::cend(entries); ++nameIt) { this->UnwatchUnusedCli(*nameIt); } return result; @@ -1725,13 +1762,13 @@ bool cmake::LoadCache(const std::string& path, bool internal, bool cmake::SaveCache(const std::string& path) { - bool result = this->State->SaveCache(path); + bool result = this->State->SaveCache(path, this->GetMessenger()); static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION", "CMAKE_CACHE_MINOR_VERSION", "CMAKE_CACHE_PATCH_VERSION", "CMAKE_CACHEFILE_DIR" }; - for (const char* const* nameIt = cmArrayBegin(entries); - nameIt != cmArrayEnd(entries); ++nameIt) { + for (const char* const* nameIt = cm::cbegin(entries); + nameIt != cm::cend(entries); ++nameIt) { this->UnwatchUnusedCli(*nameIt); } return result; @@ -1771,7 +1808,7 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v) for (cmGlobalGeneratorFactory* g : this->Generators) { cmDocumentationEntry e; g->GetDocumentation(e); - v.push_back(e); + v.push_back(std::move(e)); } for (cmExternalMakefileProjectGeneratorFactory* eg : this->ExtraGenerators) { const std::string doc = eg->GetDocumentation(); @@ -1782,7 +1819,7 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v) cmDocumentationEntry e; e.Name = a; e.Brief = doc; - v.push_back(e); + v.push_back(std::move(e)); } // Full names: @@ -1793,7 +1830,7 @@ void cmake::GetGeneratorDocumentation(std::vector<cmDocumentationEntry>& v) e.Name = cmExternalMakefileProjectGenerator::CreateFullGeneratorName(g, name); e.Brief = doc; - v.push_back(e); + v.push_back(std::move(e)); } } } @@ -1854,7 +1891,7 @@ int cmake::CheckBuildSystem() } // If the file provided does not exist, we have to rerun. - if (!cmSystemTools::FileExists(this->CheckBuildSystemArgument.c_str())) { + if (!cmSystemTools::FileExists(this->CheckBuildSystemArgument)) { if (verbose) { std::ostringstream msg; msg << "Re-run cmake missing file: " << this->CheckBuildSystemArgument @@ -1908,8 +1945,7 @@ int cmake::CheckBuildSystem() cmSystemTools::ExpandListArgument(productStr, products); } for (std::string const& p : products) { - if (!(cmSystemTools::FileExists(p.c_str()) || - cmSystemTools::FileIsSymlink(p))) { + if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) { if (verbose) { std::ostringstream msg; msg << "Re-run cmake, missing byproduct: " << p << "\n"; @@ -2107,7 +2143,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); std::string destPath = cwd + "/__cmake_systeminformation"; cmSystemTools::RemoveADirectory(destPath); - if (!cmSystemTools::MakeDirectory(destPath.c_str())) { + if (!cmSystemTools::MakeDirectory(destPath)) { std::cerr << "Error: --system-information must be run from a " "writable directory!\n"; return 1; @@ -2139,7 +2175,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) } // no option assume it is the output file else { - if (!cmSystemTools::FileIsFullPath(arg.c_str())) { + if (!cmSystemTools::FileIsFullPath(arg)) { resultFile = cwd; resultFile += "/"; } @@ -2176,9 +2212,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) std::vector<std::string> args2; args2.push_back(args[0]); args2.push_back(destPath); - std::string resultArg = "-DRESULT_FILE="; - resultArg += resultFile; - args2.push_back(resultArg); + args2.push_back("-DRESULT_FILE=" + resultFile); int res = this->Run(args2, false); if (res != 0) { @@ -2360,6 +2394,14 @@ int cmake::Build(const std::string& dir, const std::string& target, << "\"\n"; return 1; } + const char* cachedGeneratorInstance = + this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE"); + if (cachedGeneratorInstance) { + cmMakefile mf(gen.get(), this->GetCurrentSnapshot()); + if (!gen->SetGeneratorInstance(cachedGeneratorInstance, &mf)) { + return 1; + } + } std::string output; std::string projName; const char* cachedProjectName = @@ -2386,7 +2428,7 @@ int cmake::Build(const std::string& dir, const std::string& target, cmGlobalVisualStudio8Generator::GetGenerateStampList(); // Note that the stampList file only exists for VS generators. - if (cmSystemTools::FileExists(stampList.c_str()) && + if (cmSystemTools::FileExists(stampList) && !cmakeCheckStampList(stampList.c_str(), false)) { // Correctly initialize the home (=source) and home output (=binary) @@ -2421,8 +2463,51 @@ int cmake::Build(const std::string& dir, const std::string& target, #endif return gen->Build("", dir, projName, target, output, "", config, clean, - false, verbose, 0, cmSystemTools::OUTPUT_PASSTHROUGH, - nativeOptions); + false, verbose, cmDuration::zero(), + cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); +} + +bool cmake::Open(const std::string& dir, bool dryRun) +{ + this->SetHomeDirectory(""); + this->SetHomeOutputDirectory(""); + if (!cmSystemTools::FileIsDirectory(dir)) { + std::cerr << "Error: " << dir << " is not a directory\n"; + return false; + } + + std::string cachePath = FindCacheFile(dir); + if (!this->LoadCache(cachePath)) { + std::cerr << "Error: could not load cache\n"; + return false; + } + const char* genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR"); + if (!genName) { + std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n"; + return false; + } + const char* extraGenName = + this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR"); + std::string fullName = + cmExternalMakefileProjectGenerator::CreateFullGeneratorName( + genName, extraGenName ? extraGenName : ""); + + std::unique_ptr<cmGlobalGenerator> gen( + this->CreateGlobalGenerator(fullName)); + if (!gen.get()) { + std::cerr << "Error: could create CMAKE_GENERATOR \"" << fullName + << "\"\n"; + return false; + } + + const char* cachedProjectName = + this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME"); + if (!cachedProjectName) { + std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n"; + return false; + } + + return gen->Open(dir, cachedProjectName, dryRun); } void cmake::WatchUnusedCli(const std::string& var) |