commands.cc revision 3551c9c881056c480085172ff9840cab31610854
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#include "tools/gn/commands.h"
6#include "tools/gn/item.h"
7#include "tools/gn/item_node.h"
8#include "tools/gn/label.h"
9#include "tools/gn/setup.h"
10#include "tools/gn/standard_out.h"
11#include "tools/gn/target.h"
12
13namespace commands {
14
15CommandInfo::CommandInfo()
16    : help_short(NULL),
17      help(NULL),
18      runner(NULL) {
19}
20
21CommandInfo::CommandInfo(const char* in_help_short,
22                         const char* in_help,
23                         CommandRunner in_runner)
24    : help_short(in_help_short),
25      help(in_help),
26      runner(in_runner) {
27}
28
29const CommandInfoMap& GetCommands() {
30  static CommandInfoMap info_map;
31  if (info_map.empty()) {
32    #define INSERT_COMMAND(cmd) \
33        info_map[k##cmd] = CommandInfo(k##cmd##_HelpShort, \
34                                       k##cmd##_Help, \
35                                       &Run##cmd);
36
37    INSERT_COMMAND(Args)
38    INSERT_COMMAND(Desc)
39    INSERT_COMMAND(Gen)
40    INSERT_COMMAND(Help)
41    INSERT_COMMAND(Refs)
42
43    #undef INSERT_COMMAND
44  }
45  return info_map;
46}
47
48const Target* GetTargetForDesc(const std::vector<std::string>& args) {
49  // Deliberately leaked to avoid expensive process teardown.
50  Setup* setup = new Setup;
51  if (!setup->DoSetup())
52    return NULL;
53
54  // FIXME(brettw): set the output dir to be a sandbox one to avoid polluting
55  // the real output dir with files written by the build scripts.
56
57  // Do the actual load. This will also write out the target ninja files.
58  if (!setup->Run())
59    return NULL;
60
61  // Need to resolve the label after we know the default toolchain.
62  // TODO(brettw) find the current directory and resolve the input label
63  // relative to that.
64  Label default_toolchain = setup->build_settings().toolchain_manager()
65      .GetDefaultToolchainUnlocked();
66  Value arg_value(NULL, args[0]);
67  Err err;
68  Label label =
69      Label::Resolve(SourceDir("//"), default_toolchain, arg_value, &err);
70  if (err.has_error()) {
71    err.PrintToStdout();
72    return NULL;
73  }
74
75  ItemNode* node;
76  {
77    base::AutoLock lock(setup->build_settings().item_tree().lock());
78    node = setup->build_settings().item_tree().GetExistingNodeLocked(label);
79  }
80  if (!node) {
81    Err(Location(), "",
82        "I don't know about this \"" + label.GetUserVisibleName(false) +
83        "\"").PrintToStdout();
84    return NULL;
85  }
86
87  const Target* target = node->item()->AsTarget();
88  if (!target) {
89    Err(Location(), "Not a target.",
90        "The \"" + label.GetUserVisibleName(false) + "\" thing\n"
91        "is not a target. Somebody should probably implement this command for "
92        "other\nitem types.");
93    return NULL;
94  }
95
96  return target;
97}
98
99}  // namespace commands
100