1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
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
15 #include "cmLocalGenerator.h"
17 // for cmDepends::DependencyVector
18 #include "cmDepends.h"
20 class cmCustomCommand;
21 class cmDependInformation;
23 class cmMakefileTargetGenerator;
27 /** \class cmLocalUnixMakefileGenerator3
28 * \brief Write a LocalUnix makefiles.
30 * cmLocalUnixMakefileGenerator3 produces a LocalUnix makefile from its
33 class cmLocalUnixMakefileGenerator3 : public cmLocalGenerator
36 cmLocalUnixMakefileGenerator3();
37 virtual ~cmLocalUnixMakefileGenerator3();
40 * Process the CMakeLists files for this directory to fill in the
43 virtual void Configure();
46 * Generate the makefile for this directory.
48 virtual void Generate();
51 // this returns the relative path between the HomeOutputDirectory and this
52 // local generators StartOutputDirectory
53 const std::string &GetHomeRelativeOutputPath();
55 // Write out a make rule
56 void WriteMakeRule(std::ostream& os,
59 const std::vector<std::string>& depends,
60 const std::vector<std::string>& commands,
62 bool in_help = false);
64 // write the main variables used by the makefiles
65 void WriteMakeVariables(std::ostream& makefileStream);
68 * If true, then explicitly pass MAKEFLAGS on the make all target for makes
69 * that do not use environment variables.
72 void SetPassMakeflags(bool s){this->PassMakeflags = s;}
73 bool GetPassMakeflags() { return this->PassMakeflags; }
76 * Set the flag used to keep the make program silent.
78 void SetMakeSilentFlag(const char* s) { this->MakeSilentFlag = s; }
79 std::string &GetMakeSilentFlag() { return this->MakeSilentFlag; }
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.
86 void SetWindowsShell(bool v) {this->WindowsShell = v;}
89 * Set to true if the make tool being used is Watcom WMake.
91 void SetWatcomWMake(bool v) {this->WatcomWMake = v;}
94 * Set to true if the make tool being used is MinGW Make.
96 void SetMinGWMake(bool v) {this->MinGWMake = v;}
99 * Set to true if the make tool being used is NMake.
101 void SetNMake(bool v) {this->NMake = v;}
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.
108 void SetMSYSShell(bool v) {this->MSYSShell = v;}
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.
115 void SetDefineWindowsNULL(bool v) {this->DefineWindowsNULL = v;}
118 * If set to true, cd dir && command is used to
119 * run commands in a different directory.
121 void SetUnixCD(bool v) {this->UnixCD = v;}
124 * Set Support Verbose Variable. If true, then .SILENT will
125 * be not end with : i.e. .SILENT: or .SILENT
127 void SetSilentNoColon(bool v) {this->SilentNoColon = v;}
130 * Set the string used to include one makefile into another default
133 void SetIncludeDirective(const char* s) { this->IncludeDirective = s; }
134 const char *GetIncludeDirective() { return this->IncludeDirective.c_str(); }
137 * Set max makefile variable size, default is 0 which means unlimited.
139 void SetMakefileVariableSize(int s) { this->MakefileVariableSize = s; }
142 * If ignore lib prefix is true, then do not strip lib from the name
145 void SetIgnoreLibPrefix(bool s) { this->IgnoreLibPrefix = s; }
148 * Set whether passing a make target on a command line requires an
149 * extra level of escapes.
151 void SetMakeCommandEscapeTargetTwice(bool b)
152 { this->MakeCommandEscapeTargetTwice = b; }
155 * Set whether the Borland curly brace command line hack should be
158 void SetBorlandMakeCurlyHack(bool b)
159 { this->BorlandMakeCurlyHack = b; }
161 // used in writing out Cmake files such as WriteDirectoryInformation
162 static void WriteCMakeArgument(std::ostream& os, const char* s);
164 /** creates the common disclaimer text at the top of each makefile */
165 void WriteDisclaimer(std::ostream& os);
167 // write a comment line #====... in the stream
168 void WriteDivider(std::ostream& os);
170 /** used to create a recursive make call */
171 std::string GetRecursiveMakeCall(const char *makefile, const char* tgt);
173 // append flags to a string
174 virtual void AppendFlags(std::string& flags, const char* newFlags);
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);
182 /** Get whether the makefile is to have color. */
183 bool GetColorMakefile() const { return this->ColorMakefile; }
185 virtual std::string GetTargetDirectory(cmTarget const& target) const;
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);
192 static std::string ConvertToQuotedOutputPath(const char* p);
194 std::string CreateMakeVariable(const char* sin, const char* s2in);
196 /** Called from command-line hook to bring dependencies up to date
198 virtual bool UpdateDependencies(const char* tgtInfo,
199 bool verbose, bool color);
201 /** Called from command-line hook to clear dependencies. */
202 virtual void ClearDependencies(cmMakefile* mf, bool verbose);
204 /** write some extra rules such as make test etc */
205 void WriteSpecialTargetsTop(std::ostream& makefileStream);
206 void WriteSpecialTargetsBottom(std::ostream& makefileStream);
208 std::string GetRelativeTargetDirectory(cmTarget const& target);
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:
213 public std::map<cmStdString, cmDepends::DependencyVector> {};
214 struct ImplicitDependLanguageMap:
215 public std::map<cmStdString, ImplicitDependFileMap> {};
216 struct ImplicitDependTargetMap:
217 public std::map<cmStdString, ImplicitDependLanguageMap> {};
218 ImplicitDependLanguageMap const& GetImplicitDepends(cmTarget const& tgt);
220 void AddImplicitDepends(cmTarget const& tgt, const char* lang,
221 const char* obj, const char* src);
223 void AppendGlobalTargetDepends(std::vector<std::string>& depends,
226 // write the target rules for the local Makefile into the stream
227 void WriteLocalAllRules(std::ostream& ruleFileStream);
229 void AddLocalObjectFile(cmTarget* target, cmSourceFile* sf,
230 std::string objNoTargetDir,
231 bool hasSourceExtension);
233 std::vector<cmStdString> const& GetLocalHelp() { return this->LocalHelp; }
235 /** Get whether to create rules to generate preprocessed and
236 assembly sources. This could be converted to a variable lookup
238 bool GetCreatePreprocessedSourceRules()
240 return !this->SkipPreprocessedSourceRules;
242 bool GetCreateAssemblySourceRules()
244 return !this->SkipAssemblySourceRules;
247 // Fill the vector with the target names for the object files,
248 // preprocessed files and assembly files. Currently only used by the
249 // Eclipse generator.
250 void GetIndividualFileTargets(std::vector<std::string>& targets);
253 void WriteLocalMakefile();
256 // write the target rules for the local Makefile into the stream
257 void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
258 std::set<cmStdString> &emitted);
260 // this method Writes the Directory information files
261 void WriteDirectoryInformationFile();
264 // write the depend info
265 void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
267 // write the local help rule
268 void WriteHelpRule(std::ostream& ruleFileStream);
270 // this converts a file name that is relative to the StartOuputDirectory
272 std::string ConvertToFullPath(const std::string& localPath);
275 void WriteConvenienceRule(std::ostream& ruleFileStream,
276 const char* realTarget,
277 const char* helpTarget);
279 void WriteTargetDependRule(std::ostream& ruleFileStream,
281 void WriteTargetCleanRule(std::ostream& ruleFileStream,
283 const std::vector<std::string>& files);
284 void WriteTargetRequiresRule(std::ostream& ruleFileStream,
286 const std::vector<std::string>& objects);
288 void AppendRuleDepend(std::vector<std::string>& depends,
289 const char* ruleFileName);
290 void AppendRuleDepends(std::vector<std::string>& depends,
291 std::vector<std::string> const& ruleFiles);
292 void AppendCustomDepends(std::vector<std::string>& depends,
293 const std::vector<cmCustomCommand>& ccs);
294 void AppendCustomDepend(std::vector<std::string>& depends,
295 const cmCustomCommand& cc);
296 void AppendCustomCommands(std::vector<std::string>& commands,
297 const std::vector<cmCustomCommand>& ccs,
299 cmLocalGenerator::RelativeRoot relative =
300 cmLocalGenerator::HOME_OUTPUT);
301 void AppendCustomCommand(std::vector<std::string>& commands,
302 const cmCustomCommand& cc,
304 bool echo_comment=false,
305 cmLocalGenerator::RelativeRoot relative =
306 cmLocalGenerator::HOME_OUTPUT,
307 std::ostream* content = 0);
308 void AppendCleanCommand(std::vector<std::string>& commands,
309 const std::vector<std::string>& files,
310 cmTarget& target, const char* filename =0);
312 // Helper methods for dependeny updates.
313 bool ScanDependencies(const char* targetDir,
314 std::map<std::string, cmDepends::DependencyVector>& validDeps);
315 void CheckMultipleOutputs(bool verbose);
318 std::string ConvertShellCommand(std::string const& cmd, RelativeRoot root);
319 std::string MakeLauncher(const cmCustomCommand& cc, cmTarget* target,
320 RelativeRoot relative);
322 friend class cmMakefileTargetGenerator;
323 friend class cmMakefileExecutableTargetGenerator;
324 friend class cmMakefileLibraryTargetGenerator;
325 friend class cmMakefileUtilityTargetGenerator;
326 friend class cmGlobalUnixMakefileGenerator3;
328 ImplicitDependTargetMap ImplicitDepends;
330 //==========================================================================
331 // Configuration settings.
332 int MakefileVariableSize;
333 std::string IncludeDirective;
334 std::string MakeSilentFlag;
335 std::string ConfigurationName;
336 bool DefineWindowsNULL;
340 bool MakeCommandEscapeTargetTwice;
341 bool BorlandMakeCurlyHack;
342 //==========================================================================
344 std::string HomeRelativeOutputPath;
346 /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the
347 beginning of generation to avoid many duplicate lookups. */
350 /* Copy the setting of CMAKE_SKIP_PREPROCESSED_SOURCE_RULES and
351 CMAKE_SKIP_ASSEMBLY_SOURCE_RULES at the beginning of generation to
352 avoid many duplicate lookups. */
353 bool SkipPreprocessedSourceRules;
354 bool SkipAssemblySourceRules;
356 struct LocalObjectEntry
359 std::string Language;
360 LocalObjectEntry(): Target(0), Language() {}
361 LocalObjectEntry(cmTarget* t, const char* lang):
362 Target(t), Language(lang) {}
364 struct LocalObjectInfo: public std::vector<LocalObjectEntry>
366 bool HasSourceExtension;
367 bool HasPreprocessRule;
368 bool HasAssembleRule;
369 LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false),
370 HasAssembleRule(false) {}
372 std::map<cmStdString, LocalObjectInfo> LocalObjectFiles;
373 void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
374 const char* comment, const char* output,
375 LocalObjectInfo const& info);
377 std::vector<cmStdString> LocalHelp;
379 /* does the work for each target */
380 std::map<cmStdString, cmStdString> MakeVariableMap;
381 std::map<cmStdString, cmStdString> ShortMakeVariableMap;