<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
span.EmailStyle19
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-CA" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">Hello Leonard,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">That is a very interesting idea! This will particularly favor Windows where the LLVM bin/ folder is huge (3.5 GiB) since we don’t have working symlinks out-of-box. This is also going towards the
 direction that we are pursuing, having Clang and LLD together into an embedded application as suggested by llvm-buildozer [1], however we’re also considering the multi-threading aspect. We took a different route for now, which is loading the existing executables
 as shared libraries inside our application, but our concern was less the binary size on disk, and more about runtime performance (building time).<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">Regarding migrating every option to `OptTable`, are you suggesting removing `cl::opt` and `CommandLineParser` altogether? I can count 3,597 instances of `cl::opt` in the whole monorepo. This can
 be a tedious task even with automation, since it would need some level of classification into the appropriate .td file. What would be the approach for the migration? To alleviate the issue of having `cl::opt`s cross the tool domain, we could temporarily auto-generate
 a dictionary of `cl::opt`s available for each tool? That could be a quick intermediary step, while waiting for a complete migration.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">Once other issue I can see is symbols clashing at link time. Having everything in the same executable requires internal ABI compatibly throughout, ie. compiling with the same #defines and linking
 with the same (system) libraries. I’m wondering if there was a analysis done in that regards? But maybe that is not an issue.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">Best,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">Alex.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US">[1]</span> <span style="mso-fareast-language:EN-US">
<a href="https://reviews.llvm.org/D86351">https://reviews.llvm.org/D86351</a><o:p></o:p></span></p>
<p class="MsoNormal"><span style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="FR">De :</span></b><span lang="FR"> llvm-dev <llvm-dev-bounces@lists.llvm.org>
<b>De la part de</b> Leonard Chan via llvm-dev<br>
<b>Envoyé :</b> June 21, 2021 1:55 PM<br>
<b>À :</b> llvm-dev <llvm-dev@lists.llvm.org><br>
<b>Objet :</b> [llvm-dev] [RFC] LLVM Busybox Proposal<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span lang="FR-CA"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal">Hello all,<br>
<br>
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.<br>
<br>
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 performance.<br>
<br>
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 compatibility.<br>
This functionality would ideally be implemented as an option in the CMake build that toolchain vendors can opt into.<br>
<br>
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.<br>
<br>
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.<br>
<br>
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.<br>
<br>
Some open questions:<br>
- People's initial thoughts/opinions?<br>
- Are there existing tools in LLVM that already do this?<br>
- Other implementation details/global states that we would also need to account for?<br>
<br>
- Leonard<o:p></o:p></p>
</div>
</div>
</body>
</html>