Description
I'd like to propose a re-organization of llvm-libc Bazel macro to better support use case of creating an actual "llvm-libc library" (for now - in overlay mode) that the users can pass as a dependency to the binaries they are building with Bazel. It's based on the downstream configuration that we have successfully deployed internally (in Google, using Blaze).
Currently, if one wants to use llvm-libc functions in their binaries, they have two options:
- depend on the collection of individual
libc_function
targets. - group together
libc_function
targets to produce a single prebuilt static library (or a few static libraries) as an initial step, and depend on / link in those prebuilts later.
The superior alternative is to create the way to build all llvm-libc sources a vendor / user would like to ship into a single cc_library
target, that will be used as a dependency of C++ binaries/libraries, and built on-demand every time. This will:
- ensure that for "release" configuration, all llvm-libc code is built with a consistent set of compiler flags (in
libc_release_copts
). Notably, it's not the case currently. - build llvm-libc on-demand, for specific microarchitecture (which can be problematic when using prebuilts).
- allow to build llvm-libc as a dynamic library when required or convenient.
We can achieve this with relatively small changes to the existing Bazel structure, if we update the implementation of existing macro. Here's how things would change:
Target type | Example | Current macros | Current behavior | New macros | New behavior |
---|---|---|---|---|---|
test library | //libc/test/UnitTest:test_logger | libc_support_library | creates a cc_library target | libc_test_library | creates a testonly cc_library target |
internal libc component | //libc:__support_fputil_hypot | libc_support_library | creates a cc_library target | libc_support_library | creates a cc_library target for testing and filegroups for all sources and headers required to build this component |
public libc function | //libc:scanf | libc_function | creates an internal cc_library target for testing, and an external cc_library target for production code | libc_function | creates a cc_library target for testing and filegroups for all sources and headers required to build this function |
With proper filegroup naming, we can additionally ensure the invariants we'd like to preserve in llvm-libc, such as:
- only test targets can depend on
libc_test_library
libc_function
can't be used as a dependency oflibc_support_library
or anotherlibc_function
to preserve the llvm-libc modular design.
We would also add libc_release_library
macro that would accept:
- the list of
libc_function
s to include in the library - additional configuration options (e.g. which functions should be marked as weak)
- (in the future) the list of public headers to generate / expose
This macro would produce a cc_library
target that would obtain the list of source files to compile from filegroups generated by libc_support_library
and libc_function
above.
The user can then define their own libc_release_library
target (or several of such targets) to only include the functions / headers they care about. All these functions will be built on-demand, with both llvm-libc specific flags (such as -fvisibility=hidden
and higher optimization levels) and the overall build flags (e.g. for targeting specific CPU / microarchitecture).