Home | History | Annotate | Download | only in gn
      1 // Copyright 2014 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 <algorithm>
      6 #include <set>
      7 
      8 #include "base/command_line.h"
      9 #include "tools/gn/commands.h"
     10 #include "tools/gn/label_pattern.h"
     11 #include "tools/gn/setup.h"
     12 #include "tools/gn/standard_out.h"
     13 #include "tools/gn/target.h"
     14 
     15 namespace commands {
     16 
     17 const char kLs[] = "ls";
     18 const char kLs_HelpShort[] =
     19     "ls: List matching targets.";
     20 const char kLs_Help[] =
     21     "gn ls <build dir> [<label_pattern>] [--out] [--all-toolchains]\n"
     22     "\n"
     23     "  Lists all targets matching the given pattern for the given builn\n"
     24     "  directory. By default, only targets in the default toolchain will\n"
     25     "  be matched unless a toolchain is explicitly supplied.\n"
     26     "\n"
     27     "  If the label pattern is unspecified, list all targets. The label\n"
     28     "  pattern is not a general regular expression (see\n"
     29     "  \"gn help label_pattern\"). If you need more complex expressions,\n"
     30     "  pipe the result through grep.\n"
     31     "\n"
     32     "  --out\n"
     33     "      Lists the results as the files generated by the matching targets.\n"
     34     "      These files will be relative to the build directory such that\n"
     35     "      they can be specified on Ninja's command line as a file to build.\n"
     36     "\n"
     37     "  --all-toolchains\n"
     38     "      Matches all toolchains. If the label pattern does not specify an\n"
     39     "      explicit toolchain, labels from all toolchains will be matched.\n"
     40     "\n"
     41     "Examples\n"
     42     "\n"
     43     "  gn ls out/Debug\n"
     44     "      Lists all targets in the default toolchain.\n"
     45     "\n"
     46     "  gn ls out/Debug \"//base/*\"\n"
     47     "      Lists all targets in the directory base and all subdirectories.\n"
     48     "\n"
     49     "  gn ls out/Debug \"//base:*\"\n"
     50     "      Lists all targets defined in //base/BUILD.gn.\n"
     51     "\n"
     52     "  gn ls out/Debug //base --out\n"
     53     "      Lists the build output file for //base:base\n"
     54     "\n"
     55     "  gn ls out/Debug \"//base/*\" --out | xargs ninja -C out/Debug\n"
     56     "      Builds all targets in //base and all subdirectories.\n"
     57     "\n"
     58     "  gn ls out/Debug //base --all-toolchains\n"
     59     "      Lists all variants of the target //base:base (it may be referenced\n"
     60     "      in multiple toolchains).\n";
     61 
     62 int RunLs(const std::vector<std::string>& args) {
     63   if (args.size() != 1 && args.size() != 2) {
     64     Err(Location(), "You're holding it wrong.",
     65         "Usage: \"gn ls <build dir> [<label_pattern>]\"").PrintToStdout();
     66     return 1;
     67   }
     68 
     69   Setup* setup = new Setup;
     70   if (!setup->DoSetup(args[0], false) || !setup->Run())
     71     return 1;
     72 
     73   const CommandLine* cmdline = CommandLine::ForCurrentProcess();
     74   bool all_toolchains = cmdline->HasSwitch("all-toolchains");
     75 
     76   // Find matching targets.
     77   std::vector<const Target*> matches;
     78   if (args.size() == 2) {
     79     // Given a pattern, match it.
     80     if (!ResolveTargetsFromCommandLinePattern(setup, args[1], all_toolchains,
     81                                               &matches))
     82       return 1;
     83   } else if (all_toolchains) {
     84     // List all resolved targets.
     85     matches = setup->builder()->GetAllResolvedTargets();
     86   } else {
     87     // List all resolved targets in the default toolchain.
     88     std::vector<const Target*> all_targets =
     89         setup->builder()->GetAllResolvedTargets();
     90     for (size_t i = 0; i < all_targets.size(); i++) {
     91       if (all_targets[i]->settings()->is_default())
     92         matches.push_back(all_targets[i]);
     93     }
     94   }
     95 
     96   if (cmdline->HasSwitch("out")) {
     97     // List results as build files.
     98     for (size_t i = 0; i < matches.size(); i++) {
     99       OutputString(matches[i]->dependency_output_file().value());
    100       OutputString("\n");
    101     }
    102   } else {
    103     // List results as sorted labels.
    104     std::vector<Label> sorted_matches;
    105     for (size_t i = 0; i < matches.size(); i++)
    106       sorted_matches.push_back(matches[i]->label());
    107     std::sort(sorted_matches.begin(), sorted_matches.end());
    108 
    109     Label default_tc_label = setup->loader()->default_toolchain_label();
    110     for (size_t i = 0; i < sorted_matches.size(); i++) {
    111       // Print toolchain only for ones not in the default toolchain.
    112       OutputString(sorted_matches[i].GetUserVisibleName(
    113           sorted_matches[i].GetToolchainLabel() != default_tc_label));
    114       OutputString("\n");
    115     }
    116   }
    117 
    118   return 0;
    119 }
    120 
    121 }  // namespace commands
    122