1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
5 #include "cmConfigure.h" // IWYU pragma: keep
14 #include "cmDepends.h"
15 #include "cmLocalCommonGenerator.h"
16 #include "cmLocalGenerator.h"
18 class cmCustomCommand
;
19 class cmCustomCommandGenerator
;
20 class cmGeneratorTarget
;
21 class cmGlobalGenerator
;
25 /** \class cmLocalUnixMakefileGenerator3
26 * \brief Write a LocalUnix makefiles.
28 * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
31 class cmLocalUnixMakefileGenerator3
: public cmLocalCommonGenerator
34 cmLocalUnixMakefileGenerator3(cmGlobalGenerator
* gg
, cmMakefile
* mf
);
35 ~cmLocalUnixMakefileGenerator3() override
;
37 std::string
GetConfigName() const;
39 void ComputeHomeRelativeOutputPath() override
;
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();
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
);
67 * Set max makefile variable size, default is 0 which means unlimited.
69 void SetMakefileVariableSize(int s
) { this->MakefileVariableSize
= s
; }
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
;
81 * Set whether the Borland curly brace command line hack should be
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
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
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
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
;
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
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
);
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
)
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
,
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
;
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*>>