[llvm-dev] [RFC] LLVM Busybox Proposal

Leonard Chan via llvm-dev llvm-dev at lists.llvm.org
Mon Jun 21 10:54:38 PDT 2021

Hello all,

When building LLVM tools, including Clang and lld, it's currently possible
to use either static or shared linking for LLVM libraries. The latter can
significantly reduce the size of the toolchain since we aren't duplicating
the same code in every binary, but the dynamic relocations can affect
performance. The former doesn't affect performance but significantly
increases the size of our toolchain.

We would like to implement a support for a third approach which we call,
for a lack of better term, "busybox" feature, where everything is compiled
into a single binary which then dispatches into an appropriate tool
depending on the first command. This approach can significantly reduce the
size by deduplicating all of the shared code without affecting the

In terms of implementation, the build would produce a single binary called
`llvm` and the first command would identify the tool. For example, instead
of invoking `llvm-nm` you'd invoke `llvm nm`. Ideally we would also support
creation of `llvm-nm` symlink which redirects to `llvm` for backwards
This functionality would ideally be implemented as an option in the CMake
build that toolchain vendors can opt into.

The implementation would have to replace `main` function of each tool with
an entrypoint regular function which is registered into a tool registry.
This could be wrapped in a macro for convenience. When the "busybox"
feature is disabled, the macro would expand to a `main` function as before
and redirect to the entrypoint function. When the "busybox" feature is
enabled, it would register the entrypoint function into the registry, which
would be responsible for the dispatching based on the tool name. Ideally,
toolchain maintainers would also be able to control which tools they could
add to the "busybox" binary via CMake build options, so toolchains will
only include the tools they use.

One implementation detail we think will be an issue is merging arguments in
individual tools that use `cl::opt`. `cl::opt` works by maintaining a
global state of flags, but we aren’t confident of what the resulting
behavior will be when merging them together in the dispatching `main`. What
we would like to avoid is having flags used by one specific tool available
on other tools. To address this issue, we would like to migrate all tools
to use `OptTable` which doesn't have this issue and has been the general
direction most tools have been already moving into.

A second issue would be resolving symlinks. For example, llvm-objcopy will
check argv[0] and behave as llvm-strip (ie. use the right flags +
configuration) if it is called via a symlink that “looks like” a strip
tool, but for all other cases it will run under the default objcopy mode.
The “looks like” function is usually an `Is` function copied in multiple
tools that is essentially a substring check: so symlinks like `llvm-strip`,
strip.exe, and `gnu-llvm-strip-10` all result in using the strip “mode”
while all other names use the objcopy mode. To replicate the same behavior,
we will need to take great care in making sure symlinks to the busybox tool
dispatch correctly to the appropriate llvm tool, which might mean exposing
and merging these `Is` functions.

Some open questions:
- People's initial thoughts/opinions?
- Are there existing tools in LLVM that already do this?
- Other implementation details/global states that we would also need to
account for?

- Leonard
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210621/e4bac42b/attachment.html>

More information about the llvm-dev mailing list