[llvm-branch-commits] [llvm] [libc][bazel] Allow building with -DLIBC_FULL_BUILD (PR #218992)

Jackson Stogel via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Aug 26 20:16:20 PDT 2026


https://github.com/jtstogel updated https://github.com/llvm/llvm-project/pull/218992

>From 3a64a0f902181738140f265f799cc40f60c8fff8 Mon Sep 17 00:00:00 2001
From: jtstogel <jtstogel at gmail.com>
Date: Wed, 15 Jul 2026 22:43:27 -0700
Subject: [PATCH] [libc][bazel] Allow building with -DLIBC_FULL_BUILD

This PR defines a flag `-- at llvm-project//libc:build_mode` that configures LLVM-libc to build with full-build flags. This is only compatible with clang at the moment, since it relies on the `-nostdlibinc` flag.
---
 .../llvm-project-overlay/libc/BUILD.bazel     | 27 +++++++++---
 .../libc/libc_build_rules.bzl                 | 43 +++++++++++++++++--
 .../libc/libc_configure_options.bzl           | 25 +++++++++--
 3 files changed, 82 insertions(+), 13 deletions(-)

diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index b423273402676..9e39d279f253c 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -125,6 +125,27 @@ config_setting(
     flag_values = {":modular_format": "enable"},
 )
 
+# A flag to control whether LLVM libc is built in overlay or full build mode.
+string_flag(
+    name = "build_mode",
+    build_setting_default = "overlay",
+    values = [
+        "overlay",  # Build over the system libc
+        "full",  # Build as a standalone libc
+    ],
+)
+
+config_setting(
+    name = "full_build",
+    flag_values = {":build_mode": "full"},
+)
+
+config_setting(
+    name = "full_build_linux",
+    constraint_values = ["@platforms//os:linux"],
+    flag_values = {":build_mode": "full"},
+)
+
 ########################### Header Generation ##################################
 
 py_binary(
@@ -283,16 +304,12 @@ cc_library(
     hdrs = [header.target_name for header in LLVM_LIBC_HEADERS],
     includes = ["staging/include"],
     textual_hdrs = ["staging/" + f for f in STATIC_AND_CONDITIONAL_HEADERS],
-    deps = [
-        ":copy_llvm_libc_static_headers",
-        ":copy_modular_format_header",
-    ],
 )
 
 # Textual versions of the static headers. These are taken from the source tree
 # and are separate from the generated headers above. They are used for
 # testing purposes.
-libc_support_library(
+cc_library(
     name = "public_headers_deps",
     textual_hdrs = STATIC_AND_CONDITIONAL_HEADERS,
 )
diff --git a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
index da454e84843e5..a8021776c1bc6 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
@@ -18,7 +18,40 @@ def libc_common_copts():
         "-I" + libc_include_path,
         "-I" + paths.join(libc_include_path, "include"),
         "-DLIBC_NAMESPACE=" + LIBC_NAMESPACE,
-    ]
+    ] + select({
+        "//libc:full_build": [
+            "-DLIBC_FULL_BUILD",
+            "-ffreestanding",
+            "-fno-asynchronous-unwind-tables",
+            "-fno-exceptions",
+            "-fno-rtti",
+            "-fno-unwind-tables",
+            "-nostdinc++",
+            "-nostdlib",
+            "-nostdlib++",
+            # This is a clang-only option. To support gcc, we should use
+            # -nostdinc and pass in compiler builtin headers separately.
+            "-nostdlibinc",
+        ],
+        "//conditions:default": [],
+    })
+
+def libc_common_deps():
+    return select({
+        "//libc:full_build": [
+            # This is too broad. Really, we should have every public header
+            # accessible as a distinct cc_library target. However, the glob
+            # here is convenient for keeping Bazel rules in sync with CMake.
+            "//libc:public_headers",
+            "//libc:public_headers_deps",
+        ],
+        "//conditions:default": [],
+    }) + select({
+        "//libc:full_build_linux": [
+            "@linux_uapi//:linux_uapi_headers",
+        ],
+        "//conditions:default": [],
+    })
 
 def libc_release_copts():
     copts = [
@@ -42,11 +75,12 @@ def libc_release_copts():
     })
     return copts + platform_copts
 
-def _libc_library(name, **kwargs):
+def _libc_library(name, deps = [], **kwargs):
     """Internal macro to serve as a base for all other libc library rules.
 
     Args:
       name: Target name.
+      deps: cc_library deps.
       **kwargs: All other attributes relevant for the cc_library rule.
     """
 
@@ -57,6 +91,7 @@ def _libc_library(name, **kwargs):
         name = name,
         copts = libc_common_copts(),
         local_defines = LIBC_CONFIGURE_OPTIONS,
+        deps = deps + libc_common_deps(),
         linkstatic = 1,
         **kwargs
     )
@@ -207,7 +242,7 @@ def libc_release_library(
         local_defines = weak_attributes + LIBC_CONFIGURE_OPTIONS,
         deps = [
             ":" + name + "_textual_hdr_library",
-        ],
+        ] + libc_common_deps(),
         **kwargs
     )
 
@@ -241,7 +276,7 @@ def libc_header_library(name, hdrs, deps = [], **kwargs):
         # We put _hdr_deps in srcs, as they are not a part of this cc_library
         # interface, but instead are used to implement shared headers.
         srcs = [":" + name + "_hdr_deps"],
-        deps = [":" + name + "_textual_hdr_library"],
+        deps = [":" + name + "_textual_hdr_library"] + libc_common_deps(),
         # copts don't really matter, since it's a header-only library, but we
         # need proper -I flags for header validation, which are specified in
         # libc_common_copts().
diff --git a/utils/bazel/llvm-project-overlay/libc/libc_configure_options.bzl b/utils/bazel/llvm-project-overlay/libc/libc_configure_options.bzl
index 89eba49b7289a..96ed1d200df93 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_configure_options.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_configure_options.bzl
@@ -12,7 +12,7 @@ is discoverable with the following command:
 """
 
 # This list of definitions is used to customize LLVM libc.
-LIBC_CONFIGURE_OPTIONS = [
+LIBC_CONFIGURE_COMMON_OPTIONS = [
     # Documentation in libc/docs/dev/printf_behavior.rst
     # "LIBC_COPT_FLOAT_TO_STR_NO_SPECIALIZE_LD",
     # "LIBC_COPT_FLOAT_TO_STR_NO_TABLE",
@@ -39,7 +39,6 @@ LIBC_CONFIGURE_OPTIONS = [
     # "LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS",
     # "LIBC_COPT_SCANF_DISABLE_FLOAT",
     # "LIBC_COPT_SCANF_DISABLE_INDEX_MODE",
-    "LIBC_COPT_STDIO_USE_SYSTEM_FILE",
     "LIBC_COPT_STRING_LENGTH_IMPL=clang_vector",
     "LIBC_COPT_FIND_FIRST_CHARACTER_IMPL=word",
     # "LIBC_COPT_STRTOFLOAT_DISABLE_CLINGER_FAST_PATH",
@@ -52,9 +51,27 @@ LIBC_CONFIGURE_OPTIONS = [
     # Documentation in libc/docs/configure.rst
     "LIBC_THREAD_MODE=LIBC_THREAD_MODE_PLATFORM",
 
+    # Documentation in libc/src/__support/time/monotonicity.h
+    "LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY",
+]
+
+LIBC_CONFIGURE_OVERLAY_OPTIONS = [
+    # Documentation in libc/docs/dev/printf_behavior.rst
+    "LIBC_COPT_STDIO_USE_SYSTEM_FILE",
+
     # Documentation in libc/src/__support/libc_errno.h
     "LIBC_ERRNO_MODE=LIBC_ERRNO_MODE_SYSTEM_INLINE",
+]
 
-    # Documentation in libc/src/__support/time/monotonicity.h
-    "LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY",
+LIBC_CONFIGURE_FULL_BUILD_OPTIONS = [
+    # Documentation in libc/src/__support/libc_errno.h
+    "LIBC_ERRNO_MODE=LIBC_ERRNO_MODE_THREAD_LOCAL",
+
+    # Defined for targets which support threads.
+    "LIBC_COPT_SUPPORT_THREADS",
 ]
+
+LIBC_CONFIGURE_OPTIONS = LIBC_CONFIGURE_COMMON_OPTIONS + select({
+    "//libc:full_build": LIBC_CONFIGURE_FULL_BUILD_OPTIONS,
+    "//conditions:default": LIBC_CONFIGURE_OVERLAY_OPTIONS,
+})



More information about the llvm-branch-commits mailing list