llvm.org GIT mirror llvm / 1d815ca
LibDriver, llvm-lib: introduce. llvm-lib is intended to be a lib.exe compatible utility that also understands bitcode. The implementation lives in a library so that lld can use it to implement /lib. Differential Revision: http://reviews.llvm.org/D10297 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239434 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 4 years ago
16 changed file(s) with 271 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
0 //===- llvm/LibDriver/LibDriver.h - lib.exe-compatible driver ---*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines an interface to a lib.exe-compatible driver that also understands
10 // bitcode files. Used by llvm-lib and lld-link2 /lib.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIBDRIVER_LIBDRIVER_H
15 #define LLVM_LIBDRIVER_LIBDRIVER_H
16
17 namespace llvm {
18
19 int libDriverMain(int argc, const char **argv);
20
21 }
22
23 #endif
1818 add_subdirectory(ProfileData)
1919 add_subdirectory(Fuzzer)
2020 add_subdirectory(Passes)
21 add_subdirectory(LibDriver)
1616
1717 [common]
1818 subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine
19 LineEditor Linker IR IRReader LTO MC Object Option Passes ProfileData Support
20 TableGen Target Transforms
19 LibDriver LineEditor Linker IR IRReader LTO MC Object Option Passes ProfileData
20 Support TableGen Target Transforms
2121
2222 [component_0]
2323 type = Group
0 set(LLVM_TARGET_DEFINITIONS Options.td)
1 tablegen(LLVM Options.inc -gen-opt-parser-defs)
2 add_public_tablegen_target(LibOptionsTableGen)
3
4 add_llvm_library(LLVMLibDriver
5 LibDriver.cpp
6 )
7 add_dependencies(LLVMLibDriver LibOptionsTableGen)
0 ;===- ./lib/LibDriver/LLVMBuild.txt ----------------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = LibDriver
20 parent = Libraries
21 required_libraries = Object Option Support
0 //===- LibDriver.cpp - lib.exe-compatible driver --------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines an interface to a lib.exe-compatible driver that also understands
10 // bitcode files. Used by llvm-lib and lld-link2 /lib.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/LibDriver/LibDriver.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Object/ArchiveWriter.h"
17 #include "llvm/Option/Arg.h"
18 #include "llvm/Option/ArgList.h"
19 #include "llvm/Option/Option.h"
20 #include "llvm/Support/CommandLine.h"
21 #include "llvm/Support/Path.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 using namespace llvm;
25
26 namespace {
27
28 enum {
29 OPT_INVALID = 0,
30 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11) OPT_##ID,
31 #include "Options.inc"
32 #undef OPTION
33 };
34
35 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
36 #include "Options.inc"
37 #undef PREFIX
38
39 static const llvm::opt::OptTable::Info infoTable[] = {
40 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
41 { \
42 X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
43 OPT_##GROUP, OPT_##ALIAS, X6 \
44 },
45 #include "Options.inc"
46 #undef OPTION
47 };
48
49 class LibOptTable : public llvm::opt::OptTable {
50 public:
51 LibOptTable() : OptTable(infoTable, llvm::array_lengthof(infoTable), true) {}
52 };
53
54 }
55
56 static std::string getOutputPath(llvm::opt::InputArgList *Args) {
57 if (auto *Arg = Args->getLastArg(OPT_out))
58 return Arg->getValue();
59 for (auto *Arg : Args->filtered(OPT_INPUT)) {
60 if (!StringRef(Arg->getValue()).endswith_lower(".obj"))
61 continue;
62 SmallString<128> Val = StringRef(Arg->getValue());
63 llvm::sys::path::replace_extension(Val, ".lib");
64 return Val.str();
65 }
66 llvm_unreachable("internal error");
67 }
68
69 namespace {
70 // FIXME: Should re-use StringSaver from lld.
71 class StrDupSaver : public cl::StringSaver {
72 std::vector Dups;
73
74 public:
75 ~StrDupSaver() override {
76 for (std::vector::iterator I = Dups.begin(), E = Dups.end(); I != E;
77 ++I) {
78 char *Dup = *I;
79 free(Dup);
80 }
81 }
82 const char *SaveString(const char *Str) override {
83 char *Dup = strdup(Str);
84 Dups.push_back(Dup);
85 return Dup;
86 }
87 };
88 }
89
90 int llvm::libDriverMain(int Argc, const char **Argv) {
91 SmallVector NewArgv(Argv, Argv + Argc);
92 StrDupSaver Saver;
93 cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgv);
94 Argv = &NewArgv[0];
95 Argc = static_cast(NewArgv.size());
96
97 LibOptTable Table;
98 unsigned MissingIndex;
99 unsigned MissingCount;
100 std::unique_ptr Args(
101 Table.ParseArgs(&Argv[1], &Argv[Argc], MissingIndex, MissingCount));
102 if (MissingCount) {
103 llvm::errs() << "missing arg value for \""
104 << Args->getArgString(MissingIndex)
105 << "\", expected " << MissingCount
106 << (MissingCount == 1 ? " argument.\n" : " arguments.\n");
107 return 1;
108 }
109 for (auto *Arg : Args->filtered(OPT_UNKNOWN))
110 llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n";
111
112 if (Args->filtered_begin(OPT_INPUT) == Args->filtered_end()) {
113 llvm::errs() << "no input files.\n";
114 return 1;
115 }
116
117 std::vector Members;
118 for (auto *Arg : Args->filtered(OPT_INPUT))
119 Members.emplace_back(Arg->getValue(),
120 llvm::sys::path::filename(Arg->getValue()));
121
122 std::pair Result = llvm::writeArchive(
123 getOutputPath(Args.get()), Members, /*WriteSymtab=*/true);
124 if (Result.second) {
125 if (Result.first.empty())
126 Result.first = Argv[0];
127 llvm::errs() << Result.first << ": " << Result.second.message() << "\n";
128 return 1;
129 }
130
131 return 0;
132 }
0 ##===- lib/LibDriver/Makefile ------------------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 LEVEL = ../..
10 LIBRARYNAME = LLVMLibDriver
11 BUILD_ARCHIVE := 1
12 BUILT_SOURCES = Options.inc
13 TABLEGEN_INC_FILES_COMMON = 1
14
15 include $(LEVEL)/Makefile.common
16
17 $(ObjDir)/Options.inc.tmp : Options.td $(LLVM_TBLGEN) $(ObjDir)/.dir
18 $(Echo) "Building lib Driver Option tables with tblgen"
19 $(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
0 include "llvm/Option/OptParser.td"
1
2 // lib.exe accepts options starting with either a dash or a slash.
3
4 // Flag that takes no arguments.
5 class F : Flag<["/", "-", "-?"], name>;
6
7 // Flag that takes one argument after ":".
8 class P :
9 Joined<["/", "-", "-?"], name#":">, HelpText;
10
11 def out : P<"out", "Path to file to write output">;
12
13 //==============================================================================
14 // The flags below do nothing. They are defined only for lib.exe compatibility.
15 //==============================================================================
16 def nologo : F<"nologo">;
1111
1212 PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen Target \
1313 ExecutionEngine Linker LTO MC Object Option DebugInfo \
14 IRReader LineEditor ProfileData Passes
14 IRReader LineEditor ProfileData Passes LibDriver
1515
1616 include $(LEVEL)/Makefile.common
3333 llvm-dsymutil
3434 llvm-dwarfdump
3535 llvm-extract
36 llvm-lib
3637 llvm-link
3738 llvm-lto
3839 llvm-mc
2121 RUN: llvm-as %p/Inputs/trivial.ll -o=%t1
2222 RUN: rm -f %t2
2323 RUN: llvm-ar rcs %t2 %t1
24 RUN: llvm-nm %t2 | FileCheck %s -check-prefix BITCODE
25
26 RUN: rm -f %t2
27 RUN: llvm-lib /out:%t2 %t1
28 RUN: llvm-nm %t2 | FileCheck %s -check-prefix BITCODE
29
30 RUN: rm -f %t2
31 RUN: echo /out:%t2 %t1 > %t.rsp
32 RUN: llvm-lib @%t.rsp
2433 RUN: llvm-nm %t2 | FileCheck %s -check-prefix BITCODE
2534
2635 BITCODE: U SomeOtherFunction
235235 r"\bllvm-dwarfdump\b",
236236 r"\bllvm-extract\b",
237237 r"\bllvm-go\b",
238 r"\bllvm-lib\b",
238239 r"\bllvm-link\b",
239240 r"\bllvm-lto\b",
240241 r"\bllvm-mc\b",
0 set(LLVM_LINK_COMPONENTS
11 ${LLVM_TARGETS_TO_BUILD}
22 Core
3 LibDriver
34 Object
45 Support
56 )
2526 add_custom_target(llvm-ranlib ALL DEPENDS ${llvm_ranlib})
2627 set_target_properties(llvm-ranlib PROPERTIES FOLDER Tools)
2728
29 set(llvm_lib "${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-lib${CMAKE_EXECUTABLE_SUFFIX}")
30
31 add_custom_command(OUTPUT ${llvm_lib}
32 COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${llvm_ar_binary}" "${llvm_lib}"
33 DEPENDS llvm-ar)
34
35 add_custom_target(llvm-lib ALL DEPENDS ${llvm_lib})
36 set_target_properties(llvm-lib PROPERTIES FOLDER Tools)
37
2838 install(SCRIPT install_symlink.cmake -DCMAKE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\")
99 LEVEL := ../..
1010 TOOLNAME := llvm-ar
1111 TOOLALIAS = llvm-ranlib
12 LINK_COMPONENTS := all-targets bitreader support object
12 LINK_COMPONENTS := all-targets bitreader libdriver support object
1313
1414 # This tool has no plugins, optimize startup time.
1515 TOOL_NO_EXPORTS := 1
1616
1717 include $(LEVEL)/Makefile.common
18
19 all-local::
20 $(Verb) $(AliasTool) $(notdir $(ToolBuildPath)) $(ToolDir)/llvm-lib$(EXEEXT)
2222 execute_process(
2323 COMMAND "${CMAKE_COMMAND}" -E ${LINK_OR_COPY} "llvm-ar${EXECUTABLE_SUFFIX}" "llvm-ranlib${EXECUTABLE_SUFFIX}"
2424 WORKING_DIRECTORY "${bindir}")
25
26 message("Creating llvm-lib")
27
28 execute_process(
29 COMMAND "${CMAKE_COMMAND}" -E ${LINK_OR_COPY} "llvm-ar${EXECUTABLE_SUFFIX}" "llvm-lib${EXECUTABLE_SUFFIX}"
30 WORKING_DIRECTORY "${bindir}")
1414 #include "llvm/ADT/StringSwitch.h"
1515 #include "llvm/IR/LLVMContext.h"
1616 #include "llvm/IR/Module.h"
17 #include "llvm/LibDriver/LibDriver.h"
1718 #include "llvm/Object/Archive.h"
1819 #include "llvm/Object/ArchiveWriter.h"
1920 #include "llvm/Object/ObjectFile.h"
715716 PrettyStackTraceProgram X(argc, argv);
716717 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
717718
719 llvm::InitializeAllTargetInfos();
720 llvm::InitializeAllTargetMCs();
721 llvm::InitializeAllAsmParsers();
722
723 StringRef Stem = sys::path::stem(ToolName);
724 if (Stem.find("ranlib") == StringRef::npos &&
725 Stem.find("lib") != StringRef::npos)
726 return libDriverMain(argc, const_cast(argv));
727
718728 // Have the command line options parsed and handle things
719729 // like --help and --version.
720730 cl::ParseCommandLineOptions(argc, argv,
722732 " This program archives bitcode files into single libraries\n"
723733 );
724734
725 llvm::InitializeAllTargetInfos();
726 llvm::InitializeAllTargetMCs();
727 llvm::InitializeAllAsmParsers();
728
729 StringRef Stem = sys::path::stem(ToolName);
730735 if (Stem.find("ar") != StringRef::npos)
731736 return ar_main();
732737 if (Stem.find("ranlib") != StringRef::npos)
733738 return ranlib_main();
734 fail("Not ranlib or ar!");
735 }
739 fail("Not ranlib, ar or lib!");
740 }