summaryrefslogtreecommitdiff
path: root/Source/cmake.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmake.cxx')
-rw-r--r--Source/cmake.cxx201
1 files changed, 143 insertions, 58 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index fd7151f08..562072302 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)