1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "tools/gn/commands.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "tools/gn/filesystem_utils.h"
72385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "tools/gn/item.h"
82385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "tools/gn/label.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "tools/gn/label_pattern.h"
102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "tools/gn/setup.h"
112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "tools/gn/standard_out.h"
122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "tools/gn/target.h"
132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace commands {
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)CommandInfo::CommandInfo()
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : help_short(NULL),
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      help(NULL),
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      runner(NULL) {
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)CommandInfo::CommandInfo(const char* in_help_short,
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         const char* in_help,
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                         CommandRunner in_runner)
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : help_short(in_help_short),
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      help(in_help),
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      runner(in_runner) {
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const CommandInfoMap& GetCommands() {
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  static CommandInfoMap info_map;
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (info_map.empty()) {
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    #define INSERT_COMMAND(cmd) \
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        info_map[k##cmd] = CommandInfo(k##cmd##_HelpShort, \
35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                       k##cmd##_Help, \
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                       &Run##cmd);
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    INSERT_COMMAND(Args)
39c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    INSERT_COMMAND(Check)
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    INSERT_COMMAND(Desc)
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    INSERT_COMMAND(Gen)
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INSERT_COMMAND(Format)
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    INSERT_COMMAND(Help)
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    INSERT_COMMAND(Ls)
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    INSERT_COMMAND(Refs)
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    #undef INSERT_COMMAND
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return info_map;
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst Target* ResolveTargetFromCommandLineString(
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Setup* setup,
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& label_string) {
552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Need to resolve the label after we know the default toolchain.
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Label default_toolchain = setup->loader()->default_toolchain_label();
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Value arg_value(NULL, label_string);
582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Err err;
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Label label = Label::Resolve(SourceDirForCurrentDirectory(
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   setup->build_settings().root_path()),
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                               default_toolchain, arg_value, &err);
622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (err.has_error()) {
632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    err.PrintToStdout();
642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return NULL;
652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Item* item = setup->builder()->GetItem(label);
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!item) {
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Err(Location(), "Label not found.",
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        label.GetUserVisibleName(false) + " not found.").PrintToStdout();
712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return NULL;
722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Target* target = item->AsTarget();
752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!target) {
762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    Err(Location(), "Not a target.",
772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        "The \"" + label.GetUserVisibleName(false) + "\" thing\n"
782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        "is not a target. Somebody should probably implement this command for "
792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        "other\nitem types.");
802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return NULL;
812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return target;
842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ResolveTargetsFromCommandLinePattern(
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Setup* setup,
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& label_pattern,
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool all_toolchains,
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<const Target*>* matches) {
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Value pattern_value(NULL, label_pattern);
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Err err;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  LabelPattern pattern = LabelPattern::GetPattern(
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SourceDirForCurrentDirectory(setup->build_settings().root_path()),
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pattern_value,
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &err);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (err.has_error()) {
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    err.PrintToStdout();
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!all_toolchains) {
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // By default a pattern with an empty toolchain will match all toolchains.
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // IF the caller wants to default to the main toolchain only, set it
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // explicitly.
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (pattern.toolchain().is_null()) {
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // No explicit toolchain set.
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pattern.set_toolchain(setup->loader()->default_toolchain_label());
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<const Target*> all_targets =
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      setup->builder()->GetAllResolvedTargets();
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < all_targets.size(); i++) {
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (pattern.Matches(all_targets[i]->label()))
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      matches->push_back(all_targets[i]);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace commands
124