
This patch adds an llvm-driver multicall tool that can combine multiple LLVM-based tools. The build infrastructure is enabled for a tool by adding the GENERATE_DRIVER option to the add_llvm_executable CMake call, and changing the tool's main function to a canonicalized tool_name_main format (i.e. llvm_ar_main, clang_main, etc...). As currently implemented llvm-driver contains dsymutil, llvm-ar, llvm-cxxfilt, llvm-objcopy, and clang (if clang is included in the build). llvm-driver can be enabled from builds by setting LLVM_TOOL_LLVM_DRIVER_BUILD=On. There are several limitations in the current implementation, which can be addressed in subsequent patches: (1) the multicall binary cannot currently properly handle multi-dispatch tools. This means symlinking llvm-ranlib to llvm-driver will not properly result in llvm-ar's main being called. (2) the multicall binary cannot be comprised of tools containing conflicting cl::opt options as the global cl::opt option list cannot contain duplicates. These limitations can be addressed in subsequent patches. Differential revision: https://reviews.llvm.org/D109977
75 lines
2.2 KiB
C++
75 lines
2.2 KiB
C++
//===-- llvm-driver.cpp ---------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/ADT/StringSwitch.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "llvm/Support/WithColor.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define LLVM_DRIVER_TOOL(tool, entry) int entry##_main(int argc, char **argv);
|
|
#include "LLVMDriverTools.def"
|
|
|
|
constexpr char subcommands[] =
|
|
#define LLVM_DRIVER_TOOL(tool, entry) " " tool "\n"
|
|
#include "LLVMDriverTools.def"
|
|
;
|
|
|
|
static void printHelpMessage() {
|
|
llvm::outs() << "OVERVIEW: llvm toolchain driver\n\n"
|
|
<< "USAGE: llvm [subcommand] [options]\n\n"
|
|
<< "SUBCOMMANDS:\n\n"
|
|
<< subcommands
|
|
<< "\n Type \"llvm <subcommand> --help\" to get more help on a "
|
|
"specific subcommand\n\n"
|
|
<< "OPTIONS:\n\n --help - Display this message";
|
|
}
|
|
|
|
static int findTool(int Argc, char **Argv) {
|
|
if (!Argc) {
|
|
printHelpMessage();
|
|
return 1;
|
|
}
|
|
|
|
StringRef ToolName = Argv[0];
|
|
|
|
if (ToolName == "--help") {
|
|
printHelpMessage();
|
|
return 0;
|
|
}
|
|
|
|
StringRef Stem = sys::path::stem(ToolName);
|
|
auto Is = [=](StringRef Tool) {
|
|
auto I = Stem.rfind_insensitive(Tool);
|
|
return I != StringRef::npos && (I + Tool.size() == Stem.size() ||
|
|
!llvm::isAlnum(Stem[I + Tool.size()]));
|
|
};
|
|
|
|
#define LLVM_DRIVER_TOOL(tool, entry) \
|
|
if (Is(tool)) \
|
|
return entry##_main(Argc, Argv);
|
|
#include "LLVMDriverTools.def"
|
|
|
|
if (Is("llvm"))
|
|
return findTool(Argc - 1, Argv + 1);
|
|
|
|
printHelpMessage();
|
|
return 1;
|
|
}
|
|
|
|
extern bool IsLLVMDriver;
|
|
|
|
int main(int Argc, char **Argv) {
|
|
IsLLVMDriver = true;
|
|
return findTool(Argc, Argv);
|
|
}
|