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: 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);
219 void AddImplicitDepends(cmTarget const& tgt, const char* lang,
220 const char* obj, const char* src);
222 void AppendGlobalTargetDepends(std::vector<std::string>& depends,
225 // write the target rules for the local Makefile into the stream
226 void WriteLocalAllRules(std::ostream& ruleFileStream);
228 void AddLocalObjectFile(cmTarget* target, cmSourceFile* sf,
229 std::string objNoTargetDir,
230 bool hasSourceExtension);
232 std::vector<cmStdString> const& GetLocalHelp() { return this->LocalHelp; }
234 /** Get whether to create rules to generate preprocessed and
235 assembly sources. This could be converted to a variable lookup
237 bool GetCreatePreprocessedSourceRules()
239 return !this->SkipPreprocessedSourceRules;
241 bool GetCreateAssemblySourceRules()
243 return !this->SkipAssemblySourceRules;
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);
252 void WriteLocalMakefile();
255 // write the target rules for the local Makefile into the stream
256 void WriteLocalMakefileTargets(std::ostream& ruleFileStream,
257 std::set<cmStdString> &emitted);
259 // this method Writes the Directory information files
260 void WriteDirectoryInformationFile();
263 // write the depend info
264 void WriteDependLanguageInfo(std::ostream& cmakefileStream, cmTarget &tgt);
266 // write the local help rule
267 void WriteHelpRule(std::ostream& ruleFileStream);
269 // this converts a file name that is relative to the StartOuputDirectory
271 std::string ConvertToFullPath(const std::string& localPath);
274 void WriteConvenienceRule(std::ostream& ruleFileStream,
275 const char* realTarget,
276 const char* helpTarget);
278 void WriteTargetDependRule(std::ostream& ruleFileStream,
280 void WriteTargetCleanRule(std::ostream& ruleFileStream,
282 const std::vector<std::string>& files);
283 void WriteTargetRequiresRule(std::ostream& ruleFileStream,
285 const std::vector<std::string>& objects);
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,
298 cmLocalGenerator::RelativeRoot relative =
299 cmLocalGenerator::HOME_OUTPUT);
300 void AppendCustomCommand(std::vector<std::string>& commands,
301 const cmCustomCommand& cc,
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);
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);
317 std::string ConvertShellCommand(std::string const& cmd, RelativeRoot root);
318 std::string MakeLauncher(const cmCustomCommand& cc, cmTarget* target,
319 RelativeRoot relative);
321 friend class cmMakefileTargetGenerator;
322 friend class cmMakefileExecutableTargetGenerator;
323 friend class cmMakefileLibraryTargetGenerator;
324 friend class cmMakefileUtilityTargetGenerator;
325 friend class cmGlobalUnixMakefileGenerator3;
327 ImplicitDependTargetMap ImplicitDepends;
329 //==========================================================================
330 // Configuration settings.
331 int MakefileVariableSize;
332 std::string IncludeDirective;
333 std::string MakeSilentFlag;
334 std::string ConfigurationName;
335 bool DefineWindowsNULL;
339 bool MakeCommandEscapeTargetTwice;
340 bool BorlandMakeCurlyHack;
341 //==========================================================================
343 std::string HomeRelativeOutputPath;
345 /* Copy the setting of CMAKE_COLOR_MAKEFILE from the makefile at the
346 beginning of generation to avoid many duplicate lookups. */
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;
355 struct LocalObjectEntry
358 std::string Language;
359 LocalObjectEntry(): Target(0), Language() {}
360 LocalObjectEntry(cmTarget* t, const char* lang):
361 Target(t), Language(lang) {}
363 struct LocalObjectInfo: public std::vector<LocalObjectEntry>
365 bool HasSourceExtension;
366 bool HasPreprocessRule;
367 bool HasAssembleRule;
368 LocalObjectInfo():HasSourceExtension(false), HasPreprocessRule(false),
369 HasAssembleRule(false) {}
371 std::map<cmStdString, LocalObjectInfo> LocalObjectFiles;
372 void WriteObjectConvenienceRule(std::ostream& ruleFileStream,
373 const char* comment, const char* output,
374 LocalObjectInfo const& info);
376 std::vector<cmStdString> LocalHelp;
378 /* does the work for each target */
379 std::map<cmStdString, cmStdString> MakeVariableMap;
380 std::map<cmStdString, cmStdString> ShortMakeVariableMap;