Home | History | Annotate | Download | only in gn
      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 
     26 class InputFile;
     27 class Settings;
     28 class Token;
     29 class Toolchain;
     30 
     31 class 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 
    306 namespace BASE_HASH_NAMESPACE {
    307 
    308 #if defined(COMPILER_GCC)
    309 template<> 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)
    315 inline 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