File: cmCTestEmptyBinaryDirectoryCommand.cxx

package info (click to toggle)
cmake 4.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 152,336 kB
  • sloc: ansic: 403,896; cpp: 303,920; sh: 4,105; python: 3,583; yacc: 3,106; lex: 1,279; f90: 538; asm: 471; lisp: 375; cs: 270; java: 266; fortran: 239; objc: 215; perl: 213; xml: 198; makefile: 111; javascript: 83; pascal: 63; tcl: 55; php: 25; ruby: 22
file content (108 lines) | stat: -rw-r--r-- 2,762 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* 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;
}