blob: a2778729ac1b7fe2cc3b43d2a74180e0ae538837 [file] [log] [blame]
// 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");
}
}