[clang] f06abbb - LLVM Driver Multicall tool
Alex Brachet via cfe-commits
cfe-commits at lists.llvm.org
Sun Jun 5 21:28:12 PDT 2022
Author: Chris Bieneman
Date: 2022-06-06T04:27:32Z
New Revision: f06abbb393800b0d466c88e283c06f75561c432c
URL: https://github.com/llvm/llvm-project/commit/f06abbb393800b0d466c88e283c06f75561c432c
DIFF: https://github.com/llvm/llvm-project/commit/f06abbb393800b0d466c88e283c06f75561c432c.diff
LOG: LLVM Driver Multicall tool
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
Added:
llvm/cmake/driver-template.cpp.in
llvm/test/tools/llvm-driver/help-passthrough.test
llvm/test/tools/llvm-driver/help.test
llvm/test/tools/llvm-driver/symlink-call.test
llvm/tools/llvm-driver/CMakeLists.txt
llvm/tools/llvm-driver/llvm-driver.cpp
Modified:
clang/cmake/modules/AddClang.cmake
clang/tools/driver/CMakeLists.txt
clang/tools/driver/driver.cpp
llvm/CMakeLists.txt
llvm/cmake/modules/AddLLVM.cmake
llvm/lib/Support/Path.cpp
llvm/lib/Support/Unix/Path.inc
llvm/lib/Support/Windows/Path.inc
llvm/test/CMakeLists.txt
llvm/test/lit.cfg.py
llvm/test/lit.site.cfg.py.in
llvm/tools/CMakeLists.txt
llvm/tools/dsymutil/CMakeLists.txt
llvm/tools/dsymutil/dsymutil.cpp
llvm/tools/llvm-ar/CMakeLists.txt
llvm/tools/llvm-ar/llvm-ar.cpp
llvm/tools/llvm-cxxfilt/CMakeLists.txt
llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
llvm/tools/llvm-objcopy/CMakeLists.txt
llvm/tools/llvm-objcopy/llvm-objcopy.cpp
utils/bazel/llvm-project-overlay/clang/BUILD.bazel
utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
Removed:
################################################################################
diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake
index 9bbbfc032b7df..299f8ce6e2fb4 100644
--- a/clang/cmake/modules/AddClang.cmake
+++ b/clang/cmake/modules/AddClang.cmake
@@ -184,5 +184,8 @@ function(clang_target_link_libraries target type)
else()
target_link_libraries(${target} ${type} ${ARGN})
endif()
+ if (TARGET obj.${target})
+ target_link_libraries(obj.${target} ${ARGN})
+ endif()
endfunction()
diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt
index 6b3e159d1b648..d05b71db13f21 100644
--- a/clang/tools/driver/CMakeLists.txt
+++ b/clang/tools/driver/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_tool(clang
DEPENDS
intrinsics_gen
${support_plugins}
+ GENERATE_DRIVER
)
clang_target_link_libraries(clang
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index d361457f8cecd..fa1f09b44f4da 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -327,7 +327,7 @@ static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV) {
return 1;
}
-int main(int Argc, const char **Argv) {
+int clang_main(int Argc, char **Argv) {
noteBottomOfStack();
llvm::InitLLVM X(Argc, Argv);
llvm::setBugReportMsg("PLEASE submit a bug report to " BUG_REPORT_URL
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 1effbde06b80e..fab16edd7d532 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -269,6 +269,8 @@ include(VersionFromVCS)
option(LLVM_APPEND_VC_REV
"Embed the version control system revision in LLVM" ON)
+option(LLVM_TOOL_LLVM_DRIVER_BUILD "Enables building the llvm multicall tool" OFF)
+
set(PACKAGE_NAME LLVM)
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/llvm/llvm-project/issues/")
diff --git a/llvm/cmake/driver-template.cpp.in b/llvm/cmake/driver-template.cpp.in
new file mode 100644
index 0000000000000..2164fb00d168f
--- /dev/null
+++ b/llvm/cmake/driver-template.cpp.in
@@ -0,0 +1,11 @@
+//===-- driver-template.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
+//
+//===----------------------------------------------------------------------===//
+
+int @TOOL_NAME at _main(int argc, char **argv);
+
+int main(int argc, char **argv) { return @TOOL_NAME at _main(argc, argv); }
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
index f798243a80b22..64d719f2626c9 100644
--- a/llvm/cmake/modules/AddLLVM.cmake
+++ b/llvm/cmake/modules/AddLLVM.cmake
@@ -859,7 +859,7 @@ endmacro(add_llvm_library name)
macro(add_llvm_executable name)
cmake_parse_arguments(ARG
- "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS"
+ "DISABLE_LLVM_LINK_LLVM_DYLIB;IGNORE_EXTERNALIZE_DEBUGINFO;NO_INSTALL_RPATH;SUPPORT_PLUGINS;GENERATE_DRIVER"
"ENTITLEMENTS;BUNDLE_PATH"
"DEPENDS"
${ARGN})
@@ -869,7 +869,7 @@ macro(add_llvm_executable name)
list(APPEND LLVM_COMMON_DEPENDS ${ARG_DEPENDS})
# Generate objlib
- if(LLVM_ENABLE_OBJLIB)
+ if(LLVM_ENABLE_OBJLIB OR ARG_GENERATE_DRIVER)
# Generate an obj library for both targets.
set(obj_name "obj.${name}")
add_library(${obj_name} OBJECT EXCLUDE_FROM_ALL
@@ -884,6 +884,23 @@ macro(add_llvm_executable name)
set_target_properties(${obj_name} PROPERTIES FOLDER "Object Libraries")
endif()
+ if (ARG_GENERATE_DRIVER)
+ string(REPLACE "-" "_" TOOL_NAME ${name})
+ configure_file(
+ ${LLVM_MAIN_SRC_DIR}/cmake/driver-template.cpp.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${name}-driver.cpp)
+
+ list(APPEND ALL_FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}-driver.cpp)
+
+ set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_COMPONENTS ${LLVM_LINK_COMPONENTS})
+ set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_DEPS ${ARG_DEPENDS} ${LLVM_COMMON_DEPENDS})
+ set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_OBJLIBS "${obj_name}")
+
+ set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOLS ${name})
+ target_link_libraries(${obj_name} ${LLVM_PTHREAD_LIB})
+ llvm_config(${obj_name} ${USE_SHARED} ${LLVM_LINK_COMPONENTS} )
+ endif()
+
add_windows_version_resource_file(ALL_FILES ${ALL_FILES})
if(XCODE)
@@ -1449,6 +1466,12 @@ function(llvm_add_implicit_projects project)
foreach(dir ${sub-dirs})
if(IS_DIRECTORY "${dir}" AND EXISTS "${dir}/CMakeLists.txt")
canonicalize_tool_name(${dir} name)
+ # I don't like special casing things by order, but the llvm-driver ends up
+ # linking the object libraries from all the tools that opt-in, so adding
+ # it separately at the end is probably the simplest case.
+ if("${name}" STREQUAL "LLVM_DRIVER")
+ continue()
+ endif()
if (${project}_TOOL_${name}_BUILD)
get_filename_component(fn "${dir}" NAME)
list(APPEND list_of_implicit_subdirs "${fn}")
@@ -1998,6 +2021,16 @@ endfunction()
function(add_llvm_tool_symlink link_name target)
cmake_parse_arguments(ARG "ALWAYS_GENERATE" "OUTPUT_DIR" "" ${ARGN})
+
+ get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
+
+ if (${target} IN_LIST LLVM_DRIVER_TOOLS)
+ string(REPLACE "-" "_" tool_entry ${target})
+ string(REPLACE "-" "_" key ${link_name})
+ string(REPLACE "llvm-" "" tool_name ${link_name})
+ set_property(GLOBAL APPEND_STRING PROPERTY
+ LLVM_EXTRA_DRIVER_ENTRIES "LLVM_DRIVER_TOOL(\"${tool_name}\", ${tool_entry})\n")
+ endif()
set(dest_binary "$<TARGET_FILE:${target}>")
# This got a bit gross... For multi-configuration generators the target
diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index 9575e34b81c63..283dc70f2bc9a 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -1202,9 +1202,18 @@ Error readNativeFileToEOF(file_t FileHandle, SmallVectorImpl<char> &Buffer,
#include "Windows/Path.inc"
#endif
+bool IsLLVMDriver = false;
+
namespace llvm {
namespace sys {
namespace fs {
+
+std::string getMainExecutable(const char *Argv0, void *MainAddr) {
+ if (IsLLVMDriver)
+ return sys::path::stem(Argv0).str();
+ return getMainExecutableImpl(Argv0, MainAddr);
+}
+
TempFile::TempFile(StringRef Name, int FD)
: TmpName(std::string(Name)), FD(FD) {}
TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); }
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index c4345f13f0a6e..2ae7c6dc47e07 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -194,7 +194,7 @@ getprogpath(char ret[PATH_MAX], const char *bin)
/// GetMainExecutable - Return the path to the main executable, given the
/// value of argv[0] from program startup.
-std::string getMainExecutable(const char *argv0, void *MainAddr) {
+std::string getMainExecutableImpl(const char *argv0, void *MainAddr) {
#if defined(__APPLE__)
// On OS X the executable path is saved to the stack by dyld. Reading it
// from there is much faster than calling dladdr, especially for large
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 5f1a364ea1a8e..433c62900a3f6 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -130,7 +130,7 @@ namespace fs {
const file_t kInvalidFile = INVALID_HANDLE_VALUE;
-std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
+std::string getMainExecutableImpl(const char *argv0, void *MainExecAddr) {
SmallVector<wchar_t, MAX_PATH> PathName;
PathName.resize_for_overwrite(PathName.capacity());
DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.size());
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 50a4a982ec4d2..bc2869dc536b5 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -21,6 +21,7 @@ llvm_canonicalize_cmake_booleans(
LLVM_RAEVICT_MODEL_AUTOGENERATED
LLVM_ENABLE_EXPENSIVE_CHECKS
LLVM_INCLUDE_DXIL_TESTS
+ LLVM_TOOL_LLVM_DRIVER_BUILD
)
configure_lit_site_cfg(
@@ -144,6 +145,10 @@ if(TARGET llvm-lto)
set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} llvm-lto)
endif()
+if(TARGET llvm-driver)
+ set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} llvm-driver)
+endif()
+
# If Intel JIT events are supported, depend on a tool that tests the listener.
if( LLVM_USE_INTEL_JITEVENTS )
set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} llvm-jitlistener)
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index b6fb8aa9fab76..a1f4f86b84562 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -139,6 +139,7 @@ def get_asan_rtlib():
config.llvm_locstats_used = os.path.exists(llvm_locstats_tool)
tools = [
+ ToolSubst('%llvm', FindTool('llvm')),
ToolSubst('%lli', FindTool('lli'), post='.', extra_args=lli_args),
ToolSubst('%llc_dwarf', FindTool('llc'), extra_args=llc_args),
ToolSubst('%go', config.go_executable, unresolved='ignore'),
@@ -350,6 +351,9 @@ def have_cxx_shared_library():
if not config.target_triple.startswith(("nvptx", "xcore")):
config.available_features.add('object-emission')
+if config.have_llvm_driver:
+ config.available_features.add('llvm-driver')
+
import subprocess
diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in
index 266f93232ed61..c3f6cb6dd3ca1 100644
--- a/llvm/test/lit.site.cfg.py.in
+++ b/llvm/test/lit.site.cfg.py.in
@@ -59,6 +59,7 @@ config.llvm_inliner_model_autogenerated = @LLVM_INLINER_MODEL_AUTOGENERATED@
config.llvm_raevict_model_autogenerated = @LLVM_RAEVICT_MODEL_AUTOGENERATED@
config.expensive_checks = @LLVM_ENABLE_EXPENSIVE_CHECKS@
config.dxil_tests = @LLVM_INCLUDE_DXIL_TESTS@
+config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@
import lit.llvm
lit.llvm.initialize(lit_config, config)
diff --git a/llvm/test/tools/llvm-driver/help-passthrough.test b/llvm/test/tools/llvm-driver/help-passthrough.test
new file mode 100644
index 0000000000000..93f6146cdbbbe
--- /dev/null
+++ b/llvm/test/tools/llvm-driver/help-passthrough.test
@@ -0,0 +1,3 @@
+# REQUIRES: llvm-driver
+# RUN: %llvm cxxfilt --help | FileCheck %s
+# CHECK: USAGE: cxxfilt
diff --git a/llvm/test/tools/llvm-driver/help.test b/llvm/test/tools/llvm-driver/help.test
new file mode 100644
index 0000000000000..c16a30833c65d
--- /dev/null
+++ b/llvm/test/tools/llvm-driver/help.test
@@ -0,0 +1,3 @@
+# REQUIRES: llvm-driver
+# RUN: %llvm --help | FileCheck %s
+# CHECK: USAGE: llvm [subcommand]
diff --git a/llvm/test/tools/llvm-driver/symlink-call.test b/llvm/test/tools/llvm-driver/symlink-call.test
new file mode 100644
index 0000000000000..eeedf9edc73f2
--- /dev/null
+++ b/llvm/test/tools/llvm-driver/symlink-call.test
@@ -0,0 +1,23 @@
+## Don't make symlinks on Windows.
+# UNSUPPORTED: system-windows
+# REQUIRES: llvm-driver
+
+# RUN: rm -rf %t
+# RUN: mkdir %t
+# RUN: ln -s %llvm %t/llvm-cxxfilt
+# RUN: %t/llvm-cxxfilt --help | FileCheck %s
+# RUN: ln -s %llvm %t/llvm-cxxfilt-15
+# RUN: %t/llvm-cxxfilt-15 --help | FileCheck %s
+# RUN: ln -s %llvm %t/cxxfilt
+# RUN: %t/cxxfilt --help | FileCheck %s
+# RUN: ln -s %llvm %t/cxxfilt-15
+# RUN: %t/cxxfilt-15 --help | FileCheck %s
+# RUN: ln -s %llvm %t/cxxfilt-15.exe
+# RUN: %t/cxxfilt-15.exe --help | FileCheck %s
+
+# RUN: ln -s %llvm %t/llvm-15
+# RUN: %t/llvm-15 cxxfilt --help | FileCheck %s
+# RUN: ln -s %llvm %t/llvm-15.exe
+# RUN: %t/llvm-15.exe cxxfilt --help | FileCheck %s
+
+# CHECK: OVERVIEW: LLVM symbol undecoration tool
diff --git a/llvm/tools/CMakeLists.txt b/llvm/tools/CMakeLists.txt
index 770e46c4806f5..ef5edb195317b 100644
--- a/llvm/tools/CMakeLists.txt
+++ b/llvm/tools/CMakeLists.txt
@@ -53,3 +53,9 @@ foreach(p ${LLVM_EXTERNAL_PROJECTS})
endforeach(p)
set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
+
+if (LLVM_TOOL_LLVM_DRIVER_BUILD)
+ # This is explicitly added at the end _after_ all tool projects so that it can
+ # scrape up tools from other projects into itself.
+ add_subdirectory(llvm-driver)
+endif()
diff --git a/llvm/tools/dsymutil/CMakeLists.txt b/llvm/tools/dsymutil/CMakeLists.txt
index 1efc58d19e92c..a255c1c5daf51 100644
--- a/llvm/tools/dsymutil/CMakeLists.txt
+++ b/llvm/tools/dsymutil/CMakeLists.txt
@@ -32,6 +32,8 @@ add_llvm_tool(dsymutil
DEPENDS
intrinsics_gen
${tablegen_deps}
+ DsymutilTableGen
+ GENERATE_DRIVER
)
if(APPLE)
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index df50432368471..abdb4ca4d48ce 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -521,7 +521,7 @@ getOutputFileName(StringRef InputFile, const DsymutilOptions &Options) {
return OutputLocation(std::string(Path.str()), ResourceDir);
}
-int main(int argc, char **argv) {
+int dsymutil_main(int argc, char **argv) {
InitLLVM X(argc, argv);
// Parse arguments.
diff --git a/llvm/tools/llvm-ar/CMakeLists.txt b/llvm/tools/llvm-ar/CMakeLists.txt
index 602b4a46ea055..166d670017159 100644
--- a/llvm/tools/llvm-ar/CMakeLists.txt
+++ b/llvm/tools/llvm-ar/CMakeLists.txt
@@ -15,6 +15,7 @@ add_llvm_tool(llvm-ar
DEPENDS
intrinsics_gen
+ GENERATE_DRIVER
)
add_llvm_tool_symlink(llvm-ranlib llvm-ar)
diff --git a/llvm/tools/llvm-ar/llvm-ar.cpp b/llvm/tools/llvm-ar/llvm-ar.cpp
index a93943295cf93..abd10f1b500b0 100644
--- a/llvm/tools/llvm-ar/llvm-ar.cpp
+++ b/llvm/tools/llvm-ar/llvm-ar.cpp
@@ -1265,7 +1265,7 @@ static int ranlib_main(int argc, char **argv) {
return performOperation(CreateSymTab, nullptr);
}
-int main(int argc, char **argv) {
+int llvm_ar_main(int argc, char **argv) {
InitLLVM X(argc, argv);
ToolName = argv[0];
diff --git a/llvm/tools/llvm-cxxfilt/CMakeLists.txt b/llvm/tools/llvm-cxxfilt/CMakeLists.txt
index 07ba9f9e9b1d0..367744beb9b60 100644
--- a/llvm/tools/llvm-cxxfilt/CMakeLists.txt
+++ b/llvm/tools/llvm-cxxfilt/CMakeLists.txt
@@ -13,6 +13,7 @@ add_llvm_tool(llvm-cxxfilt
DEPENDS
CxxfiltOptsTableGen
+ GENERATE_DRIVER
)
if(LLVM_INSTALL_BINUTILS_SYMLINKS)
diff --git a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
index ccfaaa96deb21..1cea9e29faa4f 100644
--- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
+++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
@@ -140,7 +140,7 @@ static void demangleLine(llvm::raw_ostream &OS, StringRef Mangled, bool Split) {
OS.flush();
}
-int main(int argc, char **argv) {
+int llvm_cxxfilt_main(int argc, char **argv) {
InitLLVM X(argc, argv);
BumpPtrAllocator A;
StringSaver Saver(A);
diff --git a/llvm/tools/llvm-driver/CMakeLists.txt b/llvm/tools/llvm-driver/CMakeLists.txt
new file mode 100644
index 0000000000000..7cbeaf398eb4b
--- /dev/null
+++ b/llvm/tools/llvm-driver/CMakeLists.txt
@@ -0,0 +1,31 @@
+get_property(LLVM_COMMON_DEPENDS GLOBAL PROPERTY LLVM_DRIVER_DEPS)
+get_property(LLVM_DRIVER_OBJLIBS GLOBAL PROPERTY LLVM_DRIVER_OBJLIBS)
+
+get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
+
+foreach(tool ${LLVM_DRIVER_TOOLS})
+ string(REPLACE "-" "_" tool_entry ${tool})
+ string(REPLACE "llvm-" "" tool ${tool})
+ set(def_decl "${def_decl}LLVM_DRIVER_TOOL(\"${tool}\", ${tool_entry})\n")
+endforeach()
+
+get_property(LLVM_EXTRA_DRIVER_ENTRIES GLOBAL PROPERTY LLVM_EXTRA_DRIVER_ENTRIES)
+
+file(WRITE
+ "${CMAKE_CURRENT_BINARY_DIR}/LLVMDriverTools.def"
+ "${def_decl}${LLVM_EXTRA_DRIVER_ENTRIES}#undef LLVM_DRIVER_TOOL\n")
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_llvm_tool(llvm-driver
+ llvm-driver.cpp
+ )
+
+set_target_properties(llvm-driver PROPERTIES OUTPUT_NAME llvm)
+
+target_link_libraries(llvm-driver PUBLIC ${LLVM_DRIVER_OBJLIBS})
+
+if(APPLE)
+ # dsymutil uses some CoreFoundation stuff on Darwin...
+ target_link_libraries(llvm-driver PRIVATE "-framework CoreFoundation")
+endif(APPLE)
diff --git a/llvm/tools/llvm-driver/llvm-driver.cpp b/llvm/tools/llvm-driver/llvm-driver.cpp
new file mode 100644
index 0000000000000..3f543360ffbc4
--- /dev/null
+++ b/llvm/tools/llvm-driver/llvm-driver.cpp
@@ -0,0 +1,74 @@
+//===-- 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);
+}
diff --git a/llvm/tools/llvm-objcopy/CMakeLists.txt b/llvm/tools/llvm-objcopy/CMakeLists.txt
index 493cc87b0768c..ca94d4a477406 100644
--- a/llvm/tools/llvm-objcopy/CMakeLists.txt
+++ b/llvm/tools/llvm-objcopy/CMakeLists.txt
@@ -30,6 +30,7 @@ add_llvm_tool(llvm-objcopy
ObjcopyOptsTableGen
InstallNameToolOptsTableGen
StripOptsTableGen
+ GENERATE_DRIVER
)
add_llvm_tool_symlink(llvm-install-name-tool llvm-objcopy)
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 117a63cd9d8fb..aa262152ed646 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -223,7 +223,7 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
return Error::success();
}
-int main(int argc, char **argv) {
+int llvm_objcopy_main(int argc, char **argv) {
InitLLVM X(argc, argv);
ToolName = argv[0];
diff --git a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
index 702547e87df37..5e93d9ebe71be 100644
--- a/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/clang/BUILD.bazel
@@ -5,6 +5,7 @@
load("//llvm:tblgen.bzl", "gentbl")
load("//llvm:binary_alias.bzl", "binary_alias")
load("//llvm:cc_plugin_library.bzl", "cc_plugin_library")
+load("//llvm:template_rule.bzl", "template_rule")
package(
default_visibility = ["//visibility:public"],
@@ -1925,12 +1926,21 @@ cc_binary(
],
)
+template_rule(
+ name = "clang_main",
+ src = "//llvm:cmake/driver-template.cpp.in",
+ out = "clang_main.cpp",
+ substitutions = {
+ "@TOOL_NAME@": "clang"
+ },
+)
+
cc_library(
name = "clang-driver",
srcs = glob([
"tools/driver/*.cpp",
"tools/driver/*.h",
- ]),
+ ]) + ["clang_main.cpp"],
copts = [
# Disable stack frame size checks in the driver because
# clang::ensureStackAddressSpace allocates a large array on the stack.
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index 2e9faad29af96..8ffd63b4bd996 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -2594,12 +2594,21 @@ gentbl(
td_srcs = ["include/llvm/Option/OptParser.td"],
)
+template_rule(
+ name = "dsymutil_main",
+ src = "cmake/driver-template.cpp.in",
+ out = "dsymutil_main.cpp",
+ substitutions = {
+ "@TOOL_NAME@": "dsymutil"
+ },
+)
+
cc_binary(
name = "dsymutil",
srcs = glob([
"tools/dsymutil/*.cpp",
"tools/dsymutil/*.h",
- ]),
+ ]) + ["dsymutil_main.cpp"],
copts = llvm_copts,
stamp = 0,
deps = [
@@ -2689,12 +2698,21 @@ cc_binary(
],
)
+template_rule(
+ name = "ar_main",
+ src = "cmake/driver-template.cpp.in",
+ out = "ar_main.cpp",
+ substitutions = {
+ "@TOOL_NAME@": "llvm_ar"
+ },
+)
+
cc_binary(
name = "llvm-ar",
srcs = glob([
"tools/llvm-ar/*.cpp",
"tools/llvm-ar/*.h",
- ]),
+ ]) + ["ar_main.cpp"],
copts = llvm_copts,
stamp = 0,
deps = [
@@ -2882,12 +2900,21 @@ gentbl(
td_srcs = ["include/llvm/Option/OptParser.td"],
)
+template_rule(
+ name = "cxxfilt_main",
+ src = "cmake/driver-template.cpp.in",
+ out = "cxxfilt_main.cpp",
+ substitutions = {
+ "@TOOL_NAME@": "llvm_cxxfilt"
+ },
+)
+
cc_binary(
name = "llvm-cxxfilt",
srcs = glob([
"tools/llvm-cxxfilt/*.cpp",
"tools/llvm-cxxfilt/*.h",
- ]),
+ ]) + ["cxxfilt_main.cpp"],
copts = llvm_copts,
stamp = 0,
deps = [
@@ -3416,12 +3443,22 @@ cc_binary(
],
)
+template_rule(
+ name = "objcopy_main",
+ src = "cmake/driver-template.cpp.in",
+ out = "objcopy_main.cpp",
+ substitutions = {
+ "@TOOL_NAME@": "llvm_objcopy"
+ },
+)
+
+
cc_binary(
name = "llvm-objcopy",
srcs = glob([
"tools/llvm-objcopy/*.cpp",
"tools/llvm-objcopy/*.h",
- ]),
+ ]) + ["objcopy_main.cpp"],
copts = llvm_copts,
stamp = 0,
deps = [
More information about the cfe-commits
mailing list