Files
carbon-lang/toolchain/driver/build_runtimes_subcommand.cpp
T
Chandler Carruth 65f35ad98e Add support for forcing a rebuild of runtimes (#6537)
This is useful during development, testing, and will also be useful for
a more bazel-integrated build step.

Also clean up the path management when creating runtimes:

- Teach the main runtimes code to handle making a relative path absolute
- Separate out methods for _creating_ a runtimes tree vs. opening an
existing one. Teach the creation path to create intervening directories
as needed. This provides a more useful and less surprising set of
behaviors.

Last but not least, also clean up a bunch of comments in the runtimes
cache code to talk generically about components -- these APIs are no
longer specific to the resource directory.
2025-12-31 01:59:19 +00:00

120 lines
4.1 KiB
C++

// 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/build_runtimes_subcommand.h"
#include "llvm/TargetParser/Triple.h"
#include "toolchain/driver/clang_runner.h"
#include "toolchain/driver/clang_runtimes.h"
namespace Carbon {
auto BuildRuntimesOptions::Build(CommandLine::CommandBuilder& b) -> void {
b.AddStringOption(
{
.name = "output-directory",
.value_name = "DIR",
.help = R"""(
The directory to populate with runtime libraries suitable for the selected code
generation options.
)""",
},
[&](auto& arg_b) { arg_b.Set(&directory); });
b.AddFlag(
{
.name = "force",
.help = R"""(
Force re-creating the provided output path from scratch
This will **remove** the provided output path and re-create it from scratch.
)""",
},
[&](CommandLine::FlagBuilder& arg_b) { arg_b.Set(&force); });
codegen_options.Build(b);
}
static constexpr CommandLine::CommandInfo SubcommandInfo = {
.name = "build-runtimes",
.help = R"""(
Build Carbon's runtime libraries.
This subcommand builds Carbon's runtime libraries for a particular code
generation target, either in their default location or a specified one.
Running this command directly is not necessary as Carbon will build and cache
runtimes as needed when linking, but building them directly can aid in
debugging issues or allow them to be prebuilt, possibly with customized code
generation flags, and used explicitly when linking.
)""",
};
BuildRuntimesSubcommand::BuildRuntimesSubcommand()
: DriverSubcommand(SubcommandInfo) {}
auto BuildRuntimesSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
// Don't run Clang when fuzzing, it is known to not be reliable under fuzzing
// due to many unfixed issues.
if (TestAndDiagnoseIfFuzzingExternalLibraries(driver_env, "clang")) {
return {.success = false};
}
// For diagnosing filesystem or other errors when building runtimes.
CARBON_DIAGNOSTIC(FailureBuildingRuntimes, Error,
"failure building runtimes: {0}", std::string);
auto run_result = RunInternal(driver_env);
if (!run_result.ok()) {
driver_env.emitter.Emit(FailureBuildingRuntimes,
run_result.error().message());
return {.success = false};
}
llvm::outs() << "Built runtimes: " << *run_result << "\n";
return {.success = true};
}
auto BuildRuntimesSubcommand::RunInternal(DriverEnv& driver_env)
-> ErrorOr<std::filesystem::path> {
ClangRunner runner(driver_env.installation, driver_env.fs,
driver_env.vlog_stream);
Runtimes::Cache::Features features = {
.target = options_.codegen_options.target.str()};
bool is_cache = options_.directory.empty();
std::filesystem::path output_path = options_.directory.str();
CARBON_ASSIGN_OR_RETURN(
auto runtimes, is_cache
? driver_env.runtimes_cache.Lookup(features)
: Runtimes::Make(output_path, driver_env.vlog_stream));
if (options_.force) {
// Remove existing runtimes to force a rebuild.
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::ClangResourceDir));
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::LibUnwind));
CARBON_RETURN_IF_ERROR(runtimes.Remove(Runtimes::Libcxx));
}
ClangResourceDirBuilder resource_dir_builder(&runner, driver_env.thread_pool,
llvm::Triple(features.target),
&runtimes);
ClangArchiveRuntimesBuilder<Runtimes::LibUnwind> lib_unwind_builder(
&runner, driver_env.thread_pool, llvm::Triple(features.target),
&runtimes);
ClangArchiveRuntimesBuilder<Runtimes::Libcxx> libcxx_builder(
&runner, driver_env.thread_pool, llvm::Triple(features.target),
&runtimes);
CARBON_RETURN_IF_ERROR(std::move(resource_dir_builder).Wait());
CARBON_RETURN_IF_ERROR(std::move(lib_unwind_builder).Wait());
CARBON_RETURN_IF_ERROR(std::move(libcxx_builder).Wait());
return runtimes.base_path();
}
} // namespace Carbon