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_ITEM_TREE_H_
      6 #define TOOLS_GN_ITEM_TREE_H_
      7 
      8 #include "base/containers/hash_tables.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/synchronization/lock.h"
     11 #include "tools/gn/label.h"
     12 
     13 class BuildSettings;
     14 class Err;
     15 class Item;
     16 class ItemNode;
     17 
     18 // Represents the full dependency tree if labeled items in the system.
     19 // Generally you will interact with this through the target manager, etc.
     20 //
     21 // There are two modes for filling out the dependency tree:
     22 //
     23 // - In greedy mode, every target we encounter will be generated. This means
     24 //   that we'll recursively load all of its subdependencies. So if you have
     25 //   a build file that's loaded for any reason, all targets in that build file
     26 //   will be generated.
     27 //
     28 // - In non-greedy mode, we'll only generate and load dependncies for targets
     29 //   that have the should_generate bit set. This allows us to load the minimal
     30 //   set of buildfiles required for one or more targets.
     31 //
     32 // The main build is generally run in greedy mode, since people expect to be
     33 // be able to write random tests and have them show up in the output. We'll
     34 // switch into non-greed mode when doing diagnostics (like displaying the
     35 // dependency tree on the command line) and for dependencies on targets in
     36 // other toolchains. The toolchain behavior is important, if target A depends
     37 // on B with an alternate toolchain, it doesn't mean we should recursively
     38 // generate all targets in the buildfile just to get B: we should generate the
     39 // and load the minimum number of files in order to resolve B.
     40 class ItemTree {
     41  public:
     42   ItemTree();
     43   ~ItemTree();
     44 
     45   // This lock must be held when calling the "Locked" functions below.
     46   base::Lock& lock() const { return lock_; }
     47 
     48   // Returns NULL if the item is not found.
     49   //
     50   // The lock must be held.
     51   ItemNode* GetExistingNodeLocked(const Label& label);
     52 
     53   // There must not be an item with this label in the tree already. Takes
     54   // ownership of the pointer.
     55   //
     56   // The lock must be held.
     57   void AddNodeLocked(ItemNode* node);
     58 
     59   // Mark the given item as being defined. If it has no unresolved
     60   // dependencies, it will be marked resolved, and the resolved state will be
     61   // recursively pushed into the dependency tree. Returns an error if there was
     62   // an error.
     63   bool MarkItemDefinedLocked(const BuildSettings* build_settings,
     64                              const Label& label,
     65                              Err* err);
     66 
     67   // Fills the given vector with all known items.
     68   void GetAllItemsLocked(std::vector<const Item*>* dest) const;
     69 
     70   // Returns an error if there are unresolved dependencies, or no error if
     71   // there aren't.
     72   //
     73   // The lock should not be held.
     74   Err CheckForBadItems() const;
     75 
     76  private:
     77   void MarkItemResolvedLocked(ItemNode* node);
     78 
     79   // Given a set of unresolved nodes, looks for cycles and returns the error
     80   // message describing any cycles it found.
     81   std::string CheckForCircularDependenciesLocked(
     82       const std::vector<const ItemNode*>& bad_nodes) const;
     83 
     84   mutable base::Lock lock_;
     85 
     86   typedef base::hash_map<Label, ItemNode*> StringToNodeHash;
     87   StringToNodeHash items_;  // Owning pointer.
     88 
     89   DISALLOW_COPY_AND_ASSIGN(ItemTree);
     90 };
     91 
     92 #endif  // TOOLS_GN_ITEM_TREE_H_
     93