cmake: When given multiple source paths use last instead of first

When given two source paths via `-S` or just directory paths prefer
the last one. When the paths are mixed always prefer the last `-S`
entry.

Fixes: #23238
This commit is contained in:
Robert Maynard
2022-02-17 08:46:09 -05:00
committed by Brad King
parent 9c81f2cb8b
commit 7083b19498
9 changed files with 105 additions and 5 deletions

View File

@@ -818,7 +818,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
std::string path = cmSystemTools::CollapseFullPath(value);
cmSystemTools::ConvertToUnixSlashes(path);
state->SetHomeDirectory(path);
state->SetHomeDirectoryViaCommandLine(path, HomeDirArgStyle::Dash_S);
return true;
};
@@ -1486,6 +1487,7 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
// CMakeLists.txt file.
std::string listPath;
std::string cachePath;
bool is_source_dir = false;
bool is_empty_directory = false;
if (cmSystemTools::FileIsDirectory(arg)) {
std::string path = cmSystemTools::CollapseFullPath(arg);
@@ -1501,6 +1503,7 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
if (cmSystemTools::FileExists(listFile)) {
listPath = path;
is_empty_directory = false;
is_source_dir = true;
}
} else if (cmSystemTools::FileExists(arg)) {
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
@@ -1545,19 +1548,23 @@ bool cmake::SetDirectoriesFromFile(const std::string& arg)
const bool passed_same_path = (listPath == this->GetHomeDirectory()) ||
(listPath == this->GetHomeOutputDirectory());
bool used_provided_path =
(passed_same_path || no_source_tree || no_build_tree);
(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()) {
// When invoked with a path that points to an existing CMakeCache
// This function is called multiple times with the same path
if (no_source_tree && no_build_tree) {
if (is_source_dir) {
this->SetHomeDirectoryViaCommandLine(listPath, HomeDirArgStyle::Plain);
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_source_tree) {
this->SetHomeDirectory(listPath);
} else if (no_build_tree) {
this->SetHomeOutputDirectory(listPath);
}
@@ -1773,6 +1780,30 @@ void cmake::PrintPresetList(const cmCMakePresetsGraph& graph) const
}
#endif
void cmake::SetHomeDirectoryViaCommandLine(std::string const& path,
HomeDirArgStyle argStyle)
{
bool fromDashS = argStyle == HomeDirArgStyle::Dash_S;
static bool homeDirectorySetExplicitly = false;
if (path.empty()) {
return;
}
auto prev_path = this->GetHomeDirectory();
if (prev_path != path && !prev_path.empty()) {
const bool ignore_prev_path =
(fromDashS || (!fromDashS && !homeDirectorySetExplicitly));
const std::string& ignored_path = (ignore_prev_path) ? prev_path : path;
this->IssueMessage(MessageType::WARNING,
cmStrCat("Ignoring extra path from command line:\n \"",
ignored_path, "\""));
}
if (fromDashS || !homeDirectorySetExplicitly) {
this->SetHomeDirectory(path);
}
homeDirectorySetExplicitly = fromDashS;
}
void cmake::SetHomeDirectory(const std::string& dir)
{
this->State->SetSourceDirectory(dir);

View File

@@ -183,6 +183,29 @@ public:
#endif
std::string ReportCapabilities() const;
enum class HomeDirArgStyle
{
Plain,
Dash_S,
};
/**
* Set the home directory from `-S` or from a known location
* that contains a CMakeLists.txt. Will generate warnings
* when overriding an existing source directory.
*
* | args | src dir| warning |
* | ----------------- | ------ | -------------- |
* | `dirA dirA` | dirA | N/A |
* | `-S dirA -S dirA` | dirA | N/A |
* | `-S dirA -S dirB` | dirB | Ignoring dirA |
* | `-S dirA dirB` | dirA | Ignoring dirB |
* | `dirA -S dirB` | dirB | Ignoring dirA |
* | `dirA dirB` | dirB | Ignoring dirA |
*/
void SetHomeDirectoryViaCommandLine(std::string const& path,
HomeDirArgStyle argStyle);
//@{
/**
* Set/Get the home directory (or output directory) in the project. The

View File

@@ -168,6 +168,18 @@ endif()
run_cmake_with_raw_args(S-B-non-path "-S \"${source_dir}\" -B \"${binary_dir}\" \"\"")
run_cmake_with_raw_args(S-B-non-path2 "-S \"${source_dir}\" \"\" -B \"${binary_dir}\"")
file(REMOVE_RECURSE "${binary_dir}/other_dir")
file(MAKE_DIRECTORY "${binary_dir}/other_dir")
file(WRITE "${binary_dir}/other_dir/CMakeLists.txt" [=[ ]=])
run_cmake_with_options(S-S-same -S ${source_dir} -S ${source_dir} -B ${binary_dir})
run_cmake_with_options(S-S-differs -S ${binary_dir}/other_dir -S ${source_dir} -B ${binary_dir})
run_cmake_with_options(S-implicit-same -S ${source_dir} ${source_dir} -B ${binary_dir})
run_cmake_with_options(S-implicit-differs -S ${source_dir} ${binary_dir}/other_dir -B ${binary_dir})
run_cmake_with_options(S-implicit-differs2 ${binary_dir}/other_dir -S ${source_dir} -B ${binary_dir})
run_cmake_with_options(S-implicit-differs3 ${binary_dir}/other_dir ${source_dir} -B ${binary_dir})
run_cmake_with_options(S-S-Sdiffers -S ${binary_dir}/other_dir1 -S ${binary_dir}/other_dir2 -S ${source_dir} -B ${binary_dir})
run_cmake_with_options(S-S-Simplicit ${binary_dir}/other_dir1 ${binary_dir}/other_dir2 ${source_dir} -B ${binary_dir})
# make sure that -B can explicitly construct build directories
file(REMOVE_RECURSE "${binary_dir}")
run_cmake_with_options(B-arg -B ${binary_dir} ${source_dir})

View File

@@ -0,0 +1,9 @@
^CMake Warning:
Ignoring extra path from command line:
.*other_dir1"
.*
CMake Warning:
Ignoring extra path from command line:
.*other_dir2"$

View File

@@ -0,0 +1,9 @@
^CMake Warning:
Ignoring extra path from command line:
.*other_dir1"
.*
CMake Warning:
Ignoring extra path from command line:
.*other_dir2"$

View File

@@ -0,0 +1,4 @@
^CMake Warning:
Ignoring extra path from command line:
.*ExplicitDirs-build/other_dir.*

View File

@@ -0,0 +1,4 @@
^CMake Warning:
Ignoring extra path from command line:
.*other_dir"$

View File

@@ -0,0 +1,4 @@
^CMake Warning:
Ignoring extra path from command line:
.*ExplicitDirs-build/other_dir.*

View File

@@ -0,0 +1,4 @@
^CMake Warning:
Ignoring extra path from command line:
.*ExplicitDirs-build/other_dir.*