summaryrefslogtreecommitdiff
path: root/gn/src/gn/target.h
blob: 0004d096075c02c96a8ba4c439549532c772c7c2 (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
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
// 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 "gn/action_values.h"
#include "gn/bundle_data.h"
#include "gn/config_values.h"
#include "gn/inherited_libraries.h"
#include "gn/item.h"
#include "gn/label_pattern.h"
#include "gn/label_ptr.h"
#include "gn/lib_file.h"
#include "gn/metadata.h"
#include "gn/ordered_set.h"
#include "gn/output_file.h"
#include "gn/rust_values.h"
#include "gn/source_file.h"
#include "gn/swift_values.h"
#include "gn/toolchain.h"
#include "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,
    GENERATED_FILE,
    RUST_LIBRARY,
    RUST_PROC_MACRO,
  };

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

  using FileList = std::vector<SourceFile>;
  using StringVector = std::vector<std::string>;

  // We track the set of build files that may affect this target, please refer
  // to Scope for how this is determined.
  Target(const Settings* settings,
         const Label& label,
         const SourceFileSet& build_dependency_files = {});
  ~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;

  // Set when the target should normally be treated as a data dependency. These
  // do not need to be treated as inputs or hard dependencies for normal build
  // steps, but have to be kept in the dependency tree to be properly
  // propagated. Treating these as data only decreases superfluous rebuilds and
  // increases parallelism.
  bool IsDataOnly() 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_; }

  const SourceFileTypeSet& source_types_used() const {
    return source_types_used_;
  }
  SourceFileTypeSet& source_types_used() { return source_types_used_; }

  // 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;
  }

  // Metadata. Target takes ownership of the resulting scope.
  const Metadata& metadata() const { return metadata_; }
  Metadata& metadata() { return metadata_; }

  // Get metadata from this target and its dependencies. This is intended to
  // be called after the target is resolved.
  bool GetMetadata(const std::vector<std::string>& keys_to_extract,
                   const std::vector<std::string>& keys_to_walk,
                   const SourceDir& rebase_dir,
                   bool deps_only,
                   std::vector<Value>* result,
                   std::set<const Target*>* targets_walked,
                   Err* err) const;

  // GeneratedFile-related methods.
  bool GenerateFile(Err* err) const;

  const Value& contents() const { return contents_; }
  void set_contents(const Value& value) { contents_ = value; }
  const Value& output_conversion() const { return output_conversion_; }
  void set_output_conversion(const Value& value) { output_conversion_ = value; }

  // Metadata collection methods for GeneratedFile targets.
  const SourceDir& rebase() const { return rebase_; }
  void set_rebase(const SourceDir& value) { rebase_ = value; }
  const std::vector<std::string>& data_keys() const { return data_keys_; }
  std::vector<std::string>& data_keys() { return data_keys_; }
  const std::vector<std::string>& walk_keys() const { return walk_keys_; }
  std::vector<std::string>& walk_keys() { return walk_keys_; }

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

  std::vector<std::string>& rsp_types() { return rsp_types_; }
  const std::vector<std::string>& rsp_types() const { return rsp_types_; }

  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;
  }

  // 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 ||
           output_type_ == BUNDLE_DATA || output_type_ == GENERATED_FILE ||
           (IsBinary() && swift_values().builds_module());
  }

  // 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_; }

  SwiftValues& swift_values() { return swift_values_; }
  const SwiftValues& swift_values() const { return swift_values_; }

  RustValues& rust_values() { return rust_values_; }
  const RustValues& rust_values() const { return rust_values_; }

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

  const OrderedSet<SourceDir>& all_framework_dirs() const {
    return all_framework_dirs_;
  }
  const OrderedSet<std::string>& all_frameworks() const {
    return all_frameworks_;
  }
  const OrderedSet<std::string>& all_weak_frameworks() const {
    return all_weak_frameworks_;
  }

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

  std::vector<LabelPattern>& friends() { return friends_; }
  const std::vector<LabelPattern>& friends() const { return friends_; }

  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 and returns the outputs of this target expressed as SourceFiles.
  //
  // For binary target this depends on the tool for this target so the toolchain
  // must have been loaded beforehand. This will happen asynchronously so
  // calling this on a binary target before the build is complete will produce a
  // race condition.
  //
  // To resolve this, the caller passes in whether the entire build is complete
  // (this is used for the introspection commands which run after everything
  // else).
  //
  // If the build is complete, the toolchain will be used for binary targets to
  // compute the outputs. If the build is not complete, calling this function
  // for binary targets will produce an error.
  //
  // The |loc_for_error| is used to blame a location for any errors produced. It
  // can be empty if there is no range (like this is being called based on the
  // command-line.
  bool GetOutputsAsSourceFiles(const LocationRange& loc_for_error,
                               bool build_complete,
                               std::vector<SourceFile>* outputs,
                               Err* err) const;

  // Computes the set of output files resulting from compiling the given source
  // file.
  //
  // For binary targets, 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.
  //
  // For action_foreach and copy targets, applies the output pattern to the
  // given file name to compute the outputs.
  //
  // For all other target types, just returns the target outputs because such
  // targets conceptually process all of their inputs as one step.
  //
  // 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,
                               const char** computed_tool_type,
                               std::vector<OutputFile>* outputs) const;

 private:
  FRIEND_TEST_ALL_PREFIXES(TargetTest, 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.
  bool FillOutputFiles(Err* err);

  // 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 CheckConfigVisibility(Err* err) const;
  bool CheckTestonly(Err* err) const;
  bool CheckAssertNoDeps(Err* err) const;
  void CheckSourcesGenerated() const;
  void CheckSourceGenerated(const SourceFile& source) const;
  bool CheckSourceSetLanguages(Err* err) const;

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

  FileList sources_;
  SourceFileTypeSet source_types_used_;
  bool all_headers_public_ = true;
  FileList public_headers_;
  bool check_includes_ = true;
  bool complete_static_lib_ = false;
  bool testonly_ = false;
  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_;

  // These frameworks and dirs are inherited from statically linked deps and
  // all configs applying to this target.
  OrderedSet<SourceDir> all_framework_dirs_;
  OrderedSet<std::string> all_frameworks_;
  OrderedSet<std::string> all_weak_frameworks_;

  // 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> friends_;
  std::vector<LabelPattern> assert_no_deps_;

  // Used for all binary targets, and for inputs in regular 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_;

  // Used for Rust targets.
  RustValues rust_values_;

  // User for Swift targets.
  SwiftValues swift_values_;

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

  // 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_;

  Metadata metadata_;

  // GeneratedFile values.
  Value output_conversion_;
  Value contents_;  // Value::NONE if metadata collection should occur.

  // GeneratedFile as metadata collection values.
  SourceDir rebase_;
  std::vector<std::string> data_keys_;
  std::vector<std::string> walk_keys_;
  std::vector<std::string> rsp_types_;

  DISALLOW_COPY_AND_ASSIGN(Target);
};

extern const char kExecution_Help[];

#endif  // TOOLS_GN_TARGET_H_