Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmBuildCommand.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 "cmBuildCommand.h"
4
5
#include "cmExecutionStatus.h"
6
#include "cmGlobalGenerator.h"
7
#include "cmMakefile.h"
8
#include "cmMessageType.h"
9
#include "cmStateTypes.h"
10
#include "cmStringAlgorithms.h"
11
#include "cmSystemTools.h"
12
#include "cmValue.h"
13
14
namespace {
15
16
bool MainSignature(std::vector<std::string> const& args,
17
                   cmExecutionStatus& status)
18
0
{
19
0
  if (args.empty()) {
20
0
    status.SetError("requires at least one argument naming a CMake variable");
21
0
    return false;
22
0
  }
23
24
  // The cmake variable in which to store the result.
25
0
  std::string const& variable = args[0];
26
27
  // Parse remaining arguments.
28
0
  std::string configuration;
29
0
  std::string project_name;
30
0
  std::string target;
31
0
  std::string parallel;
32
0
  enum Doing
33
0
  {
34
0
    DoingNone,
35
0
    DoingConfiguration,
36
0
    DoingProjectName,
37
0
    DoingTarget,
38
0
    DoingParallel
39
0
  };
40
0
  Doing doing = DoingNone;
41
0
  for (unsigned int i = 1; i < args.size(); ++i) {
42
0
    if (args[i] == "CONFIGURATION") {
43
0
      doing = DoingConfiguration;
44
0
    } else if (args[i] == "PROJECT_NAME") {
45
0
      doing = DoingProjectName;
46
0
    } else if (args[i] == "TARGET") {
47
0
      doing = DoingTarget;
48
0
    } else if (args[i] == "PARALLEL_LEVEL") {
49
0
      doing = DoingParallel;
50
0
    } else if (doing == DoingConfiguration) {
51
0
      doing = DoingNone;
52
0
      configuration = args[i];
53
0
    } else if (doing == DoingProjectName) {
54
0
      doing = DoingNone;
55
0
      project_name = args[i];
56
0
    } else if (doing == DoingTarget) {
57
0
      doing = DoingNone;
58
0
      target = args[i];
59
0
    } else if (doing == DoingParallel) {
60
0
      doing = DoingNone;
61
0
      parallel = args[i];
62
0
    } else {
63
0
      status.SetError(cmStrCat("unknown argument \"", args[i], '"'));
64
0
      return false;
65
0
    }
66
0
  }
67
68
  // If null/empty CONFIGURATION argument, cmake --build uses 'Debug'
69
  // in the currently implemented multi-configuration global generators...
70
  // so we put this code here to end up with the same default configuration
71
  // as the original 2-arg build_command signature:
72
  //
73
0
  if (configuration.empty()) {
74
0
    cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configuration);
75
0
  }
76
0
  if (configuration.empty()) {
77
0
    configuration = "Release";
78
0
  }
79
80
0
  cmMakefile& mf = status.GetMakefile();
81
0
  if (!project_name.empty()) {
82
0
    mf.IssueMessage(MessageType::AUTHOR_WARNING,
83
0
                    "Ignoring PROJECT_NAME option because it has no effect.");
84
0
  }
85
86
0
  std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
87
0
    target, configuration, parallel, "", false);
88
89
0
  mf.AddDefinition(variable, makecommand);
90
91
0
  return true;
92
0
}
93
94
bool TwoArgsSignature(std::vector<std::string> const& args,
95
                      cmExecutionStatus& status)
96
0
{
97
0
  if (args.size() < 2) {
98
0
    status.SetError("called with less than two arguments");
99
0
    return false;
100
0
  }
101
102
0
  cmMakefile& mf = status.GetMakefile();
103
104
0
  std::string const& define = args[0];
105
0
  cmValue cacheValue = mf.GetDefinition(define);
106
107
0
  std::string configType;
108
0
  if (!cmSystemTools::GetEnv("CMAKE_CONFIG_TYPE", configType) ||
109
0
      configType.empty()) {
110
0
    configType = "Release";
111
0
  }
112
113
0
  std::string makecommand = mf.GetGlobalGenerator()->GenerateCMakeBuildCommand(
114
0
    "", configType, "", "", false);
115
116
0
  if (cacheValue) {
117
0
    return true;
118
0
  }
119
0
  mf.AddCacheDefinition(define, makecommand,
120
0
                        "Command used to build entire project "
121
0
                        "from the command line.",
122
0
                        cmStateEnums::STRING);
123
0
  return true;
124
0
}
125
126
} // namespace
127
128
bool cmBuildCommand(std::vector<std::string> const& args,
129
                    cmExecutionStatus& status)
130
0
{
131
  // Support the legacy signature of the command:
132
0
  if (args.size() == 2) {
133
0
    return TwoArgsSignature(args, status);
134
0
  }
135
136
0
  return MainSignature(args, status);
137
0
}