cmLocalGenerator.h 15.5 KB
Newer Older
1
2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
Ken Martin's avatar
Ken Martin committed
3
4
5
#ifndef cmLocalGenerator_h
#define cmLocalGenerator_h

6
7
#include <cmConfigure.h>

8
#include "cmListFileCache.h"
9
#include "cmOutputConverter.h"
10
#include "cmPolicies.h"
11
#include "cmState.h"
12
#include "cmake.h"
Ken Martin's avatar
Ken Martin committed
13

14
15
16
17
18
19
20
21
#include <cm_kwiml.h>
#include <iosfwd>
#include <map>
#include <set>
#include <string.h>
#include <string>
#include <vector>

22
class cmComputeLinkInformation;
23
class cmCustomCommandGenerator;
24
class cmGeneratorTarget;
25
26
class cmGlobalGenerator;
class cmMakefile;
27
class cmSourceFile;
28
class cmLinkLineComputer;
Ken Martin's avatar
Ken Martin committed
29
30
31
32
33

/** \class cmLocalGenerator
 * \brief Create required build files for a directory.
 *
 * Subclasses of this abstract class generate makefiles, DSP, etc for various
Nicolas Despres's avatar
Nicolas Despres committed
34
 * platforms. This class should never be constructed directly. A
Ken Martin's avatar
Ken Martin committed
35
36
 * GlobalGenerator will create it and invoke the appropriate commands on it.
 */
37
class cmLocalGenerator : public cmOutputConverter
Ken Martin's avatar
Ken Martin committed
38
39
{
public:
40
  cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
Ken Martin's avatar
Ken Martin committed
41
  virtual ~cmLocalGenerator();
42

Ken Martin's avatar
Ken Martin committed
43
  /**
44
   * Generate the makefile for this directory.
Ken Martin's avatar
Ken Martin committed
45
   */
Alexander Neundorf's avatar
   
Alexander Neundorf committed
46
  virtual void Generate() {}
Ken Martin's avatar
Ken Martin committed
47

48
49
  virtual void ComputeHomeRelativeOutputPath() {}

50
  /**
Alexander Neundorf's avatar
   
Alexander Neundorf committed
51
52
   * Calls TraceVSDependencies() on all targets of this generator.
   */
53
  void TraceDependencies();
Alexander Neundorf's avatar
   
Alexander Neundorf committed
54
55
56

  virtual void AddHelperCommands() {}

57
58
59
  /**
   * Generate the install rules files in this directory.
   */
60
  void GenerateInstallRules();
61

62
63
64
  /**
   * Generate the test files for tests.
   */
65
  void GenerateTestFiles();
66
67
68
69

  /**
   * Generate a manifest of target files that will be built.
   */
70
  void ComputeTargetManifest();
71

72
73
  bool IsRootMakefile() const;

Ken Martin's avatar
Ken Martin committed
74
  ///! Get the makefile for this generator
75
  cmMakefile* GetMakefile() { return this->Makefile; }
76

Alexander Neundorf's avatar
   
Alexander Neundorf committed
77
  ///! Get the makefile for this generator, const version
78
  const cmMakefile* GetMakefile() const { return this->Makefile; }
79

Ken Martin's avatar
Ken Martin committed
80
  ///! Get the GlobalGenerator this is associated with
81
82
83
84
85
  cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
  const cmGlobalGenerator* GetGlobalGenerator() const
  {
    return this->GlobalGenerator;
  }
Ken Martin's avatar
Ken Martin committed
86

87
88
89
  std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
                                 cmGeneratorTarget& tgt) const;

90
91
92
  cmState* GetState() const;
  cmState::Snapshot GetStateSnapshot() const;

93
94
  void AddArchitectureFlags(std::string& flags,
                            cmGeneratorTarget const* target,
95
96
                            const std::string& lang,
                            const std::string& config);
97

98
  void AddLanguageFlags(std::string& flags, const std::string& lang,
99
                        const std::string& config);
100
  void AddCMP0018Flags(std::string& flags, cmGeneratorTarget const* target,
101
                       std::string const& lang, const std::string& config);
102
  void AddVisibilityPresetFlags(std::string& flags,
103
                                cmGeneratorTarget const* target,
104
                                const std::string& lang);
105
  void AddConfigVariableFlags(std::string& flags, const std::string& var,
106
                              const std::string& config);
107
  void AddCompilerRequirementFlag(std::string& flags,
108
                                  cmGeneratorTarget const* target,
109
                                  const std::string& lang);
110
  ///! Append flags to a string.
111
  virtual void AppendFlags(std::string& flags, const std::string& newFlags);
112
  virtual void AppendFlags(std::string& flags, const char* newFlags);
113
114
  virtual void AppendFlagEscape(std::string& flags,
                                const std::string& rawFlag);
115
  ///! Get the include flags for the current makefile and language
116
  std::string GetIncludeFlags(const std::vector<std::string>& includes,
117
                              cmGeneratorTarget* target,
118
                              const std::string& lang,
119
                              bool forceFullPaths = false,
120
                              bool forResponseFile = false,
121
                              const std::string& config = "");
122

123
124
125
126
  const std::vector<cmGeneratorTarget*>& GetGeneratorTargets() const
  {
    return this->GeneratorTargets;
  }
127

128
129
130
131
  const std::vector<cmGeneratorTarget*>& GetImportedGeneratorTargets() const
  {
    return this->ImportedGeneratorTargets;
  }
132

133
  void AddGeneratorTarget(cmGeneratorTarget* gt);
134
  void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
135
  void AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt);
136

137
138
  cmGeneratorTarget* FindLocalNonAliasGeneratorTarget(
    const std::string& name) const;
139
140
  cmGeneratorTarget* FindGeneratorTargetToUse(const std::string& name) const;

141
142
143
144
  /**
   * Encode a list of preprocessor definitions for the compiler
   * command line.
   */
145
146
147
148
  void AppendDefines(std::set<std::string>& defines,
                     const char* defines_list) const;
  void AppendDefines(std::set<std::string>& defines,
                     std::string defines_list) const
149
150
151
  {
    this->AppendDefines(defines, defines_list.c_str());
  }
152
  void AppendDefines(std::set<std::string>& defines,
153
                     const std::vector<std::string>& defines_vec) const;
154

155
156
157
158
  /**
   * Join a set of defines into a definesString with a space separator.
   */
  void JoinDefines(const std::set<std::string>& defines,
159
                   std::string& definesString, const std::string& lang);
160

161
  /** Lookup and append options associated with a particular feature.  */
162
  void AppendFeatureOptions(std::string& flags, const std::string& lang,
163
164
                            const char* feature);

165
166
167
  const char* GetFeature(const std::string& feature,
                         const std::string& config);

168
169
170
171
172
173
174
175
176
177
178
179
  /** \brief Get absolute path to dependency \a name
   *
   * Translate a dependency as given in CMake code to the name to
   * appear in a generated build file.
   * - If \a name is a utility target, returns false.
   * - If \a name is a CMake target, it will be transformed to the real output
   *   location of that target for the given configuration.
   * - If \a name is the full path to a file, it will be returned.
   * - Otherwise \a name is treated as a relative path with respect to
   *   the source directory of this generator.  This should only be
   *   used for dependencies of custom commands.
   */
180
  bool GetRealDependency(const std::string& name, const std::string& config,
181
182
                         std::string& dep);

183
184
185
186
  virtual std::string ConvertToIncludeReference(
    std::string const& path,
    cmOutputConverter::OutputFormat format = cmOutputConverter::SHELL,
    bool forceFullPaths = false);
187

188
  /** Called from command-line hook to clear dependencies.  */
189
  virtual void ClearDependencies(cmMakefile* /* mf */, bool /* verbose */) {}
190

191
  /** Called from command-line hook to update dependencies.  */
192
  virtual bool UpdateDependencies(const char* /* tgtInfo */, bool /*verbose*/,
193
                                  bool /*color*/)
194
195
196
  {
    return true;
  }
Ken Martin's avatar
Ken Martin committed
197

198
  /** Get the include flags for the current makefile and language.  */
199
  void GetIncludeDirectories(std::vector<std::string>& dirs,
200
                             cmGeneratorTarget const* target,
201
                             const std::string& lang = "C",
202
                             const std::string& config = "",
203
                             bool stripImplicitInclDirs = true) const;
204
  void AddCompileOptions(std::string& flags, cmGeneratorTarget* target,
205
                         const std::string& lang, const std::string& config);
206
  void AddCompileDefinitions(std::set<std::string>& defines,
207
                             cmGeneratorTarget const* target,
208
                             const std::string& config,
209
                             const std::string& lang) const;
210

211
212
  std::string GetProjectName() const;

213
  /** Compute the language used to compile the given source file.  */
214
  std::string GetSourceFileLanguage(const cmSourceFile& source);
215

216
217
  // Fill the vector with the target names for the object files,
  // preprocessed files and assembly files.
218
  void GetIndividualFileTargets(std::vector<std::string>&) {}
219

220
221
222
223
  // Create a struct to hold the varibles passed into
  // ExpandRuleVariables
  struct RuleVariables
  {
224
    RuleVariables() { memset(this, 0, sizeof(*this)); }
225
226
    const char* CMTargetName;
    const char* CMTargetType;
227
    const char* TargetPDB;
228
    const char* TargetCompilePDB;
229
230
    const char* TargetVersionMajor;
    const char* TargetVersionMinor;
231
232
233
234
235
    const char* Language;
    const char* Objects;
    const char* Target;
    const char* LinkLibraries;
    const char* Source;
236
237
    const char* AssemblySource;
    const char* PreprocessedSource;
238
    const char* Output;
239
    const char* Object;
240
    const char* ObjectDir;
241
    const char* ObjectFileDir;
242
243
    const char* Flags;
    const char* ObjectsQuoted;
244
    const char* SONameFlag;
245
    const char* TargetSOName;
246
    const char* TargetInstallNameDir;
247
    const char* LinkFlags;
248
    const char* Manifests;
249
    const char* LanguageCompileFlags;
250
    const char* Defines;
251
    const char* Includes;
252
    const char* RuleLauncher;
253
    const char* DependencyFile;
254
    const char* FilterPrefix;
255
  };
Bill Hoffman's avatar
Bill Hoffman committed
256

257
258
259
260
  /**
   * Get the relative path from the generator output directory to a
   * per-target support directory.
   */
261
262
  virtual std::string GetTargetDirectory(
    cmGeneratorTarget const* target) const;
263

264
265
266
267
268
269
270
271
272
273
  /**
   * Get the level of backwards compatibility requested by the project
   * in this directory.  This is the value of the CMake variable
   * CMAKE_BACKWARDS_COMPATIBILITY whose format is
   * "major.minor[.patch]".  The returned integer is encoded as
   *
   *   CMake_VERSION_ENCODE(major, minor, patch)
   *
   * and is monotonically increasing with the CMake version.
   */
Brad King's avatar
Brad King committed
274
  KWIML_INT_uint64_t GetBackwardsCompatibility();
275
276
277
278

  /**
   * Test whether compatibility is set to a given version or lower.
   */
279
  bool NeedBackwardsCompatibility_2_4();
280

281
282
  cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID id) const;

283
284
  cmake* GetCMakeInstance() const;

285
286
287
  const char* GetSourceDirectory() const;
  const char* GetBinaryDirectory() const;

288
  const char* GetCurrentBinaryDirectory() const;
289
  const char* GetCurrentSourceDirectory() const;
290

291
292
293
  /**
   * Generate a Mac OS X application bundle Info.plist file.
   */
294
295
  void GenerateAppleInfoPList(cmGeneratorTarget* target,
                              const std::string& targetName,
296
                              const char* fname);
297
298
299
300

  /**
   * Generate a Mac OS X framework Info.plist file.
   */
301
  void GenerateFrameworkInfoPList(cmGeneratorTarget* target,
302
                                  const std::string& targetName,
303
                                  const char* fname);
304
  /** Construct a comment for a custom command.  */
305
  std::string ConstructComment(cmCustomCommandGenerator const& ccg,
306
                               const char* default_comment = "");
307
  // Compute object file names.
Daniel Pfeifer's avatar
Daniel Pfeifer committed
308
309
310
  std::string GetObjectFileNameWithoutTarget(
    const cmSourceFile& source, std::string const& dir_max,
    bool* hasSourceExtension = CM_NULLPTR);
311

312
  /** Fill out the static linker flags for the given target.  */
313
  void GetStaticLibraryFlags(std::string& flags, std::string const& config,
314
                             cmGeneratorTarget* target);
315

Bill Hoffman's avatar
Bill Hoffman committed
316
317
  /** Fill out these strings for the given target.  Libraries to link,
   *  flags, and linkflags. */
318
319
  void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
                      const std::string& config, std::string& linkLibs,
320
321
                      std::string& flags, std::string& linkFlags,
                      std::string& frameworkPath, std::string& linkPath,
322
                      cmGeneratorTarget* target);
323
324
325
  void GetTargetDefines(cmGeneratorTarget const* target,
                        std::string const& config, std::string const& lang,
                        std::set<std::string>& defines) const;
326
327
328
  void GetTargetCompileFlags(cmGeneratorTarget* target,
                             std::string const& config,
                             std::string const& lang, std::string& flags);
329

330
331
332
  std::string GetFrameworkFlags(std::string const& l,
                                std::string const& config,
                                cmGeneratorTarget* target);
333
334
  virtual std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
                                            std::string const& config);
335

336
  virtual void ComputeObjectFilenames(
337
    std::map<cmSourceFile const*, std::string>& mapping,
Daniel Pfeifer's avatar
Daniel Pfeifer committed
338
    cmGeneratorTarget const* gt = CM_NULLPTR);
339

340
341
342
343
344
  bool IsWindowsShell() const;
  bool IsWatcomWMake() const;
  bool IsMinGWMake() const;
  bool IsNMake() const;

345
346
  void IssueMessage(cmake::MessageType t, std::string const& text) const;

347
348
  void CreateEvaluationFileOutputs(const std::string& config);
  void ProcessEvaluationFiles(std::vector<std::string>& generatedFiles);
349

350
  // Expand rule variables in CMake of the type found in language rules
351
352
  void ExpandRuleVariables(cmOutputConverter* outputConverter,
                           std::string& string,
353
354
355
356
357
                           const RuleVariables& replaceValues);

  const char* GetRuleLauncher(cmGeneratorTarget* target,
                              const std::string& prop);

358
protected:
Bill Hoffman's avatar
Bill Hoffman committed
359
  ///! put all the libraries for a target on into the given stream
360
361
  void OutputLinkLibraries(cmComputeLinkInformation* pcli,
                           cmLinkLineComputer* linkLineComputer,
362
                           std::string& linkLibraries,
363
                           std::string& frameworkPath, std::string& linkPath);
364

Bill Hoffman's avatar
Bill Hoffman committed
365
  // Expand rule variables in a single string
366
367
  std::string ExpandRuleVariable(cmOutputConverter* outputConverter,
                                 std::string const& variable,
368
                                 const RuleVariables& replaceValues);
369

370
371
  // Handle old-style install rules stored in the targets.
  void GenerateTargetInstallRules(
372
    std::ostream& os, const std::string& config,
373
    std::vector<std::string> const& configurationTypes);
374

375
  std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
376
                                              std::string const& dir_max);
377

378
379
380
381
  /** Check whether the native build system supports the given
      definition.  Issues a warning.  */
  virtual bool CheckDefinition(std::string const& define) const;

382
  cmMakefile* Makefile;
383
  cmState::Snapshot StateSnapshot;
384
  cmListFileBacktrace DirectoryBacktrace;
385
  cmGlobalGenerator* GlobalGenerator;
386
  std::map<std::string, std::string> UniqueObjectNamesMap;
387
  std::string::size_type ObjectPathMax;
388
  std::set<std::string> ObjectMaxPathViolations;
389

390
  std::set<cmGeneratorTarget const*> WarnCMP0063;
391
  std::vector<cmGeneratorTarget*> GeneratorTargets;
392
  std::vector<cmGeneratorTarget*> ImportedGeneratorTargets;
393
  std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets;
394
  std::map<std::string, std::string> AliasTargets;
395

396
397
398
399
  std::map<std::string, std::string> Compilers;
  std::map<std::string, std::string> VariableMappings;
  std::string CompilerSysroot;

400
  bool EmitUniversalBinaryFlags;
401

402
403
  // Hack for ExpandRuleVariable until object-oriented version is
  // committed.
Ken Martin's avatar
Ken Martin committed
404
  std::string TargetImplib;
405

Brad King's avatar
Brad King committed
406
  KWIML_INT_uint64_t BackwardsCompatibility;
407
  bool BackwardsCompatibilityFinal;
408

409
private:
410
411
  void AddSharedFlags(std::string& flags, const std::string& lang,
                      bool shared);
412
  bool GetShouldUseOldFlags(bool shared, const std::string& lang) const;
413
414
  void AddPositionIndependentFlags(std::string& flags, std::string const& l,
                                   int targetType);
415
416

  void ComputeObjectMaxPath();
Ken Martin's avatar
Ken Martin committed
417
418
};

419
#if defined(CMAKE_BUILD_WITH_CMAKE)
420
bool cmLocalGeneratorCheckObjectName(std::string& objName,
421
422
423
424
                                     std::string::size_type dir_len,
                                     std::string::size_type max_total_len);
#endif

Ken Martin's avatar
Ken Martin committed
425
#endif