<div dir="ltr">Hi all,<div><br></div><div style>We plan to add some auto-linking support for Mach-O, and need a scheme for encoding this information in the LLVM IR. We would like the same scheme to be able to support Microsoft's #pragma comment(lib,...) and #pragma comment(library, ...) features eventually.</div>
<div style><br></div><div style>The current proposal is as follows:</div><div style><br></div><div style>--</div><div style><br></div><div style><div>#1. Extend module-level metadata flags (llvm.module.flags) to support two new behaviors:</div>
<div><br></div><div>llvm::Module::Append - The value must be a list. Module flags with equivalent unique IDs and this behavior will be appended in the order that they are linked.</div><div><br></div><div>llvm::Module::AppendUnique - The value must be a list. As with llvm::Module::Append, module flags with equivalent unique IDs are appended in the order that they are linked. However, identical MDNodes will only appear once in the list (at the earliest seen position).</div>
<div><br></div><div style>#2. Define a new "known" module level flag metadata "Linker Options" which is a list of lists of metadata strings corresponding to linker options. This metadata flag will use the llvm::Module::AppendUnique option.</div>
<div><br></div><div>The options are expected to be linker specific (thus target specific), we make no attempt to encode the intent of the options at the IR level. The frontend is responsible for selecting appropriate options based on the target.</div>
<div><br></div><div>The module level linker will only unique option lists, any diagnosis of otherwise redundant or conflicting options is expected to be handled by the linker.</div><div><br></div><div style>Example metadata for a module which is expected to link against libz and the Cocoa framework::</div>
<div style><br></div><div style><div> !0 = metadata !{ i32 6, "Linker Options", </div><div> metadata !{</div><div> !metadata { metadata !"-lz" },</div><div> !metadata { metadata !"-framework", metadata !"Cocoa" } } }<br>
</div><div> !llvm.module.flags = !{ !0 }</div><div><br></div></div><div>--</div><div><br></div><div style>We have debated whether or not there is value in adopting a more strict schema for the metadata (i.e., declare intent more explicitly by encoding things like static library vs dynamic library vs framework library instead of using target-specific linker options). However, as we have no expectation that the compiler will want to inspect this data, it seems like this adds complexity (and reduces flexibility) for no benefit. It does, however, have the downside that the frontend needs to participate (and have target linker knowledge) in order to use the appropriate options.</div>
<div style><br></div><div style>Other points of discussion:</div><div style><br></div><div style>#1. On Mach-O, the linker will expect and enforce that each list of options corresponds to a single library. This will not be enforced (nor is it enforceable) at the IR level, and other targets wouldn't have this restriction (Visual Studio supports inclusion of some arbitrary flags).</div>
<div style><br></div><div style>#2. On Microsoft, #pragma comment(linker, ...) will map naturally to this format. How #pragma comment(lib, ...) gets handled will probably depend on the details of how this is encoded in the COFF object files, which I am not yet familiar with.</div>
<div style><br></div><div style>#3. We make no attempt to encode ordering information amongst the options, which limits the utility for linking against static libraries. The current expectation is that this feature be used for system libraries where the order of the options is not important. A schema that would allow encoding dependencies amongst libraries to be auto-linked would be substantially more complicated and is outside the scope of this proposal.</div>
<div style><br></div><div style>Please let me know if you have an opinion on this works, particularly if you want to chime in on how this might interact with ELF or COFF.<br></div></div><div style><br></div><div style> - Daniel</div>
</div>