Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmAddSubDirectoryCommand.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmAddSubDirectoryCommand.h"
4
5
#include <cstring>
6
7
#include <cm/string_view>
8
9
#include "cmExecutionStatus.h"
10
#include "cmMakefile.h"
11
#include "cmRange.h"
12
#include "cmStringAlgorithms.h"
13
#include "cmSystemTools.h"
14
15
bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
16
                              cmExecutionStatus& status)
17
0
{
18
0
  if (args.empty()) {
19
0
    status.SetError("called with incorrect number of arguments");
20
0
    return false;
21
0
  }
22
23
0
  cmMakefile& mf = status.GetMakefile();
24
  // store the binpath
25
0
  std::string const& srcArg = args.front();
26
0
  std::string binArg;
27
28
0
  bool excludeFromAll = false;
29
0
  bool system = false;
30
31
  // process the rest of the arguments looking for optional args
32
0
  for (std::string const& arg : cmMakeRange(args).advance(1)) {
33
0
    if (arg == "EXCLUDE_FROM_ALL") {
34
0
      excludeFromAll = true;
35
0
      continue;
36
0
    }
37
0
    if (arg == "SYSTEM") {
38
0
      system = true;
39
0
      continue;
40
0
    }
41
0
    if (binArg.empty()) {
42
0
      binArg = arg;
43
0
    } else {
44
0
      status.SetError("called with incorrect number of arguments");
45
0
      return false;
46
0
    }
47
0
  }
48
  // "SYSTEM" directory property should also affects targets in nested
49
  // subdirectories.
50
0
  if (mf.GetPropertyAsBool("SYSTEM")) {
51
0
    system = true;
52
0
  }
53
54
  // Compute the full path to the specified source directory.
55
  // Interpret a relative path with respect to the current source directory.
56
0
  std::string srcPath;
57
0
  if (cmSystemTools::FileIsFullPath(srcArg)) {
58
0
    srcPath = srcArg;
59
0
  } else {
60
0
    srcPath = cmStrCat(mf.GetCurrentSourceDirectory(), '/', srcArg);
61
0
  }
62
0
  if (!cmSystemTools::FileIsDirectory(srcPath)) {
63
0
    std::string error = cmStrCat("given source \"", srcArg,
64
0
                                 "\" which is not an existing directory.");
65
0
    status.SetError(error);
66
0
    return false;
67
0
  }
68
0
  srcPath =
69
0
    cmSystemTools::CollapseFullPath(srcPath, mf.GetHomeOutputDirectory());
70
71
  // Compute the full path to the binary directory.
72
0
  std::string binPath;
73
0
  if (binArg.empty()) {
74
    // No binary directory was specified.  If the source directory is
75
    // not a subdirectory of the current directory then it is an
76
    // error.
77
0
    if (!cmSystemTools::IsSubDirectory(srcPath,
78
0
                                       mf.GetCurrentSourceDirectory())) {
79
0
      status.SetError(
80
0
        cmStrCat("not given a binary directory but the given source "
81
0
                 "directory \"",
82
0
                 srcPath, "\" is not a subdirectory of \"",
83
0
                 mf.GetCurrentSourceDirectory(),
84
0
                 "\".  When specifying an "
85
0
                 "out-of-tree source a binary directory must be explicitly "
86
0
                 "specified."));
87
0
      return false;
88
0
    }
89
90
    // Remove the CurrentDirectory from the srcPath and replace it
91
    // with the CurrentOutputDirectory.
92
0
    std::string const& src = mf.GetCurrentSourceDirectory();
93
0
    std::string const& bin = mf.GetCurrentBinaryDirectory();
94
0
    size_t srcLen = src.length();
95
0
    size_t binLen = bin.length();
96
0
    if (srcLen > 0 && src.back() == '/') {
97
0
      --srcLen;
98
0
    }
99
0
    if (binLen > 0 && bin.back() == '/') {
100
0
      --binLen;
101
0
    }
102
0
    binPath = cmStrCat(cm::string_view(bin).substr(0, binLen),
103
0
                       cm::string_view(srcPath).substr(srcLen));
104
0
  } else {
105
    // Use the binary directory specified.
106
    // Interpret a relative path with respect to the current binary directory.
107
0
    if (cmSystemTools::FileIsFullPath(binArg)) {
108
0
      binPath = binArg;
109
0
    } else {
110
0
      binPath = cmStrCat(mf.GetCurrentBinaryDirectory(), '/', binArg);
111
0
    }
112
0
  }
113
0
  binPath = cmSystemTools::CollapseFullPath(binPath);
114
115
  // Add the subdirectory using the computed full paths.
116
0
  mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true, system);
117
118
0
  return true;
119
0
}