| // Copyright 2021 The IREE Authors | |
| // | |
| // Licensed 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 | |
| // See llvm-project/lld/tools/lld/lld.cpp. Much of that is scaffolding for | |
| // supporting symlink based lld which auto-detects the flavor. Instead, we | |
| // duplicate the flavor parsing and invoke the backend directly similar to | |
| // what the lldMain() does. | |
| #include <cstdlib> | |
| #include <vector> | |
| #include "iree-compiler-c/Tools.h" | |
| #include "lld/Common/Driver.h" | |
| #include "lld/Common/ErrorHandler.h" | |
| #include "lld/Common/Memory.h" | |
| #include "llvm/ADT/STLExtras.h" | |
| #include "llvm/ADT/SmallVector.h" | |
| #include "llvm/ADT/StringSwitch.h" | |
| #include "llvm/ADT/Triple.h" | |
| #include "llvm/ADT/Twine.h" | |
| #include "llvm/Support/CommandLine.h" | |
| #include "llvm/Support/CrashRecoveryContext.h" | |
| #include "llvm/Support/Host.h" | |
| #include "llvm/Support/InitLLVM.h" | |
| #include "llvm/Support/Path.h" | |
| #include "llvm/Support/PluginLoader.h" | |
| #include "llvm/Support/Process.h" | |
| using namespace lld; | |
| using namespace llvm; | |
| using namespace llvm::sys; | |
| enum Flavor { | |
| Invalid, | |
| Gnu, // -flavor gnu | |
| WinLink, // -flavor link | |
| Darwin, // -flavor darwin | |
| Wasm, // -flavor wasm | |
| }; | |
| [[noreturn]] static void die(const Twine &s) { | |
| llvm::errs() << s << "\n"; | |
| exit(1); | |
| } | |
| static Flavor getFlavor(StringRef s) { | |
| return StringSwitch<Flavor>(s) | |
| .CasesLower("ld", "ld.lld", "gnu", Gnu) | |
| .CasesLower("wasm", "ld-wasm", Wasm) | |
| .CaseLower("link", WinLink) | |
| .CasesLower("ld64", "ld64.lld", "darwin", "darwinnew", | |
| "ld64.lld.darwinnew", Darwin) | |
| .Default(Invalid); | |
| } | |
| static Flavor parseFlavor(std::vector<const char *> &v) { | |
| // Parse -flavor option. | |
| if (v.size() > 1 && v[1] == StringRef("-flavor")) { | |
| if (v.size() <= 2) die("missing arg value for '-flavor'"); | |
| Flavor f = getFlavor(v[2]); | |
| if (f == Invalid) die("Unknown flavor: " + StringRef(v[2])); | |
| v.erase(v.begin() + 1, v.begin() + 3); | |
| return f; | |
| } | |
| die("Expected -flavor <gnu|link|darwin|wasm>"); | |
| } | |
| int ireeCompilerRunLldMain(int argc, char **argv) { | |
| InitLLVM x(argc, argv); | |
| sys::Process::UseANSIEscapeCodes(true); | |
| bool exitEarly = true; | |
| llvm::raw_ostream &stdoutOS = llvm::outs(); | |
| llvm::raw_ostream &stderrOS = llvm::errs(); | |
| std::vector<const char *> args(argv, argv + argc); | |
| switch (parseFlavor(args)) { | |
| case Gnu: | |
| return !elf::link(args, exitEarly, stdoutOS, stderrOS); | |
| case WinLink: | |
| return !coff::link(args, exitEarly, stdoutOS, stderrOS); | |
| case Darwin: | |
| return !macho::link(args, exitEarly, stdoutOS, stderrOS); | |
| case Wasm: | |
| return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS); | |
| default: | |
| die("lld is a generic driver.\n" | |
| "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld" | |
| " (WebAssembly) instead"); | |
| } | |
| } |