Skip to content

Commit

Permalink
[llvm-debuginfod][NFC] Switch to OptTable
Browse files Browse the repository at this point in the history
Reviewed By: mysterymath

Differential Revision: https://reviews.llvm.org/D151273
  • Loading branch information
avillega authored and mysterymath committed May 26, 2023
1 parent a2684ac commit 1610627
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 40 deletions.
8 changes: 8 additions & 0 deletions llvm/tools/llvm-debuginfod/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
set(LLVM_LINK_COMPONENTS
Option
Support
)
set(LLVM_TARGET_DEFINITIONS Opts.td)
tablegen(LLVM Opts.inc -gen-opt-parser-defs)
add_public_tablegen_target(DebugInfodOptsTableGen)

add_llvm_tool(llvm-debuginfod
llvm-debuginfod.cpp

DEPENDS
DebugInfodOptsTableGen
)
target_link_libraries(llvm-debuginfod PRIVATE LLVMDebuginfod)
if(LLVM_INSTALL_BINUTILS_SYMLINKS)
Expand Down
20 changes: 20 additions & 0 deletions llvm/tools/llvm-debuginfod/Opts.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
include "llvm/Option/OptParser.td"

class F<string name, string help> : Flag<["-"], name>, HelpText<help>;
class FF<string name, string help>: Flag<["--"], name>, HelpText<help>;
class S<string name, string meta, string help>: Separate<["-"], name>, HelpText<help>, MetaVarName<meta>;

def help : FF<"help", "Display available options">;
def : F<"h", "Alias for --help">, Alias<help>;
def max_concurrency :
S<"c", "<ulong>", "Maximum number of files to scan concurrently. "
"If 0, use the hardware concurrency.">;
def host_interface : S<"i", "<string>", "Host interface to bind to.">;
def min_interval :
S<"m", "<number>", "Minimum number of seconds to wait before an on-demand update can be"
"triggered by a request for a buildid which is not in the collection.">;
def port : S<"p", "<uint>", "Port to listen on. Set to 0 to bind to any available port.">;
def scan_interval :
S<"t", "<int>", "Number of seconds to wait between subsequent "
"automated scans of the filesystem.">;
def verbose_logging : F<"v", "Enable verbose logging.">;
140 changes: 100 additions & 40 deletions llvm/tools/llvm-debuginfod/llvm-debuginfod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,60 +15,120 @@
///
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringRef.h"
#include "llvm/Debuginfod/Debuginfod.h"
#include "llvm/Debuginfod/HTTPClient.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ThreadPool.h"

using namespace llvm;

cl::OptionCategory DebuginfodCategory("llvm-debuginfod Options");

static cl::list<std::string> ScanPaths(cl::Positional,
cl::desc("<Directories to scan>"),
cl::cat(DebuginfodCategory));

static cl::opt<unsigned>
Port("p", cl::init(0),
cl::desc("Port to listen on. Set to 0 to bind to any available port."),
cl::cat(DebuginfodCategory));

static cl::opt<std::string>
HostInterface("i", cl::init("0.0.0.0"),
cl::desc("Host interface to bind to."),
cl::cat(DebuginfodCategory));

static cl::opt<int>
ScanInterval("t", cl::init(300),
cl::desc("Number of seconds to wait between subsequent "
"automated scans of the filesystem."),
cl::cat(DebuginfodCategory));

static cl::opt<double> MinInterval(
"m", cl::init(10),
cl::desc(
"Minimum number of seconds to wait before an on-demand update can be "
"triggered by a request for a buildid which is not in the collection."),
cl::cat(DebuginfodCategory));

static cl::opt<size_t>
MaxConcurrency("c", cl::init(0),
cl::desc("Maximum number of files to scan concurrently. If "
"0, use the hardware concurrency."),
cl::cat(DebuginfodCategory));

static cl::opt<bool> VerboseLogging("v", cl::init(false),
cl::desc("Enable verbose logging."),
cl::cat(DebuginfodCategory));
// Command-line option boilerplate.
namespace {
enum ID {
OPT_INVALID = 0, // This is not an option ID.
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES) \
OPT_##ID,
#include "Opts.inc"
#undef OPTION
};

#define PREFIX(NAME, VALUE) \
static constexpr StringLiteral NAME##_init[] = VALUE; \
static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
std::size(NAME##_init) - 1);
#include "Opts.inc"
#undef PREFIX

static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES) \
{ \
PREFIX, NAME, HELPTEXT, \
METAVAR, OPT_##ID, opt::Option::KIND##Class, \
PARAM, FLAGS, OPT_##GROUP, \
OPT_##ALIAS, ALIASARGS, VALUES},
#include "Opts.inc"
#undef OPTION
};

class DebuginfodOptTable : public opt::GenericOptTable {
public:
DebuginfodOptTable() : GenericOptTable(InfoTable) {}
};
} // end anonymous namespace

// Options
static unsigned Port;
static std::string HostInterface;
static int ScanInterval;
static double MinInterval;
static size_t MaxConcurrency;
static bool VerboseLogging;
static std::vector<std::string> ScanPaths;

ExitOnError ExitOnErr;

template <typename T>
static void parseIntArg(const opt::InputArgList &Args, int ID, T &Value,
T Default) {
if (const opt::Arg *A = Args.getLastArg(ID)) {
StringRef V(A->getValue());
if (!llvm::to_integer(V, Value, 0)) {
errs() << A->getSpelling() + ": expected an integer, but got '" + V + "'";
exit(1);
}
} else {
Value = Default;
}
}

static void parseArgs(int argc, char **argv) {
DebuginfodOptTable Tbl;
llvm::StringRef ToolName = argv[0];
llvm::BumpPtrAllocator A;
llvm::StringSaver Saver{A};
opt::InputArgList Args =
Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
llvm::errs() << Msg << '\n';
std::exit(1);
});

if (Args.hasArg(OPT_help)) {
Tbl.printHelp(llvm::outs(),
"llvm-debuginfod [options] <Directories to scan>",
ToolName.str().c_str());
std::exit(0);
}

VerboseLogging = Args.hasArg(OPT_verbose_logging);
ScanPaths = Args.getAllArgValues(OPT_INPUT);

parseIntArg(Args, OPT_port, Port, 0u);
parseIntArg(Args, OPT_scan_interval, ScanInterval, 300);
parseIntArg(Args, OPT_max_concurrency, MaxConcurrency, 0ul);

if (const opt::Arg *A = Args.getLastArg(OPT_min_interval)) {
StringRef V(A->getValue());
if (!llvm::to_float(V, MinInterval)) {
errs() << A->getSpelling() + ": expected a number, but got '" + V + "'";
exit(1);
}
} else {
MinInterval = 10.0;
}

HostInterface = Args.getLastArgValue(OPT_host_interface, "0.0.0.0");
}

int main(int argc, char **argv) {
InitLLVM X(argc, argv);
HTTPClient::initialize();
cl::HideUnrelatedOptions({&DebuginfodCategory});
cl::ParseCommandLineOptions(argc, argv);
parseArgs(argc, argv);

SmallVector<StringRef, 1> Paths;
for (const std::string &Path : ScanPaths)
Expand Down
8 changes: 8 additions & 0 deletions llvm/utils/gn/secondary/llvm/tools/llvm-debuginfod/BUILD.gn
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")

tablegen("Opts") {
visibility = [ ":llvm-debuginfod" ]
args = [ "-gen-opt-parser-defs" ]
}

if (llvm_install_binutils_symlinks) {
symlink_or_copy("debuginfod") {
deps = [ ":llvm-debuginfod" ]
Expand All @@ -19,7 +25,9 @@ group("symlinks") {

executable("llvm-debuginfod") {
deps = [
":Opts",
"//llvm/lib/Debuginfod",
"//llvm/lib/Option",
"//llvm/lib/Support",
]
sources = [ "llvm-debuginfod.cpp" ]
Expand Down

0 comments on commit 1610627

Please sign in to comment.