cmLocalUnixMakefileGenerator3.h 9.94 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
Ken Martin's avatar
Ken Martin committed
3 4 5
#ifndef cmLocalUnixMakefileGenerator3_h
#define cmLocalUnixMakefileGenerator3_h

6
#include "cmConfigure.h" // IWYU pragma: keep
Ken Martin's avatar
Ken Martin committed
7

8
#include "cmDepends.h"
9 10 11 12 13 14
#include "cmLocalCommonGenerator.h"

#include <iosfwd>
#include <map>
#include <set>
#include <string>
wahikihiki's avatar
wahikihiki committed
15
#include <utility>
16
#include <vector>
17

Ken Martin's avatar
Ken Martin committed
18
class cmCustomCommand;
19
class cmCustomCommandGenerator;
20 21 22
class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
Ken Martin's avatar
Ken Martin committed
23 24 25 26 27

/** \class cmLocalUnixMakefileGenerator3
 * \brief Write a LocalUnix makefiles.
 *
 * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
28
 * member Makefile.
Ken Martin's avatar
Ken Martin committed
29
 */
30
class cmLocalUnixMakefileGenerator3 : public cmLocalCommonGenerator
Ken Martin's avatar
Ken Martin committed
31 32
{
public:
33
  cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
34
  ~cmLocalUnixMakefileGenerator3() override;
Ken Martin's avatar
Ken Martin committed
35

36
  void ComputeHomeRelativeOutputPath() override;
37

38
  /**
39
   * Generate the makefile for this directory.
40
   */
41
  void Generate() override;
Ken Martin's avatar
Ken Martin committed
42 43 44

  // this returns the relative path between the HomeOutputDirectory and this
  // local generators StartOutputDirectory
45
  const std::string& GetHomeRelativeOutputPath();
Ken Martin's avatar
Ken Martin committed
46

47
  // Write out a make rule
48
  void WriteMakeRule(std::ostream& os, const char* comment,
49
                     const std::string& target,
Ken Martin's avatar
Ken Martin committed
50
                     const std::vector<std::string>& depends,
51
                     const std::vector<std::string>& commands, bool symbolic,
52
                     bool in_help = false);
53

Ken Martin's avatar
Ken Martin committed
54
  // write the main variables used by the makefiles
Ken Martin's avatar
Ken Martin committed
55
  void WriteMakeVariables(std::ostream& makefileStream);
Ken Martin's avatar
Ken Martin committed
56

Ken Martin's avatar
Ken Martin committed
57 58 59
  /**
   * Set max makefile variable size, default is 0 which means unlimited.
   */
60
  void SetMakefileVariableSize(int s) { this->MakefileVariableSize = s; }
Ken Martin's avatar
Ken Martin committed
61

62 63 64 65 66
  /**
   * Set whether passing a make target on a command line requires an
   * extra level of escapes.
   */
  void SetMakeCommandEscapeTargetTwice(bool b)
67 68 69
  {
    this->MakeCommandEscapeTargetTwice = b;
  }
70

71 72 73 74
  /**
   * Set whether the Borland curly brace command line hack should be
   * applied.
   */
75
  void SetBorlandMakeCurlyHack(bool b) { this->BorlandMakeCurlyHack = b; }
76

77 78 79
  // used in writing out Cmake files such as WriteDirectoryInformation
  static void WriteCMakeArgument(std::ostream& os, const char* s);

Nicolas Despres's avatar
Nicolas Despres committed
80
  /** creates the common disclaimer text at the top of each makefile */
81 82 83 84 85 86
  void WriteDisclaimer(std::ostream& os);

  // write a  comment line #====... in the stream
  void WriteDivider(std::ostream& os);

  /** used to create a recursive make call */
87
  std::string GetRecursiveMakeCall(const std::string& makefile,
88
                                   const std::string& tgt);
89

90
  // append flags to a string
Marc Chevrier's avatar
Marc Chevrier committed
91 92 93
  void AppendFlags(std::string& flags,
                   const std::string& newFlags) const override;
  void AppendFlags(std::string& flags, const char* newFlags) const override;
94

95
  // append an echo command
96 97 98 99 100 101 102 103 104 105 106 107 108 109
  enum EchoColor
  {
    EchoNormal,
    EchoDepend,
    EchoBuild,
    EchoLink,
    EchoGenerate,
    EchoGlobal
  };
  struct EchoProgress
  {
    std::string Dir;
    std::string Arg;
  };
110
  void AppendEcho(std::vector<std::string>& commands, std::string const& text,
Daniel Pfeifer's avatar
Daniel Pfeifer committed
111
                  EchoColor color = EchoNormal, EchoProgress const* = nullptr);
112

113 114 115
  /** Get whether the makefile is to have color.  */
  bool GetColorMakefile() const { return this->ColorMakefile; }

116 117
  std::string GetTargetDirectory(
    cmGeneratorTarget const* target) const override;
118

119
  // create a command that cds to the start dir then runs the commands
120
  void CreateCDCommand(std::vector<std::string>& commands,
121 122
                       std::string const& targetDir,
                       std::string const& relDir);
123

124
  static std::string ConvertToQuotedOutputPath(const std::string& p,
125
                                               bool useWatcomQuote);
126

127 128
  std::string CreateMakeVariable(const std::string& sin,
                                 const std::string& s2in);
129

130 131
  /** Called from command-line hook to bring dependencies up to date
      for a target.  */
132
  bool UpdateDependencies(const std::string& tgtInfo, bool verbose,
133
                          bool color) override;
134 135

  /** Called from command-line hook to clear dependencies.  */
136
  void ClearDependencies(cmMakefile* mf, bool verbose) override;
137

138
  /** write some extra rules such as make test etc */
Ken Martin's avatar
Ken Martin committed
139
  void WriteSpecialTargetsTop(std::ostream& makefileStream);
Ken Martin's avatar
Ken Martin committed
140
  void WriteSpecialTargetsBottom(std::ostream& makefileStream);
141

142
  std::string GetRelativeTargetDirectory(cmGeneratorTarget* target);
Ken Martin's avatar
Ken Martin committed
143

144 145
  // File pairs for implicit dependency scanning.  The key of the map
  // is the depender and the value is the explicit dependee.
146
  struct ImplicitDependFileMap : public cmDepends::DependencyMap
147 148 149 150 151 152 153 154 155 156 157 158
  {
  };
  struct ImplicitDependLanguageMap
    : public std::map<std::string, ImplicitDependFileMap>
  {
  };
  struct ImplicitDependTargetMap
    : public std::map<std::string, ImplicitDependLanguageMap>
  {
  };
  ImplicitDependLanguageMap const& GetImplicitDepends(
    cmGeneratorTarget const* tgt);
159

160
  void AddImplicitDepends(cmGeneratorTarget const* tgt,
161 162
                          const std::string& lang, const std::string& obj,
                          const std::string& src);
163

164 165
  // write the target rules for the local Makefile into the stream
  void WriteLocalAllRules(std::ostream& ruleFileStream);
166

167
  std::vector<std::string> const& GetLocalHelp() { return this->LocalHelp; }
168

169 170 171
  /** Get whether to create rules to generate preprocessed and
      assembly sources.  This could be converted to a variable lookup
      later.  */
172
  bool GetCreatePreprocessedSourceRules()
173
  {
174
    return !this->SkipPreprocessedSourceRules;
175
  }
176
  bool GetCreateAssemblySourceRules()
177
  {
178
    return !this->SkipAssemblySourceRules;
179
  }
180

181 182
  // Fill the vector with the target names for the object files,
  // preprocessed files and assembly files. Currently only used by the
183 184
  // Eclipse generator.
  void GetIndividualFileTargets(std::vector<std::string>& targets);
185

Ken Martin's avatar
Ken Martin committed
186
protected:
187
  void WriteLocalMakefile();
188

Ken Martin's avatar
Ken Martin committed
189
  // write the target rules for the local Makefile into the stream
190
  void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
191
                                 std::set<std::string>& emitted);
192

193
  // this method Writes the Directory information files
194 195
  void WriteDirectoryInformationFile();

196
  // write the depend info
197
  void WriteDependLanguageInfo(std::ostream& cmakefileStream,
198
                               cmGeneratorTarget* tgt);
199

200 201 202 203
  // this converts a file name that is relative to the StartOuputDirectory
  // into a full path
  std::string ConvertToFullPath(const std::string& localPath);

Ken Martin's avatar
Ken Martin committed
204
  void WriteConvenienceRule(std::ostream& ruleFileStream,
205 206
                            const std::string& realTarget,
                            const std::string& helpTarget);
207

Ken Martin's avatar
Ken Martin committed
208 209
  void AppendRuleDepend(std::vector<std::string>& depends,
                        const char* ruleFileName);
210 211
  void AppendRuleDepends(std::vector<std::string>& depends,
                         std::vector<std::string> const& ruleFiles);
Ken Martin's avatar
Ken Martin committed
212 213 214
  void AppendCustomDepends(std::vector<std::string>& depends,
                           const std::vector<cmCustomCommand>& ccs);
  void AppendCustomDepend(std::vector<std::string>& depends,
215
                          cmCustomCommandGenerator const& cc);
216 217 218 219 220 221 222 223 224
  void AppendCustomCommands(std::vector<std::string>& commands,
                            const std::vector<cmCustomCommand>& ccs,
                            cmGeneratorTarget* target,
                            std::string const& relative);
  void AppendCustomCommand(std::vector<std::string>& commands,
                           cmCustomCommandGenerator const& ccg,
                           cmGeneratorTarget* target,
                           std::string const& relative,
                           bool echo_comment = false,
Daniel Pfeifer's avatar
Daniel Pfeifer committed
225
                           std::ostream* content = nullptr);
Ken Martin's avatar
Ken Martin committed
226
  void AppendCleanCommand(std::vector<std::string>& commands,
227
                          const std::set<std::string>& files,
Daniel Pfeifer's avatar
Daniel Pfeifer committed
228
                          cmGeneratorTarget* target,
Daniel Pfeifer's avatar
Daniel Pfeifer committed
229
                          const char* filename = nullptr);
230
  void AppendDirectoryCleanCommand(std::vector<std::string>& commands);
Ken Martin's avatar
Ken Martin committed
231

luz.paz's avatar
luz.paz committed
232
  // Helper methods for dependency updates.
233 234 235 236
  bool ScanDependencies(std::string const& targetDir,
                        std::string const& dependFile,
                        std::string const& internalDependFile,
                        cmDepends::DependencyMap& validDeps);
237 238
  void CheckMultipleOutputs(bool verbose);

Ken Martin's avatar
Ken Martin committed
239
private:
240
  std::string MaybeConvertWatcomShellCommand(std::string const& cmd);
241

242 243 244 245
  friend class cmMakefileTargetGenerator;
  friend class cmMakefileExecutableTargetGenerator;
  friend class cmMakefileLibraryTargetGenerator;
  friend class cmMakefileUtilityTargetGenerator;
Ken Martin's avatar
Ken Martin committed
246
  friend class cmGlobalUnixMakefileGenerator3;
247 248

  ImplicitDependTargetMap ImplicitDepends;
Ken Martin's avatar
Ken Martin committed
249

250
  std::string HomeRelativeOutputPath;
251

252 253
  struct LocalObjectEntry
  {
254
    cmGeneratorTarget* Target = nullptr;
255
    std::string Language;
wahikihiki's avatar
wahikihiki committed
256
    LocalObjectEntry() = default;
wahikihiki's avatar
wahikihiki committed
257
    LocalObjectEntry(cmGeneratorTarget* t, std::string lang)
258
      : Target(t)
wahikihiki's avatar
wahikihiki committed
259
      , Language(std::move(lang))
260 261
    {
    }
262
  };
263
  struct LocalObjectInfo : public std::vector<LocalObjectEntry>
264
  {
265 266 267
    bool HasSourceExtension = false;
    bool HasPreprocessRule = false;
    bool HasAssembleRule = false;
268
  };
269
  void GetLocalObjectFiles(
270
    std::map<std::string, LocalObjectInfo>& localObjectFiles);
271

272
  void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
273 274
                                  const char* comment,
                                  const std::string& output,
275 276
                                  LocalObjectInfo const& info);

277
  std::vector<std::string> LocalHelp;
278 279

  /* does the work for each target */
280 281
  std::map<std::string, std::string> MakeVariableMap;
  std::map<std::string, std::string> ShortMakeVariableMap;
282 283 284 285 286 287 288

  int MakefileVariableSize;
  bool MakeCommandEscapeTargetTwice;
  bool BorlandMakeCurlyHack;
  bool ColorMakefile;
  bool SkipPreprocessedSourceRules;
  bool SkipAssemblySourceRules;
Ken Martin's avatar
Ken Martin committed
289 290 291
};

#endif