CMake Nightly Date Stamp
[kiteware-cmake.git] / Source / cmLocalUnixMakefileGenerator3.h
blob7d5a9224b4fab9ba8b737a7a67924190bcbbc0cb
1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #pragma once
5 #include "cmConfigure.h" // IWYU pragma: keep
7 #include <iosfwd>
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
14 #include "cmDepends.h"
15 #include "cmLocalCommonGenerator.h"
16 #include "cmLocalGenerator.h"
18 class cmCustomCommand;
19 class cmCustomCommandGenerator;
20 class cmGeneratorTarget;
21 class cmGlobalGenerator;
22 class cmMakefile;
23 class cmSourceFile;
25 /** \class cmLocalUnixMakefileGenerator3
26 * \brief Write a LocalUnix makefiles.
28 * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
29 * member Makefile.
31 class cmLocalUnixMakefileGenerator3 : public cmLocalCommonGenerator
33 public:
34 cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
35 ~cmLocalUnixMakefileGenerator3() override;
37 std::string GetConfigName() const;
39 void ComputeHomeRelativeOutputPath() override;
41 /**
42 * Generate the makefile for this directory.
44 void Generate() override;
46 // this returns the relative path between the HomeOutputDirectory and this
47 // local generators StartOutputDirectory
48 const std::string& GetHomeRelativeOutputPath();
50 /**
51 * Convert a file path to a Makefile target or dependency with
52 * escaping and quoting suitable for the generator's make tool.
54 std::string ConvertToMakefilePath(std::string const& path) const;
56 // Write out a make rule
57 void WriteMakeRule(std::ostream& os, const char* comment,
58 const std::string& target,
59 const std::vector<std::string>& depends,
60 const std::vector<std::string>& commands, bool symbolic,
61 bool in_help = false);
63 // write the main variables used by the makefiles
64 void WriteMakeVariables(std::ostream& makefileStream);
66 /**
67 * Set max makefile variable size, default is 0 which means unlimited.
69 void SetMakefileVariableSize(int s) { this->MakefileVariableSize = s; }
71 /**
72 * Set whether passing a make target on a command line requires an
73 * extra level of escapes.
75 void SetMakeCommandEscapeTargetTwice(bool b)
77 this->MakeCommandEscapeTargetTwice = b;
80 /**
81 * Set whether the Borland curly brace command line hack should be
82 * applied.
84 void SetBorlandMakeCurlyHack(bool b) { this->BorlandMakeCurlyHack = b; }
86 // used in writing out Cmake files such as WriteDirectoryInformation
87 static void WriteCMakeArgument(std::ostream& os, const std::string& s);
89 /** creates the common disclaimer text at the top of each makefile */
90 void WriteDisclaimer(std::ostream& os);
92 // write a comment line #====... in the stream
93 void WriteDivider(std::ostream& os);
95 /** used to create a recursive make call */
96 std::string GetRecursiveMakeCall(const std::string& makefile,
97 const std::string& tgt);
99 // append flags to a string
100 void AppendFlags(std::string& flags,
101 const std::string& newFlags) const override;
102 using cmLocalCommonGenerator::AppendFlags;
104 // append an echo command
105 enum EchoColor
107 EchoNormal,
108 EchoDepend,
109 EchoBuild,
110 EchoLink,
111 EchoGenerate,
112 EchoGlobal
114 struct EchoProgress
116 std::string Dir;
117 std::string Arg;
119 void AppendEcho(std::vector<std::string>& commands, std::string const& text,
120 EchoColor color = EchoNormal, EchoProgress const* = nullptr);
122 /** Get whether the makefile is to have color. */
123 bool GetColorMakefile() const { return this->ColorMakefile; }
125 std::string GetTargetDirectory(
126 cmGeneratorTarget const* target) const override;
128 // create a command that cds to the start dir then runs the commands
129 void CreateCDCommand(std::vector<std::string>& commands,
130 std::string const& targetDir,
131 std::string const& relDir);
133 static std::string ConvertToQuotedOutputPath(const std::string& p,
134 bool useWatcomQuote);
136 std::string CreateMakeVariable(const std::string& sin,
137 const std::string& s2in);
139 /** Called from command-line hook to bring dependencies up to date
140 for a target. */
141 bool UpdateDependencies(const std::string& tgtInfo, bool verbose,
142 bool color) override;
144 /** Called from command-line hook to clear dependencies. */
145 void ClearDependencies(cmMakefile* mf, bool verbose) override;
147 /** write some extra rules such as make test etc */
148 void WriteSpecialTargetsTop(std::ostream& makefileStream);
149 void WriteSpecialTargetsBottom(std::ostream& makefileStream);
151 std::string GetRelativeTargetDirectory(
152 cmGeneratorTarget const* target) const;
154 // File pairs for implicit dependency scanning. The key of the map
155 // is the depender and the value is the explicit dependee.
156 using ImplicitDependFileMap = cmDepends::DependencyMap;
157 using ImplicitDependLanguageMap =
158 std::map<std::string, ImplicitDependFileMap>;
159 using ImplicitDependScannerMap =
160 std::map<cmDependencyScannerKind, ImplicitDependLanguageMap>;
161 using ImplicitDependTargetMap =
162 std::map<std::string, ImplicitDependScannerMap>;
163 ImplicitDependLanguageMap const& GetImplicitDepends(
164 cmGeneratorTarget const* tgt,
165 cmDependencyScannerKind scanner = cmDependencyScannerKind::CMake);
167 void AddImplicitDepends(
168 cmGeneratorTarget const* tgt, const std::string& lang,
169 const std::string& obj, const std::string& src,
170 cmDependencyScannerKind scanner = cmDependencyScannerKind::CMake);
172 // write the target rules for the local Makefile into the stream
173 void WriteLocalAllRules(std::ostream& ruleFileStream);
175 std::vector<std::string> const& GetLocalHelp() { return this->LocalHelp; }
177 /** Get whether to create rules to generate preprocessed and
178 assembly sources. This could be converted to a variable lookup
179 later. */
180 bool GetCreatePreprocessedSourceRules() const
182 return !this->SkipPreprocessedSourceRules;
184 bool GetCreateAssemblySourceRules() const
186 return !this->SkipAssemblySourceRules;
189 // Fill the vector with the target names for the object files,
190 // preprocessed files and assembly files. Currently only used by the
191 // Eclipse generator.
192 void GetIndividualFileTargets(std::vector<std::string>& targets);
194 std::string GetLinkDependencyFile(cmGeneratorTarget* target,
195 std::string const& config) const override;
197 protected:
198 void WriteLocalMakefile();
200 // write the target rules for the local Makefile into the stream
201 void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
202 std::set<std::string>& emitted);
204 // this method Writes the Directory information files
205 void WriteDirectoryInformationFile();
207 // write the depend info
208 void WriteDependLanguageInfo(std::ostream& cmakefileStream,
209 cmGeneratorTarget* tgt);
211 // this converts a file name that is relative to the StartOuputDirectory
212 // into a full path
213 std::string ConvertToFullPath(const std::string& localPath);
215 void WriteConvenienceRule(std::ostream& ruleFileStream,
216 const std::string& realTarget,
217 const std::string& helpTarget);
219 void AppendRuleDepend(std::vector<std::string>& depends,
220 const char* ruleFileName);
221 void AppendRuleDepends(std::vector<std::string>& depends,
222 std::vector<std::string> const& ruleFiles);
223 void AppendCustomDepends(std::vector<std::string>& depends,
224 const std::vector<cmCustomCommand>& ccs);
225 void AppendCustomDepend(std::vector<std::string>& depends,
226 cmCustomCommandGenerator const& cc);
227 void AppendCustomCommands(std::vector<std::string>& commands,
228 const std::vector<cmCustomCommand>& ccs,
229 cmGeneratorTarget* target,
230 std::string const& relative);
231 void AppendCustomCommand(std::vector<std::string>& commands,
232 cmCustomCommandGenerator const& ccg,
233 cmGeneratorTarget* target,
234 std::string const& relative,
235 bool echo_comment = false,
236 std::ostream* content = nullptr);
237 void AppendCleanCommand(std::vector<std::string>& commands,
238 const std::set<std::string>& files,
239 cmGeneratorTarget* target,
240 const char* filename = nullptr);
241 void AppendDirectoryCleanCommand(std::vector<std::string>& commands);
243 // Helper methods for dependency updates.
244 bool ScanDependencies(std::string const& targetDir,
245 std::string const& dependFile,
246 std::string const& internalDependFile,
247 cmDepends::DependencyMap& validDeps);
248 void CheckMultipleOutputs(bool verbose);
250 private:
251 std::string MaybeConvertWatcomShellCommand(std::string const& cmd);
253 friend class cmMakefileTargetGenerator;
254 friend class cmMakefileExecutableTargetGenerator;
255 friend class cmMakefileLibraryTargetGenerator;
256 friend class cmMakefileUtilityTargetGenerator;
257 friend class cmGlobalUnixMakefileGenerator3;
259 ImplicitDependTargetMap ImplicitDepends;
261 std::string HomeRelativeOutputPath;
263 struct LocalObjectEntry
265 cmGeneratorTarget* Target = nullptr;
266 std::string Language;
267 LocalObjectEntry() = default;
268 LocalObjectEntry(cmGeneratorTarget* t, std::string lang)
269 : Target(t)
270 , Language(std::move(lang))
274 struct LocalObjectInfo : public std::vector<LocalObjectEntry>
276 bool HasSourceExtension = false;
277 bool HasPreprocessRule = false;
278 bool HasAssembleRule = false;
280 void GetLocalObjectFiles(
281 std::map<std::string, LocalObjectInfo>& localObjectFiles);
283 void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
284 const char* comment,
285 const std::string& output,
286 LocalObjectInfo const& info);
288 std::vector<std::string> LocalHelp;
290 /* does the work for each target */
291 std::map<std::string, std::string> MakeVariableMap;
292 std::map<std::string, std::string> ShortMakeVariableMap;
294 int MakefileVariableSize;
295 bool MakeCommandEscapeTargetTwice;
296 bool BorlandMakeCurlyHack;
297 bool ColorMakefile;
298 bool SkipPreprocessedSourceRules;
299 bool SkipAssemblySourceRules;
301 std::set<cmSourceFile const*>& GetCommandsVisited(
302 cmGeneratorTarget const* target)
304 return this->CommandsVisited[target];
307 std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>>
308 CommandsVisited;