cmLocalGenerator.h 14.7 KB
Newer Older
1 2 3
/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
Ken Martin's avatar
Ken Martin committed
4

5 6
  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.
Ken Martin's avatar
Ken Martin committed
7

8 9 10 11
  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
Ken Martin's avatar
Ken Martin committed
12 13 14 15
#ifndef cmLocalGenerator_h
#define cmLocalGenerator_h

#include "cmStandardIncludes.h"
16
#include "cmState.h"
17
#include "cmake.h"
18
#include "cmOutputConverter.h"
Ken Martin's avatar
Ken Martin committed
19 20 21

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

/** \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
33
 * platforms. This class should never be constructed directly. A
Ken Martin's avatar
Ken Martin committed
34 35
 * GlobalGenerator will create it and invoke the appropriate commands on it.
 */
36
class cmLocalGenerator : public cmOutputConverter
Ken Martin's avatar
Ken Martin committed
37 38
{
public:
39 40
  cmLocalGenerator(cmGlobalGenerator* gg, cmLocalGenerator* parent,
                   cmState::Snapshot snapshot);
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 GenerateTargetManifest();
71

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

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

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

86 87 88
  cmState* GetState() const;
  cmState::Snapshot GetStateSnapshot() const;

89
  ///! set/get the parent generator
90
  cmLocalGenerator* GetParent() const {return this->Parent;}
91 92 93

  ///! set/get the children
  void AddChild(cmLocalGenerator* g) { this->Children.push_back(g); }
94
  std::vector<cmLocalGenerator*>& GetChildren() { return this->Children; }
95

96

97 98
  void AddArchitectureFlags(std::string& flags,
                            cmGeneratorTarget const* target,
99
                            const std::string&lang, const std::string& config);
100

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

124 125 126 127
  /**
   * Encode a list of preprocessor definitions for the compiler
   * command line.
   */
128 129
  void AppendDefines(std::set<std::string>& defines,
                     const char* defines_list);
130 131 132 133 134
  void AppendDefines(std::set<std::string>& defines,
                     std::string defines_list)
  {
    this->AppendDefines(defines, defines_list.c_str());
  }
135 136 137
  void AppendDefines(std::set<std::string>& defines,
                     const std::vector<std::string> &defines_vec);

138 139 140 141 142
  /**
   * Join a set of defines into a definesString with a space separator.
   */
  void JoinDefines(const std::set<std::string>& defines,
                   std::string &definesString,
143
                   const std::string& lang);
144

145
  /** Lookup and append options associated with a particular feature.  */
146
  void AppendFeatureOptions(std::string& flags, const std::string& lang,
147 148
                            const char* feature);

149 150 151
  const char* GetFeature(const std::string& feature,
                         const std::string& config);

152 153 154 155 156 157 158 159 160 161 162 163
  /** \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.
   */
164
  bool GetRealDependency(const std::string& name, const std::string& config,
165 166
                         std::string& dep);

167
  virtual std::string ConvertToIncludeReference(std::string const& path,
168 169
                                                OutputFormat format = SHELL,
                                                bool forceFullPaths = false);
170

171
  /** Called from command-line hook to clear dependencies.  */
172
  virtual void ClearDependencies(cmMakefile* /* mf */,
173
                                 bool /* verbose */) {}
174

175 176
  /** Called from command-line hook to update dependencies.  */
  virtual bool UpdateDependencies(const char* /* tgtInfo */,
177 178
                                  bool /*verbose*/,
                                  bool /*color*/)
179
    { return true; }
Ken Martin's avatar
Ken Martin committed
180

181
  /** Get the include flags for the current makefile and language.  */
182
  void GetIncludeDirectories(std::vector<std::string>& dirs,
183
                             cmGeneratorTarget* target,
184
                             const std::string& lang = "C",
185
                             const std::string& config = "",
186
                             bool stripImplicitInclDirs = true) const;
187
  void AddCompileOptions(std::string& flags, cmTarget* target,
188
                         const std::string& lang, const std::string& config);
189 190
  void AddCompileDefinitions(std::set<std::string>& defines,
                             cmTarget const* target,
191 192
                             const std::string& config,
                             const std::string& lang);
193

194
  /** Compute the language used to compile the given source file.  */
195
  std::string GetSourceFileLanguage(const cmSourceFile& source);
196

197 198
  // Fill the vector with the target names for the object files,
  // preprocessed files and assembly files.
199
  virtual void GetIndividualFileTargets(std::vector<std::string>&) {}
200

201 202 203 204 205 206
  // Create a struct to hold the varibles passed into
  // ExpandRuleVariables
  struct RuleVariables
  {
    RuleVariables()
      {
207
        memset(this, 0,  sizeof(*this));
208
      }
209
    cmTarget* CMTarget;
210
    const char* TargetPDB;
211
    const char* TargetCompilePDB;
212 213
    const char* TargetVersionMajor;
    const char* TargetVersionMinor;
214 215 216 217 218
    const char* Language;
    const char* Objects;
    const char* Target;
    const char* LinkLibraries;
    const char* Source;
219 220
    const char* AssemblySource;
    const char* PreprocessedSource;
221
    const char* Output;
222
    const char* Object;
223
    const char* ObjectDir;
224
    const char* ObjectFileDir;
225 226
    const char* Flags;
    const char* ObjectsQuoted;
227
    const char* SONameFlag;
228
    const char* TargetSOName;
229
    const char* TargetInstallNameDir;
230
    const char* LinkFlags;
231
    const char* LanguageCompileFlags;
232
    const char* Defines;
233
    const char* Includes;
234
    const char* RuleLauncher;
235
    const char* DependencyFile;
236
    const char* FilterPrefix;
237
  };
Bill Hoffman's avatar
Bill Hoffman committed
238

239 240 241 242 243 244
  /**
   * Get the relative path from the generator output directory to a
   * per-target support directory.
   */
  virtual std::string GetTargetDirectory(cmTarget const& target) const;

245 246 247 248 249 250 251 252 253 254
  /**
   * 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.
   */
255
  cmIML_INT_uint64_t GetBackwardsCompatibility();
256 257 258 259

  /**
   * Test whether compatibility is set to a given version or lower.
   */
260
  bool NeedBackwardsCompatibility_2_4();
261 262 263 264

  /**
   * Generate a Mac OS X application bundle Info.plist file.
   */
265
  void GenerateAppleInfoPList(cmTarget* target, const std::string& targetName,
266
                              const char* fname);
267 268 269 270 271

  /**
   * Generate a Mac OS X framework Info.plist file.
   */
  void GenerateFrameworkInfoPList(cmTarget* target,
272
                                  const std::string& targetName,
273
                                  const char* fname);
274
  /** Construct a comment for a custom command.  */
275
  std::string ConstructComment(cmCustomCommandGenerator const& ccg,
276
                               const char* default_comment = "");
277 278 279 280
  // Compute object file names.
  std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
                                             std::string const& dir_max,
                                             bool* hasSourceExtension = 0);
281

282 283 284 285 286
  /** Fill out the static linker flags for the given target.  */
  void GetStaticLibraryFlags(std::string& flags,
                             std::string const& config,
                             cmTarget* target);

Bill Hoffman's avatar
Bill Hoffman committed
287 288
  /** Fill out these strings for the given target.  Libraries to link,
   *  flags, and linkflags. */
289
  void GetTargetFlags(std::string& linkLibs,
Bill Hoffman's avatar
Bill Hoffman committed
290 291
                      std::string& flags,
                      std::string& linkFlags,
292 293
                      std::string& frameworkPath,
                      std::string& linkPath,
294 295
                      cmGeneratorTarget* target,
                      bool useWatcomQuote);
296

297 298 299 300
  virtual void ComputeObjectFilenames(
                        std::map<cmSourceFile const*, std::string>& mapping,
                        cmGeneratorTarget const* gt = 0);

301 302 303 304 305
  bool IsWindowsShell() const;
  bool IsWatcomWMake() const;
  bool IsMinGWMake() const;
  bool IsNMake() const;

306 307 308
  void IssueMessage(cmake::MessageType t, std::string const& text) const;


309
  void ComputeObjectMaxPath();
310
protected:
Bill Hoffman's avatar
Bill Hoffman committed
311
  ///! put all the libraries for a target on into the given stream
312
  void OutputLinkLibraries(std::string& linkLibraries,
313 314 315
                                   std::string& frameworkPath,
                                   std::string& linkPath,
                                   cmGeneratorTarget &,
316
                                   bool relink,
317 318
                                   bool forResponseFile,
                                   bool useWatcomQuote);
319

320 321
  // Expand rule variables in CMake of the type found in language rules
  void ExpandRuleVariables(std::string& string,
322
                           const RuleVariables& replaceValues);
Bill Hoffman's avatar
Bill Hoffman committed
323 324
  // Expand rule variables in a single string
  std::string ExpandRuleVariable(std::string const& variable,
325
                                 const RuleVariables& replaceValues);
326

327
  const char* GetRuleLauncher(cmTarget* target, const std::string& prop);
328
  void InsertRuleLauncher(std::string& s, cmTarget* target,
329
                          const std::string& prop);
330

331 332

  /** Convert a target to a utility target for unsupported
Bill Hoffman's avatar
Bill Hoffman committed
333
   *  languages of a generator */
334 335
  void AddBuildTargetRule(const std::string& llang,
                          cmGeneratorTarget& target);
336 337
  ///! add a custom command to build a .o file that is part of a target
  void AddCustomCommandToCreateObject(const char* ofname,
338
                                      const std::string& lang,
339
                                      cmSourceFile& source,
340
                                      cmGeneratorTarget& target);
341 342 343 344 345
  // Create Custom Targets and commands for unsupported languages
  // The set passed in should contain the languages supported by the
  // generator directly.  Any targets containing files that are not
  // of the types listed will be compiled as custom commands and added
  // to a custom target.
346
  void CreateCustomTargetsAndCommands(std::set<std::string> const&);
347 348 349

  // Handle old-style install rules stored in the targets.
  void GenerateTargetInstallRules(
350
    std::ostream& os, const std::string& config,
351
    std::vector<std::string> const& configurationTypes);
352

353
  std::string& CreateSafeUniqueObjectFileName(const std::string& sin,
354
                                              std::string const& dir_max);
355

356 357
  virtual std::string ConvertToLinkReference(std::string const& lib,
                                             OutputFormat format = SHELL);
358

359 360 361 362
  /** Check whether the native build system supports the given
      definition.  Issues a warning.  */
  virtual bool CheckDefinition(std::string const& define) const;

Ken Martin's avatar
Ken Martin committed
363
  cmMakefile *Makefile;
364
  cmState::Snapshot StateSnapshot;
Ken Martin's avatar
Ken Martin committed
365 366
  cmGlobalGenerator *GlobalGenerator;
  cmLocalGenerator* Parent;
367
  std::vector<cmLocalGenerator*> Children;
368
  std::map<std::string, std::string> UniqueObjectNamesMap;
369
  std::string::size_type ObjectPathMax;
370
  std::set<std::string> ObjectMaxPathViolations;
371

372 373
  std::set<cmTarget const*> WarnCMP0063;

374
  bool EmitUniversalBinaryFlags;
375

376 377
  // Hack for ExpandRuleVariable until object-oriented version is
  // committed.
Ken Martin's avatar
Ken Martin committed
378
  std::string TargetImplib;
379

380
  cmIML_INT_uint64_t BackwardsCompatibility;
381
  bool BackwardsCompatibilityFinal;
382
private:
383 384
  void AddSharedFlags(std::string& flags, const std::string& lang,
                      bool shared);
385 386 387
  bool GetShouldUseOldFlags(bool shared, const std::string &lang) const;
  void AddPositionIndependentFlags(std::string& flags, std::string const& l,
                                   int targetType);
Ken Martin's avatar
Ken Martin committed
388 389 390
};

#endif