| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #include "toolchain/driver/lld_subcommand.h"
- #include <string>
- #include "llvm/TargetParser/Host.h"
- #include "llvm/TargetParser/Triple.h"
- #include "toolchain/driver/lld_runner.h"
- namespace Carbon {
- auto LldOptions::Build(CommandLine::CommandBuilder& b) -> void {
- // We want to select a default platform based on the default target. Since
- // that requires some dynamic inspection of the target, do that here.
- std::string default_target = llvm::sys::getDefaultTargetTriple();
- llvm::Triple default_triple(default_target);
- switch (default_triple.getObjectFormat()) {
- case llvm::Triple::MachO:
- platform = Platform::MachO;
- break;
- // We default to the GNU or Unix platform as ELF is a plausible default
- // and LLD doesn't support any generic invocations.
- default:
- case llvm::Triple::ELF:
- platform = Platform::Elf;
- break;
- }
- b.AddOneOfOption(
- {
- .name = "platform",
- .help = R"""(
- Platform linking style to use. The default is selected to match the default
- target's platform.
- )""",
- },
- [&](auto& arg_b) {
- arg_b.SetOneOf(
- {
- arg_b.OneOfValue("elf", Platform::Elf),
- // Some of LLD documentation uses "Unix" or "GNU", so
- // include an alias here.
- arg_b.OneOfValue("gnu", Platform::Elf),
- arg_b.OneOfValue("unix", Platform::Elf),
- arg_b.OneOfValue("macho", Platform::MachO),
- // Darwin is also sometimes used, include it as an alias here.
- arg_b.OneOfValue("darwin", Platform::MachO),
- },
- &platform);
- });
- b.AddStringPositionalArg(
- {
- .name = "ARG",
- .help = R"""(
- Arguments passed to LLD.
- )""",
- },
- [&](auto& arg_b) { arg_b.Append(&args); });
- }
- static constexpr CommandLine::CommandInfo SubcommandInfo = {
- .name = "lld",
- .help = R"""(
- Runs LLD with the provided arguments.
- Note that a specific LLD platform must be selected, and it is actually that
- particular platform's LLD-driver that is run with the arguments. There is no
- generic LLD command line.
- For a given platform, this is equivalent to running that platform's LLD alias
- directly, and provides the full command line interface.
- Use `carbon lld --platform=elf -- ARGS` to separate the `ARGS` forwarded to LLD
- from the flags passed to the Carbon subcommand.
- Note that typically it is better to use a higher level command to link code,
- such as invoking `carbon link` with the relevant flags. However, this subcommand
- supports when you already have a specific invocation using existing command line
- syntaxes, as well as testing and debugging of the underlying tool.
- )""",
- };
- LldSubcommand::LldSubcommand() : DriverSubcommand(SubcommandInfo) {}
- // TODO: This lacks a lot of features from the main driver code. We may need to
- // add more.
- // https://github.com/llvm/llvm-project/blob/main/clang/tools/driver/driver.cpp
- auto LldSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
- LldRunner runner(driver_env.installation, driver_env.vlog_stream);
- // Don't run LLD when fuzzing, as we're not currently in a good position to
- // debug and fix fuzzer-found bugs within LLD.
- if (!DisableFuzzingExternalLibraries(driver_env, "lld")) {
- return {.success = false};
- }
- switch (options_.platform) {
- case LldOptions::Platform::Elf:
- return {.success = runner.ElfLink(options_.args)};
- case LldOptions::Platform::MachO:
- return {.success = runner.MachOLink(options_.args)};
- }
- CARBON_FATAL("Failed to find and run a valid LLD platform link!");
- }
- } // namespace Carbon
|