Coverage Report

Created: 2026-02-09 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmLocalCommonGenerator.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 "cmLocalCommonGenerator.h"
4
5
#include <map>
6
#include <memory>
7
#include <utility>
8
#include <vector>
9
10
#include <cm/optional>
11
12
#include "cmGeneratorTarget.h"
13
#include "cmGlobalGenerator.h"
14
#include "cmMakefile.h"
15
#include "cmObjectLocation.h"
16
#include "cmOutputConverter.h"
17
#include "cmStateDirectory.h"
18
#include "cmStateSnapshot.h"
19
#include "cmStringAlgorithms.h"
20
#include "cmValue.h"
21
22
cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
23
                                               cmMakefile* mf)
24
0
  : cmLocalGenerator(gg, mf)
25
0
{
26
  // Multi-config generators define one set of configurations at the top.
27
  // Single-config generators nominally define one configuration at the top,
28
  // but the implementation has never been strict about that, so look up the
29
  // per-directory config to preserve behavior.
30
0
  this->ConfigNames = (gg->IsMultiConfig() && !gg->GetMakefiles().empty()
31
0
                         ? gg->GetMakefiles().front().get()
32
0
                         : this->Makefile)
33
0
                        ->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
34
0
}
35
36
0
cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
37
38
std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const
39
0
{
40
0
  return this->StateSnapshot.GetDirectory().GetCurrentBinary();
41
0
}
42
43
std::string cmLocalCommonGenerator::GetTargetFortranFlags(
44
  cmGeneratorTarget const* target, std::string const& config)
45
0
{
46
0
  std::string flags;
47
48
  // Enable module output if necessary.
49
0
  this->AppendFlags(
50
0
    flags, this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODOUT_FLAG"));
51
52
  // Add a module output directory flag if necessary.
53
0
  std::string mod_dir =
54
0
    target->GetFortranModuleDirectory(this->GetWorkingDirectory());
55
0
  if (!mod_dir.empty()) {
56
0
    mod_dir = this->ConvertToOutputFormat(
57
0
      this->MaybeRelativeToWorkDir(mod_dir), cmOutputConverter::SHELL);
58
0
  } else {
59
0
    mod_dir =
60
0
      this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_DEFAULT");
61
0
  }
62
0
  if (!mod_dir.empty()) {
63
0
    std::string modflag = cmStrCat(
64
0
      this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
65
0
      mod_dir);
66
0
    this->AppendFlags(flags, modflag);
67
    // Some compilers do not search their own module output directory
68
    // for using other modules.  Add an include directory explicitly
69
    // for consistency with compilers that do search it.
70
0
    std::string incflag =
71
0
      this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG");
72
0
    if (!incflag.empty()) {
73
0
      incflag = cmStrCat(incflag, mod_dir);
74
0
      this->AppendFlags(flags, incflag);
75
0
    }
76
0
  }
77
78
  // If there is a separate module path flag then duplicate the
79
  // include path with it.  This compiler does not search the include
80
  // path for modules.
81
0
  if (cmValue modpath_flag =
82
0
        this->Makefile->GetDefinition("CMAKE_Fortran_MODPATH_FLAG")) {
83
0
    std::vector<std::string> includes;
84
0
    this->GetIncludeDirectories(includes, target, "C", config);
85
0
    for (std::string const& id : includes) {
86
0
      std::string flg =
87
0
        cmStrCat(*modpath_flag,
88
0
                 this->ConvertToOutputFormat(id, cmOutputConverter::SHELL));
89
0
      this->AppendFlags(flags, flg);
90
0
    }
91
0
  }
92
93
0
  return flags;
94
0
}
95
96
std::string cmLocalCommonGenerator::ComputeLongTargetDirectory(
97
  cmGeneratorTarget const* target) const
98
0
{
99
0
  std::string dir = target->GetName();
100
#if defined(__VMS)
101
  dir += "_dir";
102
#else
103
0
  dir += ".dir";
104
0
#endif
105
0
  return dir;
106
0
}
107
108
std::string cmLocalCommonGenerator::GetTargetDirectory(
109
  cmGeneratorTarget const* target,
110
  cmStateEnums::IntermediateDirKind kind) const
111
0
{
112
0
  if (target->GetUseShortObjectNames(kind)) {
113
0
    return this->ComputeShortTargetDirectory(target);
114
0
  }
115
0
  return this->ComputeLongTargetDirectory(target);
116
0
}
117
118
void cmLocalCommonGenerator::ComputeObjectFilenames(
119
  std::map<cmSourceFile const*, cmObjectLocations>& mapping,
120
  std::string const& config, cmGeneratorTarget const* gt)
121
0
{
122
  // Determine if these object files should use a custom extension
123
0
  char const* custom_ext = gt->GetCustomObjectExtension();
124
0
  for (auto& si : mapping) {
125
0
    cmSourceFile const* sf = si.first;
126
0
    bool keptSourceExtension;
127
0
    bool force = true;
128
0
    si.second.ShortLoc.emplace(this->GetObjectFileNameWithoutTarget(
129
0
      *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force));
130
0
    force = false;
131
0
    si.second.LongLoc.Update(this->GetObjectFileNameWithoutTarget(
132
0
      *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force));
133
0
    this->FillCustomInstallObjectLocations(*sf, config, custom_ext,
134
0
                                           si.second.InstallLongLoc);
135
0
  }
136
0
}