This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
abrachet marked 2 inline comments as done.
Closed by commit rGf06abbb39380: LLVM Driver Multicall tool (authored by beanz, 
committed by abrachet).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109977/new/

https://reviews.llvm.org/D109977

Files:
  clang/cmake/modules/AddClang.cmake
  clang/tools/driver/CMakeLists.txt
  clang/tools/driver/driver.cpp
  llvm/CMakeLists.txt
  llvm/cmake/driver-template.cpp.in
  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/test/tools/llvm-driver/help-passthrough.test
  llvm/test/tools/llvm-driver/help.test
  llvm/test/tools/llvm-driver/symlink-call.test
  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-driver/CMakeLists.txt
  llvm/tools/llvm-driver/llvm-driver.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

Index: utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
===================================================================
--- utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ 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 = [
Index: utils/bazel/llvm-project-overlay/clang/BUILD.bazel
===================================================================
--- utils/bazel/llvm-project-overlay/clang/BUILD.bazel
+++ 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.
Index: llvm/tools/llvm-objcopy/llvm-objcopy.cpp
===================================================================
--- llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ 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];
 
Index: llvm/tools/llvm-objcopy/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-objcopy/CMakeLists.txt
+++ 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)
Index: llvm/tools/llvm-driver/llvm-driver.cpp
===================================================================
--- /dev/null
+++ 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);
+}
Index: llvm/tools/llvm-driver/CMakeLists.txt
===================================================================
--- /dev/null
+++ 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)
Index: llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
===================================================================
--- llvm/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
+++ 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);
Index: llvm/tools/llvm-cxxfilt/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-cxxfilt/CMakeLists.txt
+++ llvm/tools/llvm-cxxfilt/CMakeLists.txt
@@ -13,6 +13,7 @@
 
   DEPENDS
   CxxfiltOptsTableGen
+  GENERATE_DRIVER
   )
 
 if(LLVM_INSTALL_BINUTILS_SYMLINKS)
Index: llvm/tools/llvm-ar/llvm-ar.cpp
===================================================================
--- llvm/tools/llvm-ar/llvm-ar.cpp
+++ 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];
 
Index: llvm/tools/llvm-ar/CMakeLists.txt
===================================================================
--- llvm/tools/llvm-ar/CMakeLists.txt
+++ llvm/tools/llvm-ar/CMakeLists.txt
@@ -15,6 +15,7 @@
 
   DEPENDS
   intrinsics_gen
+  GENERATE_DRIVER
   )
 
 add_llvm_tool_symlink(llvm-ranlib llvm-ar)
Index: llvm/tools/dsymutil/dsymutil.cpp
===================================================================
--- llvm/tools/dsymutil/dsymutil.cpp
+++ 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.
Index: llvm/tools/dsymutil/CMakeLists.txt
===================================================================
--- llvm/tools/dsymutil/CMakeLists.txt
+++ llvm/tools/dsymutil/CMakeLists.txt
@@ -32,6 +32,8 @@
   DEPENDS
   intrinsics_gen
   ${tablegen_deps}
+  DsymutilTableGen
+  GENERATE_DRIVER
   )
 
 if(APPLE)
Index: llvm/tools/CMakeLists.txt
===================================================================
--- llvm/tools/CMakeLists.txt
+++ 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()
Index: llvm/test/tools/llvm-driver/symlink-call.test
===================================================================
--- /dev/null
+++ 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
Index: llvm/test/tools/llvm-driver/help.test
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-driver/help.test
@@ -0,0 +1,3 @@
+# REQUIRES: llvm-driver
+# RUN: %llvm --help | FileCheck %s
+# CHECK: USAGE: llvm [subcommand]
Index: llvm/test/tools/llvm-driver/help-passthrough.test
===================================================================
--- /dev/null
+++ llvm/test/tools/llvm-driver/help-passthrough.test
@@ -0,0 +1,3 @@
+# REQUIRES: llvm-driver
+# RUN: %llvm cxxfilt --help | FileCheck %s 
+# CHECK: USAGE: cxxfilt
Index: llvm/test/lit.site.cfg.py.in
===================================================================
--- llvm/test/lit.site.cfg.py.in
+++ 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)
Index: llvm/test/lit.cfg.py
===================================================================
--- llvm/test/lit.cfg.py
+++ 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
 
 
Index: llvm/test/CMakeLists.txt
===================================================================
--- llvm/test/CMakeLists.txt
+++ 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)
Index: llvm/lib/Support/Windows/Path.inc
===================================================================
--- llvm/lib/Support/Windows/Path.inc
+++ 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<wchar_t, MAX_PATH> PathName;
   PathName.resize_for_overwrite(PathName.capacity());
   DWORD Size = ::GetModuleFileNameW(NULL, PathName.data(), PathName.size());
Index: llvm/lib/Support/Unix/Path.inc
===================================================================
--- llvm/lib/Support/Unix/Path.inc
+++ 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
Index: llvm/lib/Support/Path.cpp
===================================================================
--- llvm/lib/Support/Path.cpp
+++ 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); }
Index: llvm/cmake/modules/AddLLVM.cmake
===================================================================
--- llvm/cmake/modules/AddLLVM.cmake
+++ 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 "$<TARGET_FILE:${target}>")
 
   # This got a bit gross... For multi-configuration generators the target
Index: llvm/cmake/driver-template.cpp.in
===================================================================
--- /dev/null
+++ 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); }
Index: llvm/CMakeLists.txt
===================================================================
--- llvm/CMakeLists.txt
+++ 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/";)
Index: clang/tools/driver/driver.cpp
===================================================================
--- clang/tools/driver/driver.cpp
+++ 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
Index: clang/tools/driver/CMakeLists.txt
===================================================================
--- clang/tools/driver/CMakeLists.txt
+++ clang/tools/driver/CMakeLists.txt
@@ -31,6 +31,7 @@
   DEPENDS
   intrinsics_gen
   ${support_plugins}
+  GENERATE_DRIVER
   )
 
 clang_target_link_libraries(clang
Index: clang/cmake/modules/AddClang.cmake
===================================================================
--- clang/cmake/modules/AddClang.cmake
+++ 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()
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to