109 lines
2.7 KiB
C++
109 lines
2.7 KiB
C++
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file LICENSE.rst or https://cmake.org/licensing for details. */
|
|
#include "cmCTestEmptyBinaryDirectoryCommand.h"
|
|
|
|
#include "cmsys/Directory.hxx"
|
|
|
|
#include "cmExecutionStatus.h"
|
|
#include "cmMakefile.h"
|
|
#include "cmMessageType.h"
|
|
#include "cmMessenger.h"
|
|
#include "cmStringAlgorithms.h"
|
|
#include "cmSystemTools.h"
|
|
|
|
namespace {
|
|
|
|
// Try to remove the binary directory once
|
|
cmsys::Status TryToRemoveBinaryDirectoryOnce(std::string const& directoryPath)
|
|
{
|
|
cmsys::Directory directory;
|
|
directory.Load(directoryPath);
|
|
|
|
// Make sure that CMakeCache.txt is deleted last.
|
|
for (unsigned long i = 0; i < directory.GetNumberOfFiles(); ++i) {
|
|
std::string path = directory.GetFile(i);
|
|
|
|
if (path == "." || path == ".." || path == "CMakeCache.txt") {
|
|
continue;
|
|
}
|
|
|
|
std::string fullPath = cmStrCat(directoryPath, "/", path);
|
|
|
|
bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
|
|
!cmSystemTools::FileIsSymlink(fullPath);
|
|
|
|
cmsys::Status status;
|
|
if (isDirectory) {
|
|
status = cmSystemTools::RemoveADirectory(fullPath);
|
|
} else {
|
|
status = cmSystemTools::RemoveFile(fullPath);
|
|
}
|
|
if (!status) {
|
|
return status;
|
|
}
|
|
}
|
|
|
|
return cmSystemTools::RemoveADirectory(directoryPath);
|
|
}
|
|
|
|
/*
|
|
* Empty Binary Directory
|
|
*/
|
|
bool EmptyBinaryDirectory(std::string const& sname, std::string& err)
|
|
{
|
|
// try to avoid deleting root
|
|
if (sname.size() < 2) {
|
|
err = "path too short";
|
|
return false;
|
|
}
|
|
|
|
// consider non existing target directory a success
|
|
if (!cmSystemTools::FileExists(sname)) {
|
|
return true;
|
|
}
|
|
|
|
// try to avoid deleting directories that we shouldn't
|
|
std::string check = cmStrCat(sname, "/CMakeCache.txt");
|
|
|
|
if (!cmSystemTools::FileExists(check)) {
|
|
err = "path does not contain an existing CMakeCache.txt file";
|
|
return false;
|
|
}
|
|
|
|
cmsys::Status status;
|
|
for (int i = 0; i < 5; ++i) {
|
|
status = TryToRemoveBinaryDirectoryOnce(sname);
|
|
if (status) {
|
|
return true;
|
|
}
|
|
cmSystemTools::Delay(100);
|
|
}
|
|
|
|
err = status.GetString();
|
|
return false;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool cmCTestEmptyBinaryDirectoryCommand(std::vector<std::string> const& args,
|
|
cmExecutionStatus& status)
|
|
{
|
|
if (args.size() != 1) {
|
|
status.SetError("called with incorrect number of arguments");
|
|
return false;
|
|
}
|
|
|
|
std::string err;
|
|
if (!EmptyBinaryDirectory(args[0], err)) {
|
|
cmMakefile& mf = status.GetMakefile();
|
|
mf.GetMessenger()->DisplayMessage(
|
|
MessageType::FATAL_ERROR,
|
|
cmStrCat("Did not remove the binary directory:\n ", args[0],
|
|
"\nbecause:\n ", err),
|
|
mf.GetBacktrace());
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|