lld_subcommand.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/driver/lld_subcommand.h"
  5. #include <string>
  6. #include "llvm/TargetParser/Host.h"
  7. #include "llvm/TargetParser/Triple.h"
  8. #include "toolchain/driver/lld_runner.h"
  9. namespace Carbon {
  10. auto LldOptions::Build(CommandLine::CommandBuilder& b) -> void {
  11. // We want to select a default platform based on the default target. Since
  12. // that requires some dynamic inspection of the target, do that here.
  13. std::string default_target = llvm::sys::getDefaultTargetTriple();
  14. llvm::Triple default_triple(default_target);
  15. switch (default_triple.getObjectFormat()) {
  16. case llvm::Triple::MachO:
  17. platform = Platform::MachO;
  18. break;
  19. // We default to the GNU or Unix platform as ELF is a plausible default
  20. // and LLD doesn't support any generic invocations.
  21. default:
  22. case llvm::Triple::ELF:
  23. platform = Platform::Elf;
  24. break;
  25. }
  26. b.AddOneOfOption(
  27. {
  28. .name = "platform",
  29. .help = R"""(
  30. Platform linking style to use. The default is selected to match the default
  31. target's platform.
  32. )""",
  33. },
  34. [&](auto& arg_b) {
  35. arg_b.SetOneOf(
  36. {
  37. arg_b.OneOfValue("elf", Platform::Elf),
  38. // Some of LLD documentation uses "Unix" or "GNU", so
  39. // include an alias here.
  40. arg_b.OneOfValue("gnu", Platform::Elf),
  41. arg_b.OneOfValue("unix", Platform::Elf),
  42. arg_b.OneOfValue("macho", Platform::MachO),
  43. // Darwin is also sometimes used, include it as an alias here.
  44. arg_b.OneOfValue("darwin", Platform::MachO),
  45. },
  46. &platform);
  47. });
  48. b.AddStringPositionalArg(
  49. {
  50. .name = "ARG",
  51. .help = R"""(
  52. Arguments passed to LLD.
  53. )""",
  54. },
  55. [&](auto& arg_b) { arg_b.Append(&args); });
  56. }
  57. static constexpr CommandLine::CommandInfo SubcommandInfo = {
  58. .name = "lld",
  59. .help = R"""(
  60. Runs LLD with the provided arguments.
  61. Note that a specific LLD platform must be selected, and it is actually that
  62. particular platform's LLD-driver that is run with the arguments. There is no
  63. generic LLD command line.
  64. For a given platform, this is equivalent to running that platform's LLD alias
  65. directly, and provides the full command line interface.
  66. Use `carbon lld --platform=elf -- ARGS` to separate the `ARGS` forwarded to LLD
  67. from the flags passed to the Carbon subcommand.
  68. Note that typically it is better to use a higher level command to link code,
  69. such as invoking `carbon link` with the relevant flags. However, this subcommand
  70. supports when you already have a specific invocation using existing command line
  71. syntaxes, as well as testing and debugging of the underlying tool.
  72. )""",
  73. };
  74. LldSubcommand::LldSubcommand() : DriverSubcommand(SubcommandInfo) {}
  75. // TODO: This lacks a lot of features from the main driver code. We may need to
  76. // add more.
  77. // https://github.com/llvm/llvm-project/blob/main/clang/tools/driver/driver.cpp
  78. auto LldSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
  79. LldRunner runner(driver_env.installation, driver_env.vlog_stream);
  80. // Don't run LLD when fuzzing, as we're not currently in a good position to
  81. // debug and fix fuzzer-found bugs within LLD.
  82. if (TestAndDiagnoseIfFuzzingExternalLibraries(driver_env, "lld")) {
  83. return {.success = false};
  84. }
  85. switch (options_.platform) {
  86. case LldOptions::Platform::Elf:
  87. return {.success = runner.ElfLink(options_.args)};
  88. case LldOptions::Platform::MachO:
  89. return {.success = runner.MachOLink(options_.args)};
  90. }
  91. CARBON_FATAL("Failed to find and run a valid LLD platform link!");
  92. }
  93. } // namespace Carbon