mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-29 22:02:42 +01:00
This removes the separately built and installed LLD binary. The symlinks used by Clang when directly invoking LLD now point back to the main `carbon-busybox` binary and dispatch through the newly added subcommand. With this change we're down to shipping a single busybox binary in the toolchain, removing duplicate installed copies of LLD and all its LLVM dependencies. =] The LLD subcommand works a bit differently from the `clang` subcommand because the CLI for LLD is specific to which platform flavor of linker is being invoked. As part of this, I've extracted some of the common functionality in the Clang runner into a base class that can be re-used. I expect to use this again in a follow-up change to add subcommands to run other LLVM tools. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
74 lines
2.7 KiB
C++
74 lines
2.7 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/tool_runner_base.h"
|
|
|
|
#include <memory>
|
|
|
|
#include "common/vlog.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
|
|
namespace Carbon {
|
|
|
|
ToolRunnerBase::ToolRunnerBase(const InstallPaths* install_paths,
|
|
llvm::raw_ostream* vlog_stream)
|
|
: installation_(install_paths), vlog_stream_(vlog_stream) {}
|
|
|
|
auto ToolRunnerBase::BuildCStrArgs(llvm::StringRef tool_name,
|
|
llvm::StringRef tool_path,
|
|
std::optional<llvm::StringRef> verbose_flag,
|
|
llvm::ArrayRef<llvm::StringRef> args,
|
|
llvm::OwningArrayRef<char>& cstr_arg_storage)
|
|
-> llvm::SmallVector<const char*, 64> {
|
|
// TODO: Maybe handle response file expansion similar to the Clang CLI?
|
|
|
|
// If we have a verbose logging stream, and that stream is the same as
|
|
// `llvm::errs`, then add the `-v` flag so that the driver also prints verbose
|
|
// information.
|
|
bool inject_v_arg = verbose_flag.has_value() && vlog_stream_ == &llvm::errs();
|
|
std::array<llvm::StringRef, 1> v_arg_storage;
|
|
llvm::ArrayRef<llvm::StringRef> maybe_v_arg;
|
|
if (inject_v_arg) {
|
|
v_arg_storage[0] = *verbose_flag;
|
|
maybe_v_arg = v_arg_storage;
|
|
}
|
|
|
|
CARBON_VLOG("Running {} driver with arguments:\n", tool_name);
|
|
|
|
// Render the arguments into null-terminated C-strings. Command lines can get
|
|
// quite long in build systems so this tries to minimize the memory allocation
|
|
// overhead.
|
|
|
|
// Provide the wrapped tool path as the synthetic `argv[0]`.
|
|
std::array<llvm::StringRef, 1> exe_arg = {tool_path};
|
|
auto args_range =
|
|
llvm::concat<const llvm::StringRef>(exe_arg, maybe_v_arg, args);
|
|
int total_size = 0;
|
|
for (llvm::StringRef arg : args_range) {
|
|
// Accumulate both the string size and a null terminator byte.
|
|
total_size += arg.size() + 1;
|
|
}
|
|
|
|
// Allocate one chunk of storage for the actual C-strings and a vector of
|
|
// pointers into the storage.
|
|
cstr_arg_storage = llvm::OwningArrayRef<char>(total_size);
|
|
llvm::SmallVector<const char*, 64> cstr_args;
|
|
cstr_args.reserve(args.size() + inject_v_arg + 1);
|
|
for (ssize_t i = 0; llvm::StringRef arg : args_range) {
|
|
cstr_args.push_back(&cstr_arg_storage[i]);
|
|
memcpy(&cstr_arg_storage[i], arg.data(), arg.size());
|
|
i += arg.size();
|
|
cstr_arg_storage[i] = '\0';
|
|
++i;
|
|
}
|
|
for (const char* cstr_arg : llvm::ArrayRef(cstr_args)) {
|
|
CARBON_VLOG(" '{0}'\n", cstr_arg);
|
|
}
|
|
|
|
return cstr_args;
|
|
}
|
|
|
|
} // namespace Carbon
|