1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef TOOLS_GN_TARGET_H_
6#define TOOLS_GN_TARGET_H_
7
8#include <set>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/compiler_specific.h"
14#include "base/logging.h"
15#include "base/strings/string_piece.h"
16#include "base/synchronization/lock.h"
17#include "tools/gn/action_values.h"
18#include "tools/gn/config_values.h"
19#include "tools/gn/item.h"
20#include "tools/gn/label_ptr.h"
21#include "tools/gn/ordered_set.h"
22#include "tools/gn/output_file.h"
23#include "tools/gn/source_file.h"
24#include "tools/gn/unique_vector.h"
25
26class InputFile;
27class Settings;
28class Token;
29class Toolchain;
30
31class Target : public Item {
32 public:
33  enum OutputType {
34    UNKNOWN,
35    GROUP,
36    EXECUTABLE,
37    SHARED_LIBRARY,
38    STATIC_LIBRARY,
39    SOURCE_SET,
40    COPY_FILES,
41    ACTION,
42    ACTION_FOREACH,
43  };
44  typedef std::vector<SourceFile> FileList;
45  typedef std::vector<std::string> StringVector;
46
47  Target(const Settings* settings, const Label& label);
48  virtual ~Target();
49
50  // Returns a string naming the output type.
51  static const char* GetStringForOutputType(OutputType type);
52
53  // Item overrides.
54  virtual Target* AsTarget() OVERRIDE;
55  virtual const Target* AsTarget() const OVERRIDE;
56  virtual bool OnResolved(Err* err) OVERRIDE;
57
58  OutputType output_type() const { return output_type_; }
59  void set_output_type(OutputType t) { output_type_ = t; }
60
61  // Can be linked into other targets.
62  bool IsLinkable() const;
63
64  // Can have dependencies linked in.
65  bool IsFinal() const;
66
67  // Will be the empty string to use the target label as the output name.
68  // See GetComputedOutputName().
69  const std::string& output_name() const { return output_name_; }
70  void set_output_name(const std::string& name) { output_name_ = name; }
71
72  // Returns the output name for this target, which is the output_name if
73  // specified, or the target label if not. If the flag is set, it will also
74  // include any output prefix specified on the tool (often "lib" on Linux).
75  //
76  // Because this depends on the tool for this target, the toolchain must
77  // have been set before calling.
78  std::string GetComputedOutputName(bool include_prefix) const;
79
80  const std::string& output_extension() const { return output_extension_; }
81  void set_output_extension(const std::string& extension) {
82    output_extension_ = extension;
83  }
84
85  const FileList& sources() const { return sources_; }
86  FileList& sources() { return sources_; }
87
88  // Set to true when all sources are public. This is the default. In this case
89  // the public headers list should be empty.
90  bool all_headers_public() const { return all_headers_public_; }
91  void set_all_headers_public(bool p) { all_headers_public_ = p; }
92
93  // When all_headers_public is false, this is the list of public headers. It
94  // could be empty which would mean no headers are public.
95  const FileList& public_headers() const { return public_headers_; }
96  FileList& public_headers() { return public_headers_; }
97
98  // Whether this target's includes should be checked by "gn check".
99  bool check_includes() const { return check_includes_; }
100  void set_check_includes(bool ci) { check_includes_ = ci; }
101
102  // Whether this static_library target should have code linked in.
103  bool complete_static_lib() const { return complete_static_lib_; }
104  void set_complete_static_lib(bool complete) {
105    DCHECK_EQ(STATIC_LIBRARY, output_type_);
106    complete_static_lib_ = complete;
107  }
108
109  bool testonly() const { return testonly_; }
110  void set_testonly(bool value) { testonly_ = value; }
111
112  // Compile-time extra dependencies.
113  const FileList& inputs() const { return inputs_; }
114  FileList& inputs() { return inputs_; }
115
116  // Runtime dependencies.
117  const FileList& data() const { return data_; }
118  FileList& data() { return data_; }
119
120  // Returns true if targets depending on this one should have an order
121  // dependency.
122  bool hard_dep() const {
123    return output_type_ == ACTION ||
124           output_type_ == ACTION_FOREACH ||
125           output_type_ == COPY_FILES;
126  }
127
128  // Linked private dependencies.
129  const LabelTargetVector& private_deps() const { return private_deps_; }
130  LabelTargetVector& private_deps() { return private_deps_; }
131
132  // Linked public dependencies.
133  const LabelTargetVector& public_deps() const { return public_deps_; }
134  LabelTargetVector& public_deps() { return public_deps_; }
135
136  // Non-linked dependencies.
137  const LabelTargetVector& data_deps() const { return data_deps_; }
138  LabelTargetVector& data_deps() { return data_deps_; }
139
140  // List of configs that this class inherits settings from. Once a target is
141  // resolved, this will also list all-dependent and public configs.
142  const UniqueVector<LabelConfigPair>& configs() const { return configs_; }
143  UniqueVector<LabelConfigPair>& configs() { return configs_; }
144
145  // List of configs that all dependencies (direct and indirect) of this
146  // target get. These configs are not added to this target. Note that due
147  // to the way this is computed, there may be duplicates in this list.
148  const UniqueVector<LabelConfigPair>& all_dependent_configs() const {
149    return all_dependent_configs_;
150  }
151  UniqueVector<LabelConfigPair>& all_dependent_configs() {
152    return all_dependent_configs_;
153  }
154
155  // List of configs that targets depending directly on this one get. These
156  // configs are also added to this target.
157  const UniqueVector<LabelConfigPair>& public_configs() const {
158    return public_configs_;
159  }
160  UniqueVector<LabelConfigPair>& public_configs() {
161    return public_configs_;
162  }
163
164  // A list of a subset of deps where we'll re-export public_configs as
165  // public_configs of this target.
166  const UniqueVector<LabelTargetPair>& forward_dependent_configs() const {
167    return forward_dependent_configs_;
168  }
169  UniqueVector<LabelTargetPair>& forward_dependent_configs() {
170    return forward_dependent_configs_;
171  }
172
173  // Dependencies that can include files from this target.
174  const std::set<Label>& allow_circular_includes_from() const {
175    return allow_circular_includes_from_;
176  }
177  std::set<Label>& allow_circular_includes_from() {
178    return allow_circular_includes_from_;
179  }
180
181  const UniqueVector<const Target*>& inherited_libraries() const {
182    return inherited_libraries_;
183  }
184
185  // This config represents the configuration set directly on this target.
186  ConfigValues& config_values() { return config_values_; }
187  const ConfigValues& config_values() const { return config_values_; }
188
189  ActionValues& action_values() { return action_values_; }
190  const ActionValues& action_values() const { return action_values_; }
191
192  const OrderedSet<SourceDir>& all_lib_dirs() const { return all_lib_dirs_; }
193  const OrderedSet<std::string>& all_libs() const { return all_libs_; }
194
195  const std::set<const Target*>& recursive_hard_deps() const {
196    return recursive_hard_deps_;
197  }
198
199  // The toolchain is only known once this target is resolved (all if its
200  // dependencies are known). They will be null until then. Generally, this can
201  // only be used during target writing.
202  const Toolchain* toolchain() const { return toolchain_; }
203
204  // Sets the toolchain. The toolchain must include a tool for this target
205  // or the error will be set and the function will return false. Unusually,
206  // this function's "err" output is optional since this is commonly used
207  // frequently by unit tests which become needlessly verbose.
208  bool SetToolchain(const Toolchain* toolchain, Err* err = NULL);
209
210  // Returns outputs from this target. The link output file is the one that
211  // other targets link to when they depend on this target. This will only be
212  // valid for libraries and will be empty for all other target types.
213  //
214  // The dependency output file is the file that should be used to express
215  // a dependency on this one. It could be the same as the link output file
216  // (this will be the case for static libraries). For shared libraries it
217  // could be the same or different than the link output file, depending on the
218  // system. For actions this will be the stamp file.
219  //
220  // These are only known once the target is resolved and will be empty before
221  // that. This is a cache of the files to prevent every target that depends on
222  // a given library from recomputing the same pattern.
223  const OutputFile& link_output_file() const {
224    return link_output_file_;
225  }
226  const OutputFile& dependency_output_file() const {
227    return dependency_output_file_;
228  }
229
230 private:
231  // Pulls necessary information from dependencies to this one when all
232  // dependencies have been resolved.
233  void PullDependentTargetInfo();
234
235  // These each pull specific things from dependencies to this one when all
236  // deps have been resolved.
237  void PullForwardedDependentConfigs();
238  void PullForwardedDependentConfigsFrom(const Target* from);
239  void PullRecursiveHardDeps();
240
241  // Fills the link and dependency output files when a target is resolved.
242  void FillOutputFiles();
243
244  // Validates the given thing when a target is resolved.
245  bool CheckVisibility(Err* err) const;
246  bool CheckTestonly(Err* err) const;
247  bool CheckNoNestedStaticLibs(Err* err) const;
248
249  OutputType output_type_;
250  std::string output_name_;
251  std::string output_extension_;
252
253  FileList sources_;
254  bool all_headers_public_;
255  FileList public_headers_;
256  bool check_includes_;
257  bool complete_static_lib_;
258  bool testonly_;
259  FileList inputs_;
260  FileList data_;
261
262  bool hard_dep_;
263
264  LabelTargetVector private_deps_;
265  LabelTargetVector public_deps_;
266  LabelTargetVector data_deps_;
267
268  UniqueVector<LabelConfigPair> configs_;
269  UniqueVector<LabelConfigPair> all_dependent_configs_;
270  UniqueVector<LabelConfigPair> public_configs_;
271  UniqueVector<LabelTargetPair> forward_dependent_configs_;
272
273  std::set<Label> allow_circular_includes_from_;
274
275  bool external_;
276
277  // Static libraries and source sets from transitive deps. These things need
278  // to be linked only with the end target (executable, shared library). Source
279  // sets do not get pushed beyond static library boundaries, and neither
280  // source sets nor static libraries get pushed beyond sahred library
281  // boundaries.
282  UniqueVector<const Target*> inherited_libraries_;
283
284  // These libs and dirs are inherited from statically linked deps and all
285  // configs applying to this target.
286  OrderedSet<SourceDir> all_lib_dirs_;
287  OrderedSet<std::string> all_libs_;
288
289  // All hard deps from this target and all dependencies. Filled in when this
290  // target is marked resolved. This will not include the current target.
291  std::set<const Target*> recursive_hard_deps_;
292
293  ConfigValues config_values_;  // Used for all binary targets.
294  ActionValues action_values_;  // Used for action[_foreach] targets.
295
296  // Toolchain used by this target. Null until target is resolved.
297  const Toolchain* toolchain_;
298
299  // Output files. Null until the target is resolved.
300  OutputFile link_output_file_;
301  OutputFile dependency_output_file_;
302
303  DISALLOW_COPY_AND_ASSIGN(Target);
304};
305
306namespace BASE_HASH_NAMESPACE {
307
308#if defined(COMPILER_GCC)
309template<> struct hash<const Target*> {
310  std::size_t operator()(const Target* t) const {
311    return reinterpret_cast<std::size_t>(t);
312  }
313};
314#elif defined(COMPILER_MSVC)
315inline size_t hash_value(const Target* t) {
316  return reinterpret_cast<size_t>(t);
317}
318#endif  // COMPILER...
319
320}  // namespace BASE_HASH_NAMESPACE
321
322#endif  // TOOLS_GN_TARGET_H_
323