resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmGlobalUnixMakefileGenerator3.h
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
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <cstddef>
8 #include <iosfwd>
9 #include <map>
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <vector>
14
15 #include "cmBuildOptions.h"
16 #include "cmGeneratorTarget.h"
17 #include "cmGlobalCommonGenerator.h"
18 #include "cmGlobalGeneratorFactory.h"
19 #include "cmStateSnapshot.h"
20
21 class cmGeneratedFileStream;
22 class cmLocalGenerator;
23 class cmLocalUnixMakefileGenerator3;
24 class cmMakefile;
25 class cmMakefileTargetGenerator;
26 class cmake;
27 struct cmDocumentationEntry;
28
29 /** \class cmGlobalUnixMakefileGenerator3
30  * \brief Write a Unix makefiles.
31  *
32  * cmGlobalUnixMakefileGenerator3 manages UNIX build process for a tree
33
34
35  The basic approach of this generator is to produce Makefiles that will all
36  be run with the current working directory set to the Home Output
37  directory. The one exception to this is the subdirectory Makefiles which are
38  created as a convenience and just cd up to the Home Output directory and
39  invoke the main Makefiles.
40
41  The make process starts with Makefile. Makefile should only contain the
42  targets the user is likely to invoke directly from a make command line. No
43  internal targets should be in this file. Makefile2 contains the internal
44  targets that are required to make the process work.
45
46  Makefile2 in turn will recursively make targets in the correct order. Each
47  target has its own directory \<target\>.dir and its own makefile build.make in
48  that directory. Also in that directory is a couple makefiles per source file
49  used by the target. Typically these are named source.obj.build.make and
50  source.obj.build.depend.make. The source.obj.build.make contains the rules
51  for building, cleaning, and computing dependencies for the given source
52  file. The build.depend.make contains additional dependencies that were
53  computed during dependency scanning. An additional file called
54  source.obj.depend is used as a marker to indicate when dependencies must be
55  rescanned.
56
57  Rules for custom commands follow the same model as rules for source files.
58
59  */
60
61 class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
62 {
63 public:
64   cmGlobalUnixMakefileGenerator3(cmake* cm);
65   static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
66   {
67     return std::unique_ptr<cmGlobalGeneratorFactory>(
68       new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
69   }
70
71   ~cmGlobalUnixMakefileGenerator3() override;
72
73   cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) =
74     delete;
75   cmGlobalUnixMakefileGenerator3& operator=(
76     const cmGlobalUnixMakefileGenerator3&) = delete;
77
78   //! Get the name for the generator.
79   std::string GetName() const override
80   {
81     return cmGlobalUnixMakefileGenerator3::GetActualName();
82   }
83   static std::string GetActualName() { return "Unix Makefiles"; }
84
85   /**
86    * Utilized by the generator factory to determine if this generator
87    * supports toolsets.
88    */
89   static bool SupportsToolset() { return false; }
90
91   /**
92    * Utilized by the generator factory to determine if this generator
93    * supports platforms.
94    */
95   static bool SupportsPlatform() { return false; }
96
97   /**
98    * Utilized to determine if this generator
99    * supports DEPFILE option.
100    */
101   bool SupportsCustomCommandDepfile() const override { return true; }
102
103   /** Get the documentation entry for this generator.  */
104   static void GetDocumentation(cmDocumentationEntry& entry);
105
106   std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
107     cmMakefile* mf) override;
108
109   /**
110    * Try to determine system information such as shared library
111    * extension, pthreads, byte order etc.
112    */
113   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
114                       bool optional) override;
115
116   void Configure() override;
117
118   /**
119    * Generate the all required files for building this project/tree. This
120    * basically creates a series of LocalGenerators for each directory and
121    * requests that they Generate.
122    */
123   void Generate() override;
124
125   void WriteMainCMakefileLanguageRules(
126     cmGeneratedFileStream& cmakefileStream,
127     std::vector<std::unique_ptr<cmLocalGenerator>>&);
128
129   // write out the help rule listing the valid targets
130   void WriteHelpRule(std::ostream& ruleFileStream,
131                      cmLocalUnixMakefileGenerator3*);
132
133   // write the top level target rules
134   void WriteConvenienceRules(std::ostream& ruleFileStream,
135                              std::set<std::string>& emitted);
136
137   // Make tool supports dependency files generated by compiler
138   bool SupportsCompilerDependencies() const
139   {
140     return this->ToolSupportsCompilerDependencies;
141   }
142
143   // Make tool supports long line dependencies
144   bool SupportsLongLineDependencies() const
145   {
146     return this->ToolSupportsLongLineDependencies;
147   }
148
149   /** Get the command to use for a target that has no rule.  This is
150       used for multiple output dependencies and for cmake_force.  */
151   std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
152
153   /** Get the fake dependency to use when a rule has no real commands
154       or dependencies.  */
155   std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
156
157   /**
158    * Convert a file path to a Makefile target or dependency with
159    * escaping and quoting suitable for the generator's make tool.
160    */
161   std::string ConvertToMakefilePath(std::string const& path) const;
162
163   // change the build command for speed
164   std::vector<GeneratedMakeCommand> GenerateBuildCommand(
165     const std::string& makeProgram, const std::string& projectName,
166     const std::string& projectDir, std::vector<std::string> const& targetNames,
167     const std::string& config, int jobs, bool verbose,
168     const cmBuildOptions& buildOptions = cmBuildOptions(),
169     std::vector<std::string> const& makeOptions =
170       std::vector<std::string>()) override;
171
172   /** Record per-target progress information.  */
173   void RecordTargetProgress(cmMakefileTargetGenerator* tg);
174
175   void AddCXXCompileCommand(const std::string& sourceFile,
176                             const std::string& workingDirectory,
177                             const std::string& compileCommand);
178
179   /** Does the make tool tolerate .NOTPARALLEL? */
180   virtual bool AllowNotParallel() const { return true; }
181
182   /** Does the make tool tolerate .DELETE_ON_ERROR? */
183   virtual bool AllowDeleteOnError() const { return true; }
184
185   /** Does the make tool interpret '\#' as '#'?  */
186   virtual bool CanEscapeOctothorpe() const;
187
188   bool IsIPOSupported() const override { return true; }
189
190   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
191
192   std::string IncludeDirective;
193   std::string LineContinueDirective;
194   bool DefineWindowsNULL;
195   bool PassMakeflags;
196   bool UnixCD;
197
198 protected:
199   void WriteMainMakefile2();
200   void WriteMainCMakefile();
201
202   void WriteConvenienceRules2(std::ostream& ruleFileStream,
203                               cmLocalUnixMakefileGenerator3& rootLG,
204                               cmLocalUnixMakefileGenerator3& lg);
205
206   void WriteDirectoryRule2(std::ostream& ruleFileStream,
207                            cmLocalUnixMakefileGenerator3& rootLG,
208                            DirectoryTarget const& dt, const char* pass,
209                            bool check_all, bool check_relink,
210                            std::vector<std::string> const& commands = {});
211   void WriteDirectoryRules2(std::ostream& ruleFileStream,
212                             cmLocalUnixMakefileGenerator3& rootLG,
213                             DirectoryTarget const& dt);
214
215   void AppendGlobalTargetDepends(std::vector<std::string>& depends,
216                                  cmGeneratorTarget* target);
217
218   // Target name hooks for superclass.
219   const char* GetAllTargetName() const override { return "all"; }
220   const char* GetInstallTargetName() const override { return "install"; }
221   const char* GetInstallLocalTargetName() const override
222   {
223     return "install/local";
224   }
225   const char* GetInstallStripTargetName() const override
226   {
227     return "install/strip";
228   }
229   const char* GetPreinstallTargetName() const override { return "preinstall"; }
230   const char* GetTestTargetName() const override { return "test"; }
231   const char* GetPackageTargetName() const override { return "package"; }
232   const char* GetPackageSourceTargetName() const override
233   {
234     return "package_source";
235   }
236   const char* GetRebuildCacheTargetName() const override
237   {
238     return "rebuild_cache";
239   }
240   const char* GetCleanTargetName() const override { return "clean"; }
241
242   bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
243
244   // Specify if the make tool is able to consume dependency files
245   // generated by the compiler
246   bool ToolSupportsCompilerDependencies = true;
247
248   // some Make generator, such as Borland not support long line dependencies,
249   // we add SupportsLongLineDependencies to predicate.
250   bool ToolSupportsLongLineDependencies = true;
251
252   // Some make programs (Borland) do not keep a rule if there are no
253   // dependencies or commands.  This is a problem for creating rules
254   // that might not do anything but might have other dependencies
255   // added later.  If non-empty this variable holds a fake dependency
256   // that can be added.
257   std::string EmptyRuleHackDepends;
258
259   // Some make programs (Watcom) do not like rules with no commands.
260   // If non-empty this variable holds a bogus command that may be put
261   // in the rule to satisfy the make program.
262   std::string EmptyRuleHackCommand;
263
264   // Store per-target progress counters.
265   struct TargetProgress
266   {
267     unsigned long NumberOfActions = 0;
268     std::string VariableFile;
269     std::vector<unsigned long> Marks;
270     void WriteProgressVariables(unsigned long total, unsigned long& current);
271   };
272   using ProgressMapType = std::map<cmGeneratorTarget const*, TargetProgress,
273                                    cmGeneratorTarget::StrictTargetComparison>;
274   ProgressMapType ProgressMap;
275
276   size_t CountProgressMarksInTarget(
277     cmGeneratorTarget const* target,
278     std::set<cmGeneratorTarget const*>& emitted);
279   size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
280
281   std::unique_ptr<cmGeneratedFileStream> CommandDatabase;
282
283 private:
284   const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
285
286   std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>,
287            cmStateSnapshot::StrictWeakOrder>
288     DirectoryTargetsMap;
289   void InitializeProgressMarks() override;
290 };