build_runtimes_subcommand.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/build_runtimes_subcommand.h"
  5. #include <variant>
  6. #include "llvm/TargetParser/Triple.h"
  7. #include "toolchain/driver/clang_runner.h"
  8. namespace Carbon {
  9. auto BuildRuntimesOptions::Build(CommandLine::CommandBuilder& b) -> void {
  10. b.AddStringOption(
  11. {
  12. .name = "output-directory",
  13. .value_name = "DIR",
  14. .help = R"""(
  15. The directory to populate with runtime libraries suitable for the selected code
  16. generation options.
  17. )""",
  18. },
  19. [&](auto& arg_b) { arg_b.Set(&directory); });
  20. codegen_options.Build(b);
  21. }
  22. static constexpr CommandLine::CommandInfo SubcommandInfo = {
  23. .name = "build-runtimes",
  24. .help = R"""(
  25. Build Carbon's runtime libraries.
  26. This subcommand builds Carbon's runtime libraries for a particular code
  27. generation target, either in their default location or a specified one.
  28. Running this command directly is not necessary as Carbon will build and cache
  29. runtimes as needed when linking, but building them directly can aid in
  30. debugging issues or allow them to be prebuilt, possibly with customized code
  31. generation flags, and used explicitly when linking.
  32. )""",
  33. };
  34. BuildRuntimesSubcommand::BuildRuntimesSubcommand()
  35. : DriverSubcommand(SubcommandInfo) {}
  36. auto BuildRuntimesSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
  37. // Don't run Clang when fuzzing, it is known to not be reliable under fuzzing
  38. // due to many unfixed issues.
  39. if (TestAndDiagnoseIfFuzzingExternalLibraries(driver_env, "clang")) {
  40. return {.success = false};
  41. }
  42. // For diagnosing filesystem or other errors when building runtimes.
  43. CARBON_DIAGNOSTIC(FailureBuildingRuntimes, Error,
  44. "failure building runtimes: {0}", std::string);
  45. auto run_result = RunInternal(driver_env);
  46. if (!run_result.ok()) {
  47. driver_env.emitter.Emit(FailureBuildingRuntimes,
  48. run_result.error().message());
  49. return {.success = false};
  50. }
  51. llvm::outs() << "Built runtimes: " << *run_result << "\n";
  52. return {.success = true};
  53. }
  54. auto BuildRuntimesSubcommand::RunInternal(DriverEnv& driver_env)
  55. -> ErrorOr<std::filesystem::path> {
  56. ClangRunner runner(driver_env.installation, &driver_env.runtimes_cache,
  57. driver_env.fs, driver_env.vlog_stream);
  58. Runtimes::Cache::Features features = {
  59. .target = options_.codegen_options.target.str()};
  60. bool is_cache = options_.directory.empty();
  61. std::filesystem::path explicit_output_path = options_.directory.str();
  62. if (!is_cache) {
  63. auto access_result = Filesystem::Cwd().Access(explicit_output_path);
  64. if (access_result.ok()) {
  65. return Error("output directory already exists");
  66. }
  67. if (!access_result.error().no_entity()) {
  68. return std::move(access_result).error();
  69. }
  70. }
  71. CARBON_ASSIGN_OR_RETURN(
  72. auto runtimes,
  73. is_cache ? driver_env.runtimes_cache.Lookup(features)
  74. : Runtimes::Make(explicit_output_path, driver_env.vlog_stream));
  75. CARBON_ASSIGN_OR_RETURN(auto tmp_dir, Filesystem::MakeTmpDir());
  76. return runner.BuildTargetResourceDir(features, runtimes, tmp_dir.abs_path());
  77. }
  78. } // namespace Carbon