summaryrefslogtreecommitdiff
path: root/chromium/tools/gn/target.h
blob: 1890a535e7a7f4c8671ee7be9138e488ce92e1f1 (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
// 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_TARGET_H_
#define TOOLS_GN_TARGET_H_

#include <set>
#include <string>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "base/macros.h"
#include "tools/gn/action_values.h"
#include "tools/gn/bundle_data.h"
#include "tools/gn/config_values.h"
#include "tools/gn/inherited_libraries.h"
#include "tools/gn/item.h"
#include "tools/gn/label_pattern.h"
#include "tools/gn/label_ptr.h"
#include "tools/gn/lib_file.h"
#include "tools/gn/ordered_set.h"
#include "tools/gn/output_file.h"
#include "tools/gn/source_file.h"
#include "tools/gn/toolchain.h"
#include "tools/gn/unique_vector.h"

class DepsIteratorRange;
class Settings;
class Toolchain;

class Target : public Item {
 public:
  enum OutputType {
    UNKNOWN,
    GROUP,
    EXECUTABLE,
    SHARED_LIBRARY,
    LOADABLE_MODULE,
    STATIC_LIBRARY,
    SOURCE_SET,
    COPY_FILES,
    ACTION,
    ACTION_FOREACH,
    BUNDLE_DATA,
    CREATE_BUNDLE,
  };

  enum DepsIterationType {
    DEPS_ALL,  // Iterates through all public, private, and data deps.
    DEPS_LINKED,  // Iterates through all non-data dependencies.
  };

  typedef std::vector<SourceFile> FileList;
  typedef std::vector<std::string> StringVector;

  Target(const Settings* settings, const Label& label);
  ~Target() override;

  // Returns a string naming the output type.
  static const char* GetStringForOutputType(OutputType type);

  // Item overrides.
  Target* AsTarget() override;
  const Target* AsTarget() const override;
  bool OnResolved(Err* err) override;

  OutputType output_type() const { return output_type_; }
  void set_output_type(OutputType t) { output_type_ = t; }

  // True for targets that compile source code (all types of libaries and
  // executables).
  bool IsBinary() const;

  // Can be linked into other targets.
  bool IsLinkable() const;

  // True if the target links dependencies rather than propogated up the graph.
  // This is also true of action and copy steps even though they don't link
  // dependencies, because they also don't propogate libraries up.
  bool IsFinal() const;

  // Will be the empty string to use the target label as the output name.
  // See GetComputedOutputName().
  const std::string& output_name() const { return output_name_; }
  void set_output_name(const std::string& name) { output_name_ = name; }

  // Returns the output name for this target, which is the output_name if
  // specified, or the target label if not.
  //
  // Because this depends on the tool for this target, the toolchain must
  // have been set before calling.
  std::string GetComputedOutputName() const;

  bool output_prefix_override() const { return output_prefix_override_; }
  void set_output_prefix_override(bool prefix_override) {
    output_prefix_override_ = prefix_override;
  }

  // Desired output directory for the final output. This will be used for
  // the {{output_dir}} substitution in the tool if it is specified. If
  // is_null, the tool default will be used.
  const SourceDir& output_dir() const { return output_dir_; }
  void set_output_dir(const SourceDir& dir) { output_dir_ = dir; }

  // The output extension is really a tri-state: unset (output_extension_set
  // is false and the string is empty, meaning the default extension should be
  // used), the output extension is set but empty (output should have no
  // extension) and the output extension is set but nonempty (use the given
  // extension).
  const std::string& output_extension() const { return output_extension_; }
  void set_output_extension(const std::string& extension) {
    output_extension_ = extension;
    output_extension_set_ = true;
  }
  bool output_extension_set() const {
    return output_extension_set_;
  }

  const FileList& sources() const { return sources_; }
  FileList& sources() { return sources_; }

  // Set to true when all sources are public. This is the default. In this case
  // the public headers list should be empty.
  bool all_headers_public() const { return all_headers_public_; }
  void set_all_headers_public(bool p) { all_headers_public_ = p; }

  // When all_headers_public is false, this is the list of public headers. It
  // could be empty which would mean no headers are public.
  const FileList& public_headers() const { return public_headers_; }
  FileList& public_headers() { return public_headers_; }

  // Whether this target's includes should be checked by "gn check".
  bool check_includes() const { return check_includes_; }
  void set_check_includes(bool ci) { check_includes_ = ci; }

  // Whether this static_library target should have code linked in.
  bool complete_static_lib() const { return complete_static_lib_; }
  void set_complete_static_lib(bool complete) {
    DCHECK_EQ(STATIC_LIBRARY, output_type_);
    complete_static_lib_ = complete;
  }

  bool testonly() const { return testonly_; }
  void set_testonly(bool value) { testonly_ = value; }

  OutputFile write_runtime_deps_output() const {
    return write_runtime_deps_output_;
  }
  void set_write_runtime_deps_output(const OutputFile& value) {
    write_runtime_deps_output_ = value;
  }

  // Compile-time extra dependencies.
  const FileList& inputs() const { return inputs_; }
  FileList& inputs() { return inputs_; }

  // Runtime dependencies. These are "file-like things" that can either be
  // directories or files. They do not need to exist, these are just passed as
  // runtime dependencies to external test systems as necessary.
  const std::vector<std::string>& data() const { return data_; }
  std::vector<std::string>& data() { return data_; }

  // Information about the bundle. Only valid for CREATE_BUNDLE target after
  // they have been resolved.
  const BundleData& bundle_data() const { return bundle_data_; }
  BundleData& bundle_data() { return bundle_data_; }

  // Returns true if targets depending on this one should have an order
  // dependency.
  bool hard_dep() const {
    return output_type_ == ACTION ||
           output_type_ == ACTION_FOREACH ||
           output_type_ == COPY_FILES ||
           output_type_ == CREATE_BUNDLE;
  }

  // Returns the iterator range which can be used in range-based for loops
  // to iterate over multiple types of deps in one loop:
  //   for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) ...
  DepsIteratorRange GetDeps(DepsIterationType type) const;

  // Linked private dependencies.
  const LabelTargetVector& private_deps() const { return private_deps_; }
  LabelTargetVector& private_deps() { return private_deps_; }

  // Linked public dependencies.
  const LabelTargetVector& public_deps() const { return public_deps_; }
  LabelTargetVector& public_deps() { return public_deps_; }

  // Non-linked dependencies.
  const LabelTargetVector& data_deps() const { return data_deps_; }
  LabelTargetVector& data_deps() { return data_deps_; }

  // List of configs that this class inherits settings from. Once a target is
  // resolved, this will also list all-dependent and public configs.
  const UniqueVector<LabelConfigPair>& configs() const { return configs_; }
  UniqueVector<LabelConfigPair>& configs() { return configs_; }

  // List of configs that all dependencies (direct and indirect) of this
  // target get. These configs are not added to this target. Note that due
  // to the way this is computed, there may be duplicates in this list.
  const UniqueVector<LabelConfigPair>& all_dependent_configs() const {
    return all_dependent_configs_;
  }
  UniqueVector<LabelConfigPair>& all_dependent_configs() {
    return all_dependent_configs_;
  }

  // List of configs that targets depending directly on this one get. These
  // configs are also added to this target.
  const UniqueVector<LabelConfigPair>& public_configs() const {
    return public_configs_;
  }
  UniqueVector<LabelConfigPair>& public_configs() {
    return public_configs_;
  }

  // Dependencies that can include files from this target.
  const std::set<Label>& allow_circular_includes_from() const {
    return allow_circular_includes_from_;
  }
  std::set<Label>& allow_circular_includes_from() {
    return allow_circular_includes_from_;
  }

  const InheritedLibraries& inherited_libraries() const {
    return inherited_libraries_;
  }

  // This config represents the configuration set directly on this target.
  ConfigValues& config_values() { return config_values_; }
  const ConfigValues& config_values() const { return config_values_; }

  ActionValues& action_values() { return action_values_; }
  const ActionValues& action_values() const { return action_values_; }

  const OrderedSet<SourceDir>& all_lib_dirs() const { return all_lib_dirs_; }
  const OrderedSet<LibFile>& all_libs() const { return all_libs_; }

  const std::set<const Target*>& recursive_hard_deps() const {
    return recursive_hard_deps_;
  }

  std::vector<LabelPattern>& assert_no_deps() {
    return assert_no_deps_;
  }
  const std::vector<LabelPattern>& assert_no_deps() const {
    return assert_no_deps_;
  }

  // The toolchain is only known once this target is resolved (all if its
  // dependencies are known). They will be null until then. Generally, this can
  // only be used during target writing.
  const Toolchain* toolchain() const { return toolchain_; }

  // Sets the toolchain. The toolchain must include a tool for this target
  // or the error will be set and the function will return false. Unusually,
  // this function's "err" output is optional since this is commonly used
  // frequently by unit tests which become needlessly verbose.
  bool SetToolchain(const Toolchain* toolchain, Err* err = nullptr);

  // Once this target has been resolved, all outputs from the target will be
  // listed here. This will include things listed in the "outputs" for an
  // action or a copy step, and the output library or executable file(s) from
  // binary targets.
  //
  // It will NOT include stamp files and object files.
  const std::vector<OutputFile>& computed_outputs() const {
    return computed_outputs_;
  }

  // Returns outputs from this target. The link output file is the one that
  // other targets link to when they depend on this target. This will only be
  // valid for libraries and will be empty for all other target types.
  //
  // The dependency output file is the file that should be used to express
  // a dependency on this one. It could be the same as the link output file
  // (this will be the case for static libraries). For shared libraries it
  // could be the same or different than the link output file, depending on the
  // system. For actions this will be the stamp file.
  //
  // These are only known once the target is resolved and will be empty before
  // that. This is a cache of the files to prevent every target that depends on
  // a given library from recomputing the same pattern.
  const OutputFile& link_output_file() const {
    return link_output_file_;
  }
  const OutputFile& dependency_output_file() const {
    return dependency_output_file_;
  }

  // The subset of computed_outputs that are considered runtime outputs.
  const std::vector<OutputFile>& runtime_outputs() const {
    return runtime_outputs_;
  }

  // Computes the set of output files resulting from compiling the given source
  // file. If the file can be compiled and the tool exists, fills the outputs
  // in and writes the tool type to computed_tool_type. If the file is not
  // compilable, returns false.
  //
  // The function can succeed with a "NONE" tool type for object files which
  // are just passed to the output. The output will always be overwritten, not
  // appended to.
  bool GetOutputFilesForSource(const SourceFile& source,
                               Toolchain::ToolType* computed_tool_type,
                               std::vector<OutputFile>* outputs) const;

 private:
  FRIEND_TEST_ALL_PREFIXES(Target, ResolvePrecompiledHeaders);

  // Pulls necessary information from dependencies to this one when all
  // dependencies have been resolved.
  void PullDependentTargetConfigs();
  void PullDependentTargetLibsFrom(const Target* dep, bool is_public);
  void PullDependentTargetLibs();
  void PullRecursiveHardDeps();
  void PullRecursiveBundleData();

  // Fills the link and dependency output files when a target is resolved.
  void FillOutputFiles();

  // Checks precompiled headers from configs and makes sure the resulting
  // values are in config_values_.
  bool ResolvePrecompiledHeaders(Err* err);

  // Validates the given thing when a target is resolved.
  bool CheckVisibility(Err* err) const;
  bool CheckTestonly(Err* err) const;
  bool CheckAssertNoDeps(Err* err) const;
  void CheckSourcesGenerated() const;
  void CheckSourceGenerated(const SourceFile& source) const;

  OutputType output_type_;
  std::string output_name_;
  bool output_prefix_override_;
  SourceDir output_dir_;
  std::string output_extension_;
  bool output_extension_set_;

  FileList sources_;
  bool all_headers_public_;
  FileList public_headers_;
  bool check_includes_;
  bool complete_static_lib_;
  bool testonly_;
  FileList inputs_;
  std::vector<std::string> data_;
  BundleData bundle_data_;
  OutputFile write_runtime_deps_output_;

  LabelTargetVector private_deps_;
  LabelTargetVector public_deps_;
  LabelTargetVector data_deps_;

  // See getters for more info.
  UniqueVector<LabelConfigPair> configs_;
  UniqueVector<LabelConfigPair> all_dependent_configs_;
  UniqueVector<LabelConfigPair> public_configs_;

  std::set<Label> allow_circular_includes_from_;

  // Static libraries, shared libraries, and source sets from transitive deps
  // that need to be linked.
  InheritedLibraries inherited_libraries_;

  // These libs and dirs are inherited from statically linked deps and all
  // configs applying to this target.
  OrderedSet<SourceDir> all_lib_dirs_;
  OrderedSet<LibFile> all_libs_;

  // All hard deps from this target and all dependencies. Filled in when this
  // target is marked resolved. This will not include the current target.
  std::set<const Target*> recursive_hard_deps_;

  std::vector<LabelPattern> assert_no_deps_;

  // Used for all binary targets. The precompiled header values in this struct
  // will be resolved to the ones to use for this target, if precompiled
  // headers are used.
  ConfigValues config_values_;

  // Used for action[_foreach] targets.
  ActionValues action_values_;

  // Toolchain used by this target. Null until target is resolved.
  const Toolchain* toolchain_;

  // Output files. Empty until the target is resolved.
  std::vector<OutputFile> computed_outputs_;
  OutputFile link_output_file_;
  OutputFile dependency_output_file_;
  std::vector<OutputFile> runtime_outputs_;

  DISALLOW_COPY_AND_ASSIGN(Target);
};

extern const char kExecution_Help[];

#endif  // TOOLS_GN_TARGET_H_