From 82e4c3a8af4c71fbd2717e69453145682f73c571 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 18 Feb 2026 05:39:23 -0800 Subject: [PATCH] Add response file expansion to the busybox and improve `-Xcarbon` (#6750) When the response file contains the subcommand itself, or when there are `-Xcarbon` flags within the response file that we need to re-organize, we need to hoist the expansion into the busybox itself. I've left the response file expansion in the `ClangRunner` so that library users can still use them, including in the VFS of the runner. It's also useful to handle `-Xcarbon`-style flags even when using subcommands rather than a symlink to the busybox: build systems often have a facility to append flags, but appending doesn't let us inject flags easily into the `carbon` driver itself. So this PR moves the `-Xcarbon` reorganization to happen in all cases, and to insert them before the first subcommand or positional parameter. When teaching Bazel to link by running `carbon link ...` commands, this lets us do things like `bazel build --linkopt=-Xcarbon=-v` to enable verbose logging. I've not added a test here as we don't really have much testing of the busybox. I can move the current symlinks test to be more of an integration test of the busybox logic if desired, but would be a somewhat larger change and maybe worth separating out. This will end up tested in the Bazel example in a subsequent PR that starts using it in the installed crosstool configuration. --- toolchain/install/BUILD | 1 + toolchain/install/busybox_main.cpp | 54 +++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/toolchain/install/BUILD b/toolchain/install/BUILD index 9b8054279507..ceeb1f4aae08 100644 --- a/toolchain/install/BUILD +++ b/toolchain/install/BUILD @@ -64,6 +64,7 @@ cc_binary( "//toolchain/base:install_paths", "//toolchain/base:llvm_tools_def", "//toolchain/driver", + "@llvm-project//clang:driver", "@llvm-project//llvm:Support", ], ) diff --git a/toolchain/install/busybox_main.cpp b/toolchain/install/busybox_main.cpp index 2812e3907f95..4a3ab42b3bd5 100644 --- a/toolchain/install/busybox_main.cpp +++ b/toolchain/install/busybox_main.cpp @@ -7,12 +7,15 @@ #include #include +#include "clang/Driver/Driver.h" #include "common/bazel_working_dir.h" #include "common/error.h" #include "common/init_llvm.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Error.h" #include "llvm/Support/LLVMDriver.h" #include "toolchain/base/install_paths.h" #include "toolchain/driver/driver.h" @@ -46,9 +49,17 @@ static auto Main(int argc, char** argv) -> ErrorOr { auto fs = llvm::vfs::getRealFileSystem(); - llvm::SmallVector raw_args; + llvm::SmallVector raw_args; raw_args.append(argv + 1, argv + argc); + // Expand any response files in the arguments. + llvm::BumpPtrAllocator alloc; + if (llvm::Error error = clang::driver::expandResponseFiles( + raw_args, busybox_info.mode && *busybox_info.mode == "clang-cl", + alloc, fs.get())) { + return Error(llvm::toString(std::move(error))); + } + llvm::SmallVector args; args.reserve(argc + 1); if (busybox_info.mode) { @@ -85,23 +96,36 @@ static auto Main(int argc, char** argv) -> ErrorOr { .Default({*busybox_info.mode, "--"}); - // When we're operating as a busybox, we also support a special command line - // syntax for passing flags to the base Carbon driver as - // `-Xcarbon=--some-carbon-flag=some-value`. Extract any arguments of that - // form, remove the prefix, and prepend them to the arg list prior to the - // busybox subcommand arguments. - llvm::erase_if(raw_args, [&args](llvm::StringRef raw_arg) { - if (raw_arg.consume_front("-Xcarbon=")) { - args.push_back(raw_arg); - return true; - } - return false; - }); - // And now append the subcommand args. args.append(subcommand_args); } - args.append(raw_args); + llvm::append_range(args, raw_args); + + // We also support a special command line syntax for passing flags to the base + // Carbon driver as `-Xcarbon=--some-carbon-flag=some-value`. This is + // important when build systems only allow appending custom user flags to + // allow them to be used for driver. + // + // Extract any arguments of that form, remove the prefix, and insert them to + // the argument list just before the first positional parameter or subcommand. + // This let's them come after any other flags to the base driver and override + // them if needed. + llvm::SmallVector extra_driver_args; + llvm::erase_if(args, [&extra_driver_args](llvm::StringRef arg) { + if (arg.consume_front("-Xcarbon=")) { + extra_driver_args.push_back(arg); + return true; + } + return false; + }); + if (!extra_driver_args.empty()) { + auto* subcommand_it = llvm::find_if(args, [](llvm::StringRef arg) { + // Flags start with `-`, unless it is the string `-` or `--`. + return !arg.starts_with("-") || arg == "-" || arg == "--"; + }); + args.insert(subcommand_it, extra_driver_args.begin(), + extra_driver_args.end()); + } Driver driver(fs, &install_paths, stdin, &llvm::outs(), &llvm::errs(), /*fuzzing=*/false, /*enable_leaking=*/true);