summaryrefslogtreecommitdiff
path: root/gn/tools/gn/ninja_binary_target_writer.h
blob: 5cb7ab5d889c7a31e121e48e86998681b917dc14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_
#define TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_

#include "base/macros.h"
#include "tools/gn/config_values.h"
#include "tools/gn/ninja_target_writer.h"
#include "tools/gn/toolchain.h"
#include "tools/gn/unique_vector.h"

struct EscapeOptions;
class SourceFileTypeSet;

// Writes a .ninja file for a binary target type (an executable, a shared
// library, or a static library).
class NinjaBinaryTargetWriter : public NinjaTargetWriter {
 public:
  class SourceFileTypeSet;

  NinjaBinaryTargetWriter(const Target* target, std::ostream& out);
  ~NinjaBinaryTargetWriter() override;

  void Run() override;

 private:
  typedef std::set<OutputFile> OutputFileSet;

  // Writes all flags for the compiler: includes, defines, cflags, etc.
  void WriteCompilerVars(const SourceFileTypeSet& used_types);

  // Writes to the output stream a stamp rule for inputs, and
  // returns the file to be appended to source rules that encodes the
  // implicit dependencies for the current target. The returned OutputFile
  // will be empty if there are no inputs.
  OutputFile WriteInputsStampAndGetDep() const;

  // Writes build lines required for precompiled headers. Any generated
  // object files will be appended to the |object_files|. Any generated
  // non-object files (for instance, .gch files from a GCC toolchain, are
  // appended to |other_files|).
  //
  // input_dep is the stamp file collecting the dependencies required before
  // compiling this target. It will be empty if there are no input deps.
  void WritePCHCommands(const SourceFileTypeSet& used_types,
                        const OutputFile& input_dep,
                        const std::vector<OutputFile>& order_only_deps,
                        std::vector<OutputFile>* object_files,
                        std::vector<OutputFile>* other_files);

  // Writes a .pch compile build line for a language type.
  void WritePCHCommand(SubstitutionType flag_type,
                       Toolchain::ToolType tool_type,
                       Tool::PrecompiledHeaderType header_type,
                       const OutputFile& input_dep,
                       const std::vector<OutputFile>& order_only_deps,
                       std::vector<OutputFile>* object_files,
                       std::vector<OutputFile>* other_files);

  void WriteGCCPCHCommand(SubstitutionType flag_type,
                          Toolchain::ToolType tool_type,
                          const OutputFile& input_dep,
                          const std::vector<OutputFile>& order_only_deps,
                          std::vector<OutputFile>* gch_files);

  void WriteWindowsPCHCommand(SubstitutionType flag_type,
                              Toolchain::ToolType tool_type,
                              const OutputFile& input_dep,
                              const std::vector<OutputFile>& order_only_deps,
                              std::vector<OutputFile>* object_files);

  // pch_deps are additional dependencies to run before the rule. They are
  // expected to abide by the naming conventions specified by GetPCHOutputFiles.
  //
  // order_only_dep are the dependencies that must be run before doing any
  // compiles.
  //
  // The files produced by the compiler will be added to two output vectors.
  void WriteSources(const std::vector<OutputFile>& pch_deps,
                    const OutputFile& input_dep,
                    const std::vector<OutputFile>& order_only_deps,
                    std::vector<OutputFile>* object_files,
                    std::vector<SourceFile>* other_files);

  // Writes a build line.
  void WriteCompilerBuildLine(const SourceFile& source,
                              const std::vector<OutputFile>& extra_deps,
                              const std::vector<OutputFile>& order_only_deps,
                              Toolchain::ToolType tool_type,
                              const std::vector<OutputFile>& outputs);

  void WriteLinkerStuff(const std::vector<OutputFile>& object_files,
                        const std::vector<SourceFile>& other_files,
                        const OutputFile& input_dep);
  void WriteLinkerFlags(const SourceFile* optional_def_file);
  void WriteLibs();
  void WriteOutputSubstitutions();
  void WriteSolibs(const std::vector<OutputFile>& solibs);

  // Writes the stamp line for a source set. These are not linked.
  void WriteSourceSetStamp(const std::vector<OutputFile>& object_files);

  // Gets all target dependencies and classifies them, as well as accumulates
  // object files from source sets we need to link.
  void GetDeps(UniqueVector<OutputFile>* extra_object_files,
               UniqueVector<const Target*>* linkable_deps,
               UniqueVector<const Target*>* non_linkable_deps) const;

  // Classifies the dependency as linkable or nonlinkable with the current
  // target, adding it to the appropriate vector. If the dependency is a source
  // set we should link in, the source set's object files will be appended to
  // |extra_object_files|.
  void ClassifyDependency(const Target* dep,
                          UniqueVector<OutputFile>* extra_object_files,
                          UniqueVector<const Target*>* linkable_deps,
                          UniqueVector<const Target*>* non_linkable_deps) const;

  // Writes the implicit dependencies for the link or stamp line. This is
  // the "||" and everything following it on the ninja line.
  //
  // The order-only dependencies are the non-linkable deps passed in as an
  // argument, plus the data file depdencies in the target.
  void WriteOrderOnlyDependencies(
      const UniqueVector<const Target*>& non_linkable_deps);


  // Checks for duplicates in the given list of output files. If any duplicates
  // are found, throws an error and return false.
  bool CheckForDuplicateObjectFiles(const std::vector<OutputFile>& files) const;

  const Tool* tool_;

  // Cached version of the prefix used for rule types for this toolchain.
  std::string rule_prefix_;

  DISALLOW_COPY_AND_ASSIGN(NinjaBinaryTargetWriter);
};

#endif  // TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_