Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmLocalUnixMakefileGenerator3.h
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #ifndef cmLocalUnixMakefileGenerator3_h
13 #define cmLocalUnixMakefileGenerator3_h
14
15 #include "cmLocalGenerator.h"
16
17 // for cmDepends::DependencyVector
18 #include "cmDepends.h"
19
20 class cmCustomCommand;
21 class cmDependInformation;
22 class cmDepends;
23 class cmMakefileTargetGenerator;
24 class cmTarget;
25 class cmSourceFile;
26
27 /** \class cmLocalUnixMakefileGenerator3
28  * \brief Write a LocalUnix makefiles.
29  *
30  * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
31  * member Makefile.
32  */
33 class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator
34 {
35 public:
36   cmLocalUnixMakefileGenerator3();
37   virtual ~cmLocalUnixMakefileGenerator3();
38
39   /**
40    * Process the CMakeLists files for this directory to fill in the
41    * Makefile ivar
42    */
43   virtual void Configure();
44
45   /**
46    * Generate the makefile for this directory.
47    */
48   virtual void Generate();
49
50
51   // this returns the relative path between the HomeOutputDirectory and this
52   // local generators StartOutputDirectory
53   const std::string &GetHomeRelativeOutputPath();
54
55   // Write out a make rule
56   void WriteMakeRule(std::ostream& os,
57                      const char* comment,
58                      const char* target,
59                      const std::vector<std::string>& depends,
60                      const std::vector<std::string>& commands,
61                      bool symbolic,
62                      bool in_help = false);
63
64   // write the main variables used by the makefiles
65   void WriteMakeVariables(std::ostream& makefileStream);
66
67   /**
68    * If true, then explicitly pass MAKEFLAGS on the make all target for makes
69    * that do not use environment variables.
70    *
71    */
72   void SetPassMakeflags(bool s){this->PassMakeflags = s;}
73   bool GetPassMakeflags() { return this->PassMakeflags; }
74
75   /**
76    * Set the flag used to keep the make program silent.
77    */
78   void SetMakeSilentFlag(const char* s) { this->MakeSilentFlag = s; }
79   std::string &GetMakeSilentFlag() { return this->MakeSilentFlag; }
80
81   /**
82    * Set to true if the shell being used is the windows shell.
83    * This controls if statements in the makefile and the SHELL variable.
84    * The default is false.
85    */
86   void SetWindowsShell(bool v)  {this->WindowsShell = v;}
87
88   /**
89    * Set to true if the make tool being used is Watcom WMake.
90    */
91   void SetWatcomWMake(bool v)  {this->WatcomWMake = v;}
92
93   /**
94    * Set to true if the make tool being used is MinGW Make.
95    */
96   void SetMinGWMake(bool v)  {this->MinGWMake = v;}
97
98   /**
99    * Set to true if the make tool being used is NMake.
100    */
101   void SetNMake(bool v)  {this->NMake = v;}
102
103   /**
104    * Set to true if the shell being used is the MSYS shell.
105    * This controls if statements in the makefile and the SHELL variable.
106    * The default is false.
107    */
108   void SetMSYSShell(bool v)  {this->MSYSShell = v;}
109
110   /**
111    * If set to true, then NULL is set to nil for non Windows_NT.
112    * This uses make syntax used by nmake and borland.
113    * The default is false.
114    */
115   void SetDefineWindowsNULL(bool v)  {this->DefineWindowsNULL = v;}
116
117   /**
118    * If set to true, cd dir && command is used to
119    * run commands in a different directory.
120    */
121   void SetUnixCD(bool v)  {this->UnixCD = v;}
122
123   /**
124    * Set Support Verbose Variable.  If true, then .SILENT will
125    * be not end with :  i.e. .SILENT: or .SILENT
126    */
127   void SetSilentNoColon(bool v)  {this->SilentNoColon = v;}
128
129   /**
130    * Set the string used to include one makefile into another default
131    * is include.
132    */
133   void SetIncludeDirective(const char* s) { this->IncludeDirective = s; }
134   const char *GetIncludeDirective() { return this->IncludeDirective.c_str(); }
135
136   /**
137    * Set max makefile variable size, default is 0 which means unlimited.
138    */
139   void SetMakefileVariableSize(int s) { this->MakefileVariableSize = s; }
140
141   /**
142    * If ignore lib prefix is true, then do not strip lib from the name
143    * of a library.
144    */
145   void SetIgnoreLibPrefix(bool s) { this->IgnoreLibPrefix = s; }
146
147   /**
148    * Set whether passing a make target on a command line requires an
149    * extra level of escapes.
150    */
151   void SetMakeCommandEscapeTargetTwice(bool b)
152     { this->MakeCommandEscapeTargetTwice = b; }
153
154   /**
155    * Set whether the Borland curly brace command line hack should be
156    * applied.
157    */
158   void SetBorlandMakeCurlyHack(bool b)
159     { this->BorlandMakeCurlyHack = b; }
160
161   // used in writing out Cmake files such as WriteDirectoryInformation
162   static void WriteCMakeArgument(std::ostream& os, const char* s);
163
164   /** creates the common disclaimer text at the top of each makefile */
165   void WriteDisclaimer(std::ostream& os);
166
167   // write a  comment line #====... in the stream
168   void WriteDivider(std::ostream& os);
169
170   /** used to create a recursive make call */
171   std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);
172
173   // append flags to a string
174   virtual void AppendFlags(std::string& flags, const char* newFlags);
175
176   // append an echo command
177   enum EchoColor { EchoNormal, EchoDepend, EchoBuild, EchoLink,
178                    EchoGenerate, EchoGlobal };
179   void AppendEcho(std::vector<std::string>& commands, const char* text,
180                   EchoColor color = EchoNormal);
181
182   /** Get whether the makefile is to have color.  */
183   bool GetColorMakefile() const { return this->ColorMakefile; }
184
185   virtual std::string GetTargetDirectory(cmTarget const& target) const;
186
187     // create a command that cds to the start dir then runs the commands
188   void CreateCDCommand(std::vector<std::string>& commands,
189                        const char *targetDir,
190                        cmLocalGenerator::RelativeRoot returnDir);
191
192   static std::string ConvertToQuotedOutputPath(const char* p);
193
194   std::string CreateMakeVariable(const char* sin, const char* s2in);
195
196   /** Called from command-line hook to bring dependencies up to date
197       for a target.  */
198   virtual bool UpdateDependencies(const char* tgtInfo,
199                                   bool verbose, bool color);
200
201   /** Called from command-line hook to clear dependencies.  */
202   virtual void ClearDependencies(cmMakefile* mf, bool verbose);
203
204   /** write some extra rules such as make test etc */
205   void WriteSpecialTargetsTop(std::ostream& makefileStream);
206   void WriteSpecialTargetsBottom(std::ostream& makefileStream);
207
208   std::string GetRelativeTargetDirectory(cmTarget const& target);
209
210   // File pairs for implicit dependency scanning.  The key of the map
211   // is the depender and the value is the explicit dependee.
212   struct ImplicitDependFileMap: public std::map<cmStdString, cmStdString> {};
213   struct ImplicitDependLanguageMap:
214     public std::map<cmStdString, ImplicitDependFileMap> {};
215   struct ImplicitDependTargetMap:
216     public std::map<cmStdString, ImplicitDependLanguageMap> {};
217   ImplicitDependLanguageMap const& GetImplicitDepends(cmTarget const& tgt);
218
219   void AddImplicitDepends(cmTarget const& tgt, const char* lang,
220                           const char* obj, const char* src);
221
222   void AppendGlobalTargetDepends(std::vector<std::string>& depends,
223                                  cmTarget& target);
224
225   // write the target rules for the local Makefile into the stream
226   void WriteLocalAllRules(std::ostream& ruleFileStream);
227
228   void AddLocalObjectFile(cmTarget* target, cmSourceFile* sf,
229                           std::string objNoTargetDir,
230                           bool hasSourceExtension);
231
232   std::vector<cmStdString> const& GetLocalHelp() { return this->LocalHelp; }
233
234   /** Get whether to create rules to generate preprocessed and
235       assembly sources.  This could be converted to a variable lookup
236       later.  */
237   bool GetCreatePreprocessedSourceRules()
238     {
239     return !this->SkipPreprocessedSourceRules;
240     }
241   bool GetCreateAssemblySourceRules()
242     {
243     return !this->SkipAssemblySourceRules;
244     }
245
246   // Fill the vector with the target names for the object files,
247   // preprocessed files and assembly files. Currently only used by the
248   // Eclipse generator.
249   void GetIndividualFileTargets(std::vector<std::string>& targets);
250
251 protected:
252   void WriteLocalMakefile();
253
254
255   // write the target rules for the local Makefile into the stream
256   void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
257                                  std::set<cmStdString> &emitted);
258
259   // this method Writes the Directory information files
260   void WriteDirectoryInformationFile();
261
262
263   // write the depend info
264   void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
265
266   // write the local help rule
267   void WriteHelpRule(std::ostream& ruleFileStream);
268
269   // this converts a file name that is relative to the StartOuputDirectory
270   // into a full path
271   std::string ConvertToFullPath(const std::string& localPath);
272
273
274   void WriteConvenienceRule(std::ostream& ruleFileStream,
275                             const char* realTarget,
276                             const char* helpTarget);
277
278   void WriteTargetDependRule(std::ostream& ruleFileStream,
279                              cmTarget& target);
280   void WriteTargetCleanRule(std::ostream& ruleFileStream,
281                             cmTarget& target,
282                             const std::vector<std::string>& files);
283   void WriteTargetRequiresRule(std::ostream& ruleFileStream,
284                                cmTarget& target,
285                                const std::vector<std::string>& objects);
286
287   void AppendRuleDepend(std::vector<std::string>& depends,
288                         const char* ruleFileName);
289   void AppendRuleDepends(std::vector<std::string>& depends,
290                          std::vector<std::string> const& ruleFiles);
291   void AppendCustomDepends(std::vector<std::string>& depends,
292                            const std::vector<cmCustomCommand>& ccs);
293   void AppendCustomDepend(std::vector<std::string>& depends,
294                           const cmCustomCommand& cc);
295   void AppendCustomCommands(std::vector<std::string>& commands,
296                             const std::vector<cmCustomCommand>& ccs,
297                             cmTarget* target,
298                             cmLocalGenerator::RelativeRoot relative =
299                             cmLocalGenerator::HOME_OUTPUT);
300   void AppendCustomCommand(std::vector<std::string>& commands,
301                            const cmCustomCommand& cc,
302                            cmTarget* target,
303                            bool echo_comment=false,
304                            cmLocalGenerator::RelativeRoot relative =
305                            cmLocalGenerator::HOME_OUTPUT,
306                            std::ostream* content = 0);
307   void AppendCleanCommand(std::vector<std::string>& commands,
308                           const std::vector<std::string>& files,
309                           cmTarget& target, const char* filename =0);
310
311   // Helper methods for dependeny updates.
312   bool ScanDependencies(const char* targetDir,
313                 std::map<std::string, cmDepends::DependencyVector>& validDeps);
314   void CheckMultipleOutputs(bool verbose);
315
316 private:
317   std::string ConvertShellCommand(std::string const& cmd, RelativeRoot root);
318   std::string MakeLauncher(const cmCustomCommand& cc, cmTarget* target,
319                            RelativeRoot relative);
320
321   friend class cmMakefileTargetGenerator;
322   friend class cmMakefileExecutableTargetGenerator;
323   friend class cmMakefileLibraryTargetGenerator;
324   friend class cmMakefileUtilityTargetGenerator;
325   friend class cmGlobalUnixMakefileGenerator3;
326
327   ImplicitDependTargetMap ImplicitDepends;
328
329   //==========================================================================
330   // Configuration settings.
331   int MakefileVariableSize;
332   std::string IncludeDirective;
333   std::string MakeSilentFlag;
334   std::string ConfigurationName;
335   bool DefineWindowsNULL;
336   bool UnixCD;
337   bool PassMakeflags;
338   bool SilentNoColon;
339   bool MakeCommandEscapeTargetTwice;
340   bool BorlandMakeCurlyHack;
341   //==========================================================================
342
343   std::string HomeRelativeOutputPath;
344
345   /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the
346      beginning of generation to avoid many duplicate lookups.  */
347   bool ColorMakefile;
348
349   /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and
350      CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to
351      avoid many duplicate lookups.  */
352   bool SkipPreprocessedSourceRules;
353   bool SkipAssemblySourceRules;
354
355   struct LocalObjectEntry
356   {
357     cmTarget* Target;
358     std::string Language;
359     LocalObjectEntry(): Target(0), Language() {}
360     LocalObjectEntry(cmTarget* t, const char* lang):
361       Target(t), Language(lang) {}
362   };
363   struct LocalObjectInfo: public std::vector<LocalObjectEntry>
364   {
365     bool HasSourceExtension;
366     bool HasPreprocessRule;
367     bool HasAssembleRule;
368     LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false),
369                       HasAssembleRule(false) {}
370   };
371   std::map<cmStdString, LocalObjectInfo> LocalObjectFiles;
372   void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
373                                   const char* comment, const char* output,
374                                   LocalObjectInfo const& info);
375
376   std::vector<cmStdString> LocalHelp;
377
378   /* does the work for each target */
379   std::map<cmStdString, cmStdString> MakeVariableMap;
380   std::map<cmStdString, cmStdString> ShortMakeVariableMap;
381 };
382
383 #endif