~ubuntu-branches/ubuntu/quantal/cmake/quantal

« back to all changes in this revision

Viewing changes to Source/cmGlobalNinjaGenerator.h

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2012-04-30 12:14:32 UTC
  • mfrom: (3.1.30 sid)
  • Revision ID: package-import@ubuntu.com-20120430121432-rqh2fjl3zcblehh5
Tags: 2.8.8-2ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add xfail_compiler_flag.diff: Mark compiler flag tests as expected
    failures.
  - Add ubuntu_qt_import_dir_variable.diff: define QT_IMPORTS_DIR even
    when that dir does not exist.
* Remove increase_ctest_test_timeout.diff, merged upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*============================================================================
 
2
  CMake - Cross Platform Makefile Generator
 
3
  Copyright 2011 Peter Collingbourne <peter@pcc.me.uk>
 
4
  Copyright 2011 Nicolas Despres <nicolas.despres@gmail.com>
 
5
 
 
6
  Distributed under the OSI-approved BSD License (the "License");
 
7
  see accompanying file Copyright.txt for details.
 
8
 
 
9
  This software is distributed WITHOUT ANY WARRANTY; without even the
 
10
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
11
  See the License for more information.
 
12
============================================================================*/
 
13
#ifndef cmGlobalNinjaGenerator_h
 
14
#  define cmGlobalNinjaGenerator_h
 
15
 
 
16
#  include "cmGlobalGenerator.h"
 
17
#  include "cmNinjaTypes.h"
 
18
 
 
19
class cmLocalGenerator;
 
20
class cmGeneratedFileStream;
 
21
class cmGeneratorTarget;
 
22
 
 
23
/**
 
24
 * \class cmGlobalNinjaGenerator
 
25
 * \brief Write a build.ninja file.
 
26
 *
 
27
 * The main differences between this generator and the UnixMakefile
 
28
 * generator family are:
 
29
 * - We don't care about VERBOSE variable or RULE_MESSAGES property since
 
30
 *   it is handle by Ninja's -v option.
 
31
 * - We don't care about computing any progress status since Ninja manages
 
32
 *   it itself.
 
33
 * - We don't care about generating a clean target since Ninja already have
 
34
 *   a clean tool.
 
35
 * - We generate one build.ninja and one rules.ninja per project.
 
36
 * - We try to minimize the number of generated rules: one per target and
 
37
 *   language.
 
38
 * - We use Ninja special variable $in and $out to produce nice output.
 
39
 * - We extensively use Ninja variable overloading system to minimize the
 
40
 *   number of generated rules.
 
41
 */
 
42
class cmGlobalNinjaGenerator : public cmGlobalGenerator
 
43
{
 
44
public:
 
45
  /// The default name of Ninja's build file. Typically: build.ninja.
 
46
  static const char* NINJA_BUILD_FILE;
 
47
 
 
48
  /// The default name of Ninja's rules file. Typically: rules.ninja.
 
49
  /// It is included in the main build.ninja file.
 
50
  static const char* NINJA_RULES_FILE;
 
51
 
 
52
  /// The indentation string used when generating Ninja's build file.
 
53
  static const char* INDENT;
 
54
 
 
55
  /// Write @a count times INDENT level to output stream @a os.
 
56
  static void Indent(std::ostream& os, int count);
 
57
 
 
58
  /// Write a divider in the given output stream @a os.
 
59
  static void WriteDivider(std::ostream& os);
 
60
 
 
61
  static std::string EncodeIdent(const std::string &ident, std::ostream &vars);
 
62
  static std::string EncodeLiteral(const std::string &lit);
 
63
  static std::string EncodePath(const std::string &path);
 
64
 
 
65
  /**
 
66
   * Write the given @a comment to the output stream @a os. It
 
67
   * handles new line character properly.
 
68
   */
 
69
  static void WriteComment(std::ostream& os, const std::string& comment);
 
70
 
 
71
  /**
 
72
   * Write a build statement to @a os with the @a comment using
 
73
   * the @a rule the list of @a outputs files and inputs.
 
74
   * It also writes the variables bound to this build statement.
 
75
   * @warning no escaping of any kind is done here.
 
76
   */
 
77
  static void WriteBuild(std::ostream& os,
 
78
                         const std::string& comment,
 
79
                         const std::string& rule,
 
80
                         const cmNinjaDeps& outputs,
 
81
                         const cmNinjaDeps& explicitDeps,
 
82
                         const cmNinjaDeps& implicitDeps,
 
83
                         const cmNinjaDeps& orderOnlyDeps,
 
84
                         const cmNinjaVars& variables);
 
85
 
 
86
  /**
 
87
   * Helper to write a build statement with the special 'phony' rule.
 
88
   */
 
89
  static void WritePhonyBuild(std::ostream& os,
 
90
                              const std::string& comment,
 
91
                              const cmNinjaDeps& outputs,
 
92
                              const cmNinjaDeps& explicitDeps,
 
93
                              const cmNinjaDeps& implicitDeps = cmNinjaDeps(),
 
94
                              const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(),
 
95
                              const cmNinjaVars& variables = cmNinjaVars());
 
96
 
 
97
  void WriteCustomCommandBuild(const std::string& command,
 
98
                               const std::string& description,
 
99
                               const std::string& comment,
 
100
                               const cmNinjaDeps& outputs,
 
101
                               const cmNinjaDeps& deps = cmNinjaDeps(),
 
102
                             const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
 
103
 
 
104
  /**
 
105
   * Write a rule statement named @a name to @a os with the @a comment,
 
106
   * the mandatory @a command, the @a depfile and the @a description.
 
107
   * It also writes the variables bound to this rule statement.
 
108
   * @warning no escaping of any kind is done here.
 
109
   */
 
110
  static void WriteRule(std::ostream& os,
 
111
                        const std::string& name,
 
112
                        const std::string& command,
 
113
                        const std::string& description,
 
114
                        const std::string& comment = "",
 
115
                        const std::string& depfile = "",
 
116
                        bool restat = false,
 
117
                        bool generator = false);
 
118
 
 
119
  /**
 
120
   * Write a variable named @a name to @a os with value @a value and an
 
121
   * optional @a comment. An @a indent level can be specified.
 
122
   * @warning no escaping of any kind is done here.
 
123
   */
 
124
  static void WriteVariable(std::ostream& os,
 
125
                            const std::string& name,
 
126
                            const std::string& value,
 
127
                            const std::string& comment = "",
 
128
                            int indent = 0);
 
129
 
 
130
  /**
 
131
   * Write an include statement including @a filename with an optional
 
132
   * @a comment to the @a os stream.
 
133
   */
 
134
  static void WriteInclude(std::ostream& os,
 
135
                           const std::string& filename,
 
136
                           const std::string& comment = "");
 
137
 
 
138
  /**
 
139
   * Write a default target statement specifying @a targets as
 
140
   * the default targets.
 
141
   */
 
142
  static void WriteDefault(std::ostream& os,
 
143
                           const cmNinjaDeps& targets,
 
144
                           const std::string& comment = "");
 
145
 
 
146
public:
 
147
  /// Default constructor.
 
148
  cmGlobalNinjaGenerator();
 
149
 
 
150
  /// Convenience method for creating an instance of this class.
 
151
  static cmGlobalGenerator* New() {
 
152
    return new cmGlobalNinjaGenerator; }
 
153
 
 
154
  /// Destructor.
 
155
  virtual ~cmGlobalNinjaGenerator() { }
 
156
 
 
157
  /// Overloaded methods. @see cmGlobalGenerator::CreateLocalGenerator()
 
158
  virtual cmLocalGenerator* CreateLocalGenerator();
 
159
 
 
160
  /// Overloaded methods. @see cmGlobalGenerator::GetName().
 
161
  virtual const char* GetName() const {
 
162
    return cmGlobalNinjaGenerator::GetActualName(); }
 
163
 
 
164
  /// @return the name of this generator.
 
165
  static const char* GetActualName() { return "Ninja"; }
 
166
 
 
167
  /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
 
168
  virtual void GetDocumentation(cmDocumentationEntry& entry) const;
 
169
 
 
170
  /// Overloaded methods. @see cmGlobalGenerator::Generate()
 
171
  virtual void Generate();
 
172
 
 
173
  /// Overloaded methods. @see cmGlobalGenerator::EnableLanguage()
 
174
  virtual void EnableLanguage(std::vector<std::string>const& languages,
 
175
                              cmMakefile* mf,
 
176
                              bool optional);
 
177
 
 
178
  /// Overloaded methods. @see cmGlobalGenerator::GenerateBuildCommand()
 
179
  virtual std::string GenerateBuildCommand(const char* makeProgram,
 
180
                                           const char* projectName,
 
181
                                           const char* additionalOptions,
 
182
                                           const char* targetName,
 
183
                                           const char* config,
 
184
                                           bool ignoreErrors,
 
185
                                           bool fast);
 
186
 
 
187
  // Setup target names
 
188
  virtual const char* GetAllTargetName()           const { return "all"; }
 
189
  virtual const char* GetInstallTargetName()       const { return "install"; }
 
190
  virtual const char* GetInstallLocalTargetName()  const {
 
191
    return "install/local";
 
192
  }
 
193
  virtual const char* GetInstallStripTargetName()  const {
 
194
    return "install/strip";
 
195
  }
 
196
  virtual const char* GetTestTargetName()          const { return "test"; }
 
197
  virtual const char* GetPackageTargetName()       const { return "package"; }
 
198
  virtual const char* GetPackageSourceTargetName() const {
 
199
    return "package_source";
 
200
  }
 
201
  virtual const char* GetEditCacheTargetName()     const {
 
202
    return "edit_cache";
 
203
  }
 
204
  virtual const char* GetRebuildCacheTargetName()  const {
 
205
    return "rebuild_cache";
 
206
  }
 
207
  virtual const char* GetCleanTargetName()         const { return "clean"; }
 
208
 
 
209
public:
 
210
  cmGeneratedFileStream* GetBuildFileStream() const
 
211
  { return this->BuildFileStream; }
 
212
 
 
213
  cmGeneratedFileStream* GetRulesFileStream() const
 
214
  { return this->RulesFileStream; }
 
215
 
 
216
  /**
 
217
   * Add a rule to the generated build system.
 
218
   * Call WriteRule() behind the scene but perform some check before like:
 
219
   * - Do not add twice the same rule.
 
220
   */
 
221
  void AddRule(const std::string& name,
 
222
               const std::string& command,
 
223
               const std::string& description,
 
224
               const std::string& comment = "",
 
225
               const std::string& depfile = "",
 
226
               bool restat = false,
 
227
               bool generator = false);
 
228
 
 
229
  bool HasRule(const std::string& name);
 
230
 
 
231
  void AddCustomCommandRule();
 
232
 
 
233
protected:
 
234
 
 
235
  /// Overloaded methods.
 
236
  /// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
 
237
  virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
 
238
 
 
239
private:
 
240
 
 
241
  /// @see cmGlobalGenerator::ComputeTargetObjects
 
242
  virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
 
243
 
 
244
private:
 
245
  // In order to access the AddDependencyToAll() functions and co.
 
246
  friend class cmLocalNinjaGenerator;
 
247
 
 
248
  // In order to access the SeenCustomCommand() function.
 
249
  friend class cmNinjaTargetGenerator;
 
250
  friend class cmNinjaNormalTargetGenerator;
 
251
  friend class cmNinjaUtilityTargetGenerator;
 
252
 
 
253
private:
 
254
  void OpenBuildFileStream();
 
255
  void CloseBuildFileStream();
 
256
 
 
257
  void OpenRulesFileStream();
 
258
  void CloseRulesFileStream();
 
259
 
 
260
  /// Write the common disclaimer text at the top of each build file.
 
261
  void WriteDisclaimer(std::ostream& os);
 
262
 
 
263
  void AddDependencyToAll(cmTarget* target);
 
264
 
 
265
  void WriteAssumedSourceDependencies();
 
266
 
 
267
  void AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs);
 
268
  void AppendTargetDepends(cmTarget* target, cmNinjaDeps& outputs);
 
269
 
 
270
  void AddTargetAlias(const std::string& alias, cmTarget* target);
 
271
  void WriteTargetAliases(std::ostream& os);
 
272
 
 
273
  void WriteBuiltinTargets(std::ostream& os);
 
274
  void WriteTargetAll(std::ostream& os);
 
275
  void WriteTargetRebuildManifest(std::ostream& os);
 
276
 
 
277
  /// Called when we have seen the given custom command.  Returns true
 
278
  /// if we has seen it before.
 
279
  bool SeenCustomCommand(cmCustomCommand const *cc) {
 
280
    return !this->CustomCommands.insert(cc).second;
 
281
  }
 
282
 
 
283
  /// Called when we have seen the given custom command output.
 
284
  void SeenCustomCommandOutput(const std::string &output) {
 
285
    this->CustomCommandOutputs.insert(output);
 
286
    // We don't need the assumed dependencies anymore, because we have
 
287
    // an output.
 
288
    this->AssumedSourceDependencies.erase(output);
 
289
  }
 
290
 
 
291
  bool HasCustomCommandOutput(const std::string &output) {
 
292
    return this->CustomCommandOutputs.find(output) !=
 
293
           this->CustomCommandOutputs.end();
 
294
  }
 
295
 
 
296
  void AddAssumedSourceDependencies(const std::string &source,
 
297
                                    const cmNinjaDeps &deps) {
 
298
    std::set<std::string> &ASD = this->AssumedSourceDependencies[source];
 
299
    // Because we may see the same source file multiple times (same source
 
300
    // specified in multiple targets), compute the union of any assumed
 
301
    // dependencies.
 
302
    ASD.insert(deps.begin(), deps.end());
 
303
  }
 
304
 
 
305
private:
 
306
  /// The file containing the build statement. (the relation ship of the
 
307
  /// compilation DAG).
 
308
  cmGeneratedFileStream* BuildFileStream;
 
309
  /// The file containing the rule statements. (The action attached to each
 
310
  /// edge of the compilation DAG).
 
311
  cmGeneratedFileStream* RulesFileStream;
 
312
 
 
313
  /// The type used to store the set of rules added to the generated build
 
314
  /// system.
 
315
  typedef std::set<std::string> RulesSetType;
 
316
 
 
317
  /// The set of rules added to the generated build system.
 
318
  RulesSetType Rules;
 
319
 
 
320
  /// The set of dependencies to add to the "all" target.
 
321
  cmNinjaDeps AllDependencies;
 
322
 
 
323
  /// The set of custom commands we have seen.
 
324
  std::set<cmCustomCommand const*> CustomCommands;
 
325
 
 
326
  /// The set of custom command outputs we have seen.
 
327
  std::set<std::string> CustomCommandOutputs;
 
328
 
 
329
  /// The mapping from source file to assumed dependencies.
 
330
  std::map<std::string, std::set<std::string> > AssumedSourceDependencies;
 
331
 
 
332
  typedef std::map<std::string, cmTarget*> TargetAliasMap;
 
333
  TargetAliasMap TargetAliases;
 
334
 
 
335
  static cmLocalGenerator* LocalGenerator;
 
336
};
 
337
 
 
338
#endif // ! cmGlobalNinjaGenerator_h