summaryrefslogtreecommitdiffstats
path: root/Source/cmake.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmake.cxx')
-rw-r--r--Source/cmake.cxx249
1 files changed, 188 insertions, 61 deletions
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index fda7900..7de488b 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -28,8 +28,9 @@
#include "cm_sys_stat.h"
+#include "cmBuildOptions.h"
#include "cmCMakePath.h"
-#include "cmCMakePresetsFile.h"
+#include "cmCMakePresetsGraph.h"
#include "cmCommandLineArgument.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
@@ -205,7 +206,7 @@ cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
exts.ordered.reserve(extList.size());
for (cm::string_view ext : extList) {
exts.ordered.emplace_back(ext);
- };
+ }
// Fill unordered set
exts.unordered.insert(exts.ordered.begin(), exts.ordered.end());
};
@@ -543,6 +544,10 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
"-C", "-C must be followed by a file name.",
CommandArgument::Values::One, CommandArgument::RequiresSeparator::No,
[&](std::string const& value, cmake* state) -> bool {
+ if (value.empty()) {
+ cmSystemTools::Error("No file name specified for -C");
+ return false;
+ }
cmSystemTools::Stdout("loading initial cache file " + value + "\n");
// Resolve script path specified on command line
// relative to $PWD.
@@ -790,6 +795,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
bool haveBArg = false;
bool scriptMode = false;
std::string possibleUnknownArg;
+ std::string extraProvidedPath;
#if !defined(CMAKE_BOOTSTRAP)
std::string profilingFormat;
std::string profilingOutput;
@@ -798,14 +804,30 @@ void cmake::SetArgs(const std::vector<std::string>& args)
ListPresets listPresets = ListPresets::None;
#endif
+ auto EmptyStringArgLambda = [](std::string const&, cmake* state) -> bool {
+ state->IssueMessage(
+ MessageType::WARNING,
+ "Ignoring empty string (\"\") provided on the command line.");
+ return true;
+ };
+
auto SourceArgLambda = [](std::string const& value, cmake* state) -> bool {
+ if (value.empty()) {
+ cmSystemTools::Error("No source directory specified for -S");
+ return false;
+ }
std::string path = cmSystemTools::CollapseFullPath(value);
cmSystemTools::ConvertToUnixSlashes(path);
- state->SetHomeDirectory(path);
+
+ state->SetHomeDirectoryViaCommandLine(path);
return true;
};
auto BuildArgLambda = [&](std::string const& value, cmake* state) -> bool {
+ if (value.empty()) {
+ cmSystemTools::Error("No build directory specified for -B");
+ return false;
+ }
std::string path = cmSystemTools::CollapseFullPath(value);
cmSystemTools::ConvertToUnixSlashes(path);
state->SetHomeOutputDirectory(path);
@@ -834,6 +856,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
};
std::vector<CommandArgument> arguments = {
+ CommandArgument{ "", CommandArgument::Values::Zero, EmptyStringArgLambda },
CommandArgument{ "-S", "No source directory specified for -S",
CommandArgument::Values::One,
CommandArgument::RequiresSeparator::No, SourceArgLambda },
@@ -968,7 +991,34 @@ void cmake::SetArgs(const std::vector<std::string>& args)
"--debug-find", CommandArgument::Values::Zero,
[](std::string const&, cmake* state) -> bool {
std::cout << "Running with debug output on for the `find` commands.\n";
- state->SetDebugFindOutputOn(true);
+ state->SetDebugFindOutput(true);
+ return true;
+ } },
+ CommandArgument{
+ "--debug-find-pkg", "Provide a package argument for --debug-find-pkg",
+ CommandArgument::Values::One, CommandArgument::RequiresSeparator::Yes,
+ [](std::string const& value, cmake* state) -> bool {
+ std::vector<std::string> find_pkgs(cmTokenize(value, ","));
+ std::cout << "Running with debug output on for the 'find' commands "
+ "for package(s)";
+ for (auto const& v : find_pkgs) {
+ std::cout << " " << v;
+ state->SetDebugFindOutputPkgs(v);
+ }
+ std::cout << ".\n";
+ return true;
+ } },
+ CommandArgument{
+ "--debug-find-var", CommandArgument::Values::One,
+ CommandArgument::RequiresSeparator::Yes,
+ [](std::string const& value, cmake* state) -> bool {
+ std::vector<std::string> find_vars(cmTokenize(value, ","));
+ std::cout << "Running with debug output on for the variable(s)";
+ for (auto const& v : find_vars) {
+ std::cout << " " << v;
+ state->SetDebugFindOutputVars(v);
+ }
+ std::cout << ".\n";
return true;
} },
CommandArgument{ "--trace-expand", CommandArgument::Values::Zero,
@@ -1141,10 +1191,18 @@ void cmake::SetArgs(const std::vector<std::string>& args)
} else if (!matched && cmHasLiteralPrefix(arg, "-")) {
possibleUnknownArg = arg;
} else if (!matched) {
- this->SetDirectoriesFromFile(arg);
+ bool parsedDirectory = this->SetDirectoriesFromFile(arg);
+ if (!parsedDirectory) {
+ extraProvidedPath = arg;
+ }
}
}
+ if (!extraProvidedPath.empty() && !scriptMode) {
+ this->IssueMessage(MessageType::WARNING,
+ cmStrCat("Ignoring extra path from command line:\n \"",
+ extraProvidedPath, "\""));
+ }
if (!possibleUnknownArg.empty() && !scriptMode) {
cmSystemTools::Error(cmStrCat("Unknown argument ", possibleUnknownArg));
cmSystemTools::Error("Run 'cmake --help' for all supported options.");
@@ -1212,43 +1270,43 @@ void cmake::SetArgs(const std::vector<std::string>& args)
#if !defined(CMAKE_BOOTSTRAP)
if (listPresets != ListPresets::None || !presetName.empty()) {
- cmCMakePresetsFile settingsFile;
- auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
- if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) {
+ cmCMakePresetsGraph presetsGraph;
+ auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory());
+ if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
cmSystemTools::Error(
cmStrCat("Could not read presets from ", this->GetHomeDirectory(),
- ": ", cmCMakePresetsFile::ResultToString(result)));
+ ": ", cmCMakePresetsGraph::ResultToString(result)));
return;
}
if (listPresets != ListPresets::None) {
if (listPresets == ListPresets::Configure) {
- this->PrintPresetList(settingsFile);
+ this->PrintPresetList(presetsGraph);
} else if (listPresets == ListPresets::Build) {
- settingsFile.PrintBuildPresetList();
+ presetsGraph.PrintBuildPresetList();
} else if (listPresets == ListPresets::Test) {
- settingsFile.PrintTestPresetList();
+ presetsGraph.PrintTestPresetList();
} else if (listPresets == ListPresets::All) {
- settingsFile.PrintAllPresets();
+ presetsGraph.PrintAllPresets();
}
this->SetWorkingMode(WorkingMode::HELP_MODE);
return;
}
- auto preset = settingsFile.ConfigurePresets.find(presetName);
- if (preset == settingsFile.ConfigurePresets.end()) {
+ auto preset = presetsGraph.ConfigurePresets.find(presetName);
+ if (preset == presetsGraph.ConfigurePresets.end()) {
cmSystemTools::Error(cmStrCat("No such preset in ",
this->GetHomeDirectory(), ": \"",
presetName, '"'));
- this->PrintPresetList(settingsFile);
+ this->PrintPresetList(presetsGraph);
return;
}
if (preset->second.Unexpanded.Hidden) {
cmSystemTools::Error(cmStrCat("Cannot use hidden preset in ",
this->GetHomeDirectory(), ": \"",
presetName, '"'));
- this->PrintPresetList(settingsFile);
+ this->PrintPresetList(presetsGraph);
return;
}
auto const& expandedPreset = preset->second.Expanded;
@@ -1292,14 +1350,14 @@ void cmake::SetArgs(const std::vector<std::string>& args)
if (!expandedPreset->ArchitectureStrategy ||
expandedPreset->ArchitectureStrategy ==
- cmCMakePresetsFile::ArchToolsetStrategy::Set) {
+ cmCMakePresetsGraph::ArchToolsetStrategy::Set) {
if (!this->GeneratorPlatformSet) {
this->SetGeneratorPlatform(expandedPreset->Architecture);
}
}
if (!expandedPreset->ToolsetStrategy ||
expandedPreset->ToolsetStrategy ==
- cmCMakePresetsFile::ArchToolsetStrategy::Set) {
+ cmCMakePresetsGraph::ArchToolsetStrategy::Set) {
if (!this->GeneratorToolsetSet) {
this->SetGeneratorToolset(expandedPreset->Toolset);
}
@@ -1325,7 +1383,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
this->DebugTryCompileOn();
}
if (expandedPreset->DebugFind == true) {
- this->SetDebugFindOutputOn(true);
+ this->SetDebugFindOutput(true);
}
}
#endif
@@ -1423,26 +1481,31 @@ void cmake::PrintTraceFormatVersion()
}
}
-void cmake::SetDirectoriesFromFile(const std::string& arg)
+bool cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
// CMakeLists.txt file.
std::string listPath;
std::string cachePath;
- bool argIsFile = false;
+ bool is_source_dir = false;
+ bool is_empty_directory = false;
if (cmSystemTools::FileIsDirectory(arg)) {
std::string path = cmSystemTools::CollapseFullPath(arg);
cmSystemTools::ConvertToUnixSlashes(path);
std::string cacheFile = cmStrCat(path, "/CMakeCache.txt");
std::string listFile = cmStrCat(path, "/CMakeLists.txt");
+
+ is_empty_directory = true;
if (cmSystemTools::FileExists(cacheFile)) {
cachePath = path;
+ is_empty_directory = false;
}
if (cmSystemTools::FileExists(listFile)) {
listPath = path;
+ is_empty_directory = false;
+ is_source_dir = true;
}
} else if (cmSystemTools::FileExists(arg)) {
- argIsFile = true;
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
@@ -1458,7 +1521,6 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
if (name == "cmakecache.txt"_s || name == "cmakelists.txt"_s) {
- argIsFile = true;
listPath = cmSystemTools::GetFilenamePath(fullPath);
} else {
listPath = fullPath;
@@ -1473,42 +1535,60 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
if (existingValue) {
this->SetHomeOutputDirectory(cachePath);
this->SetHomeDirectory(*existingValue);
- return;
+ return true;
}
}
}
+ bool no_source_tree = this->GetHomeDirectory().empty();
+ bool no_build_tree = this->GetHomeOutputDirectory().empty();
+
+ // When invoked with a path that points to an existing CMakeCache
+ // This function is called multiple times with the same path
+ const bool passed_same_path = (listPath == this->GetHomeDirectory()) ||
+ (listPath == this->GetHomeOutputDirectory());
+ bool used_provided_path =
+ (passed_same_path || is_source_dir || no_build_tree);
+
// If there is a CMakeLists.txt file, use it as the source tree.
if (!listPath.empty()) {
- this->SetHomeDirectory(listPath);
-
- if (argIsFile) {
- // Source CMakeLists.txt file given. It was probably dropped
- // onto the executable in a GUI. Default to an in-source build.
- this->SetHomeOutputDirectory(listPath);
- } else {
- // Source directory given on command line. Use current working
- // directory as build tree if -B hasn't been given already
- if (this->GetHomeOutputDirectory().empty()) {
+ // When invoked with a path that points to an existing CMakeCache
+ // This function is called multiple times with the same path
+ if (is_source_dir) {
+ this->SetHomeDirectoryViaCommandLine(listPath);
+ if (no_build_tree) {
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
this->SetHomeOutputDirectory(cwd);
}
+ } else if (no_source_tree && no_build_tree) {
+ this->SetHomeDirectory(listPath);
+
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ this->SetHomeOutputDirectory(cwd);
+ } else if (no_build_tree) {
+ this->SetHomeOutputDirectory(listPath);
+ }
+ } else {
+ if (no_source_tree) {
+ // We didn't find a CMakeLists.txt and it wasn't specified
+ // with -S. Assume it is the path to the source tree
+ std::string full = cmSystemTools::CollapseFullPath(arg);
+ this->SetHomeDirectory(full);
+ }
+ if (no_build_tree && !no_source_tree && is_empty_directory) {
+ // passed `-S <path> <build_dir> when build_dir is an empty directory
+ std::string full = cmSystemTools::CollapseFullPath(arg);
+ this->SetHomeOutputDirectory(full);
+ } else if (no_build_tree) {
+ // We didn't find a CMakeCache.txt and it wasn't specified
+ // with -B. Assume the current working directory as the build tree.
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ this->SetHomeOutputDirectory(cwd);
+ used_provided_path = false;
}
- return;
}
- if (this->GetHomeDirectory().empty()) {
- // We didn't find a CMakeLists.txt and it wasn't specified
- // with -S. Assume it is the path to the source tree
- std::string full = cmSystemTools::CollapseFullPath(arg);
- this->SetHomeDirectory(full);
- }
- if (this->GetHomeOutputDirectory().empty()) {
- // We didn't find a CMakeCache.txt and it wasn't specified
- // with -B. Assume the current working directory as the build tree.
- std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
- this->SetHomeOutputDirectory(cwd);
- }
+ return used_provided_path;
}
// at the end of this CMAKE_ROOT and CMAKE_COMMAND should be added to the
@@ -1680,12 +1760,12 @@ bool cmake::CreateAndSetGlobalGenerator(const std::string& name,
}
#ifndef CMAKE_BOOTSTRAP
-void cmake::PrintPresetList(const cmCMakePresetsFile& file) const
+void cmake::PrintPresetList(const cmCMakePresetsGraph& graph) const
{
std::vector<GeneratorInfo> generators;
this->GetRegisteredGenerators(generators, false);
auto filter =
- [&generators](const cmCMakePresetsFile::ConfigurePreset& preset) -> bool {
+ [&generators](const cmCMakePresetsGraph::ConfigurePreset& preset) -> bool {
if (preset.Generator.empty()) {
return true;
}
@@ -1696,16 +1776,37 @@ void cmake::PrintPresetList(const cmCMakePresetsFile& file) const
return it != generators.end();
};
- file.PrintConfigurePresetList(filter);
+ graph.PrintConfigurePresetList(filter);
}
#endif
+void cmake::SetHomeDirectoryViaCommandLine(std::string const& path)
+{
+ if (path.empty()) {
+ return;
+ }
+
+ auto prev_path = this->GetHomeDirectory();
+ if (prev_path != path && !prev_path.empty()) {
+ this->IssueMessage(MessageType::WARNING,
+ cmStrCat("Ignoring extra path from command line:\n \"",
+ prev_path, "\""));
+ }
+ this->SetHomeDirectory(path);
+}
+
void cmake::SetHomeDirectory(const std::string& dir)
{
this->State->SetSourceDirectory(dir);
if (this->CurrentSnapshot.IsValid()) {
this->CurrentSnapshot.SetDefinition("CMAKE_SOURCE_DIR", dir);
}
+
+ if (this->State->GetProjectKind() == cmState::ProjectKind::Normal) {
+ this->Messenger->SetTopSource(this->GetHomeDirectory());
+ } else {
+ this->Messenger->SetTopSource(cm::nullopt);
+ }
}
std::string const& cmake::GetHomeDirectory() const
@@ -2155,7 +2256,8 @@ int cmake::ActualConfigure()
"CMakeLists.txt ?");
}
- this->State->SaveVerificationScript(this->GetHomeOutputDirectory());
+ this->State->SaveVerificationScript(this->GetHomeOutputDirectory(),
+ this->Messenger.get());
this->SaveCache(this->GetHomeOutputDirectory());
if (cmSystemTools::GetErrorOccuredFlag()) {
return -1;
@@ -2452,7 +2554,7 @@ void cmake::AddGlobCacheEntry(bool recurse, bool listDirectories,
{
this->State->AddGlobCacheEntry(recurse, listDirectories, followSymlinks,
relative, expression, files, variable,
- backtrace);
+ backtrace, this->Messenger.get());
}
std::vector<std::string> cmake::GetAllExtensions() const
@@ -3185,8 +3287,8 @@ std::vector<std::string> cmake::GetDebugConfigs()
int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
std::string config, std::vector<std::string> nativeOptions,
- bool clean, bool verbose, const std::string& presetName,
- bool listPresets)
+ cmBuildOptions& buildOptions, bool verbose,
+ const std::string& presetName, bool listPresets)
{
this->SetHomeDirectory("");
this->SetHomeOutputDirectory("");
@@ -3196,12 +3298,12 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- cmCMakePresetsFile settingsFile;
+ cmCMakePresetsGraph settingsFile;
auto result = settingsFile.ReadProjectPresets(this->GetHomeDirectory());
- if (result != cmCMakePresetsFile::ReadFileResult::READ_OK) {
+ if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
cmSystemTools::Error(
cmStrCat("Could not read presets from ", this->GetHomeDirectory(),
- ": ", cmCMakePresetsFile::ResultToString(result)));
+ ": ", cmCMakePresetsGraph::ResultToString(result)));
return 1;
}
@@ -3292,8 +3394,13 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
config = expandedPreset->Configuration;
}
- if (!clean && expandedPreset->CleanFirst) {
- clean = *expandedPreset->CleanFirst;
+ if (!buildOptions.Clean && expandedPreset->CleanFirst) {
+ buildOptions.Clean = *expandedPreset->CleanFirst;
+ }
+
+ if (buildOptions.ResolveMode == PackageResolveMode::Default &&
+ expandedPreset->ResolvePackageReferences) {
+ buildOptions.ResolveMode = *expandedPreset->ResolvePackageReferences;
}
if (!verbose && expandedPreset->Verbose) {
@@ -3432,7 +3539,7 @@ int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs);
return this->GlobalGenerator->Build(
- jobs, "", dir, projName, targets, output, "", config, clean, false,
+ jobs, "", dir, projName, targets, output, "", config, buildOptions,
verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH,
nativeOptions);
}
@@ -3612,6 +3719,26 @@ void cmake::SetDeprecatedWarningsAsErrors(bool b)
cmStateEnums::INTERNAL);
}
+void cmake::SetDebugFindOutputPkgs(std::string const& args)
+{
+ this->DebugFindPkgs.emplace(args);
+}
+
+void cmake::SetDebugFindOutputVars(std::string const& args)
+{
+ this->DebugFindVars.emplace(args);
+}
+
+bool cmake::GetDebugFindOutput(std::string const& var) const
+{
+ return this->DebugFindVars.count(var);
+}
+
+bool cmake::GetDebugFindPkgOutput(std::string const& pkg) const
+{
+ return this->DebugFindPkgs.count(pkg);
+}
+
#if !defined(CMAKE_BOOTSTRAP)
cmMakefileProfilingData& cmake::GetProfilingOutput()
{