Skip to content

[libc][bazel] Reorganize Bazel rules to build "release" version of llvm-libc as a single cc_library #130327

@vonosmas

Description

@vonosmas

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 of libc_support_library or another libc_function to preserve the llvm-libc modular design.

We would also add libc_release_library macro that would accept:

  • the list of libc_functions 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).

Metadata

Metadata

Assignees

Labels

bazel"Peripheral" support tier build system: utils/bazellibc

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions