diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake --- a/clang/cmake/modules/AddClang.cmake +++ b/clang/cmake/modules/AddClang.cmake @@ -184,5 +184,8 @@ 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 --- a/clang/tools/driver/CMakeLists.txt +++ b/clang/tools/driver/CMakeLists.txt @@ -31,6 +31,7 @@ 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 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -327,7 +327,7 @@ 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 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -269,6 +269,8 @@ 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 --- /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@_main(int argc, char **argv); + +int main(int argc, char **argv) { return @TOOL_NAME@_main(argc, argv); } diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -859,7 +859,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 "$") # 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 --- a/llvm/lib/Support/Path.cpp +++ b/llvm/lib/Support/Path.cpp @@ -1202,9 +1202,18 @@ #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 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -194,7 +194,7 @@ /// 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 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -130,7 +130,7 @@ const file_t kInvalidFile = INVALID_HANDLE_VALUE; -std::string getMainExecutable(const char *argv0, void *MainExecAddr) { +std::string getMainExecutableImpl(const char *argv0, void *MainExecAddr) { SmallVector 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 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -21,6 +21,7 @@ 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 @@ 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 --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -139,6 +139,7 @@ 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 @@ 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 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -59,6 +59,7 @@ 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 --- /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 --- /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 --- /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 --- a/llvm/tools/CMakeLists.txt +++ b/llvm/tools/CMakeLists.txt @@ -53,3 +53,9 @@ 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 --- a/llvm/tools/dsymutil/CMakeLists.txt +++ b/llvm/tools/dsymutil/CMakeLists.txt @@ -32,6 +32,8 @@ DEPENDS intrinsics_gen ${tablegen_deps} + DsymutilTableGen + GENERATE_DRIVER ) if(APPLE) diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp --- a/llvm/tools/dsymutil/dsymutil.cpp +++ b/llvm/tools/dsymutil/dsymutil.cpp @@ -521,7 +521,7 @@ 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 --- a/llvm/tools/llvm-ar/CMakeLists.txt +++ b/llvm/tools/llvm-ar/CMakeLists.txt @@ -15,6 +15,7 @@ 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 --- a/llvm/tools/llvm-ar/llvm-ar.cpp +++ b/llvm/tools/llvm-ar/llvm-ar.cpp @@ -1265,7 +1265,7 @@ 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 --- a/llvm/tools/llvm-cxxfilt/CMakeLists.txt +++ b/llvm/tools/llvm-cxxfilt/CMakeLists.txt @@ -13,6 +13,7 @@ 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 --- a/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp +++ b/llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp @@ -140,7 +140,7 @@ 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 --- /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 --- /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 --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 --- a/llvm/tools/llvm-objcopy/CMakeLists.txt +++ b/llvm/tools/llvm-objcopy/CMakeLists.txt @@ -30,6 +30,7 @@ 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 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -223,7 +223,7 @@ 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 --- 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 @@ ], ) +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 --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -2594,12 +2594,21 @@ 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 @@ ], ) +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 @@ 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 @@ ], ) +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 = [