mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-26 04:09:35 +03:00
install: Fix bugs around empty directories
The conversion between internal list representations led to empty directories being left behind when processing generator expressions in the destination. This ensures the intended behavior of creating a destination directory but installing nothing into it when no <dirs> are specified, regardless of the presence or absence of genex. Further, an explicit empty string <dir> (via `""`, or an undefined variable) led to the current source directory being expanded as a file to install, leading to the generation of an infinitely recursive install command. Disallow this behavior, forcing projects to explicitly specify the current source directory if that is their intention. Fixes: #27568
This commit is contained in:
@@ -1791,10 +1791,11 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
|
||||
exclude_from_all = true;
|
||||
doing = DoingNone;
|
||||
} else if (doing == DoingDirs) {
|
||||
// Convert this directory to a full path.
|
||||
// If the given directory is not a full path, convert it to one by
|
||||
// assuming it's relative to the current source directory.
|
||||
std::string dir = args[i];
|
||||
std::string::size_type gpos = cmGeneratorExpression::Find(dir);
|
||||
if (gpos != 0 && !cmSystemTools::FileIsFullPath(dir)) {
|
||||
if (!dir.empty() && gpos != 0 && !cmSystemTools::FileIsFullPath(dir)) {
|
||||
dir =
|
||||
cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', args[i]);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
file LICENSE.rst or https://cmake.org/licensing for details. */
|
||||
#include "cmInstallDirectoryGenerator.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "cmGeneratorExpression.h"
|
||||
@@ -54,6 +55,13 @@ bool cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
|
||||
std::vector<std::string> cmInstallDirectoryGenerator::GetDirectories(
|
||||
std::string const& config) const
|
||||
{
|
||||
// If given only empty directories, collapse into a single specification to
|
||||
// avoid redundant calls. This supports the use case of installing an empty
|
||||
// directory into a destination when a directory is not specified.
|
||||
if (std::all_of(this->Directories.begin(), this->Directories.end(),
|
||||
[](std::string const& d) { return d.empty(); })) {
|
||||
return std::vector<std::string>{ "" };
|
||||
}
|
||||
cmList directories;
|
||||
if (this->ActionsPerConfig) {
|
||||
for (std::string const& f : this->Directories) {
|
||||
@@ -81,11 +89,13 @@ void cmInstallDirectoryGenerator::GenerateScriptForConfig(
|
||||
{
|
||||
std::vector<std::string> dirs = this->GetDirectories(config);
|
||||
|
||||
// Make sure all dirs have absolute paths.
|
||||
cmMakefile const& mf = *this->LocalGenerator->GetMakefile();
|
||||
for (std::string& d : dirs) {
|
||||
if (!cmSystemTools::FileIsFullPath(d)) {
|
||||
d = cmStrCat(mf.GetCurrentSourceDirectory(), '/', d);
|
||||
if (!(dirs.size() == 1 && dirs[0].empty())) {
|
||||
// Make sure all dirs have absolute paths.
|
||||
cmMakefile const& mf = *this->LocalGenerator->GetMakefile();
|
||||
for (std::string& d : dirs) {
|
||||
if (!cmSystemTools::FileIsFullPath(d)) {
|
||||
d = cmStrCat(mf.GetCurrentSourceDirectory(), '/', d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
check_installed([[^dir1;dir1/empty\.c;dir1/empty\.h;dir2;dir2/pattern;dir2/pattern/empty\.txt;dir3;dir3/empty\.c;dir3/empty\.h;dir3/empty\.txt;dir4;dir4/empty\.c;dir4/empty\.h;dir4/empty\.txt;empty$]])
|
||||
check_installed([[^dir1;dir1/empty\.c;dir1/empty\.h;dir2;dir2/pattern;dir2/pattern/empty\.txt;dir3;dir3/empty\.c;dir3/empty\.h;dir3/empty\.txt;dir4;dir4/empty\.c;dir4/empty\.h;dir4/empty\.txt;empty;empty_str;empty_with_genex$]])
|
||||
|
||||
@@ -34,3 +34,13 @@ install(
|
||||
DIRECTORY
|
||||
DESTINATION empty
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "" ""
|
||||
DESTINATION empty_str
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY
|
||||
DESTINATION $<LOWER_CASE:EMPTY_WITH_GENEX>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user