[libc-commits] [libc] [llvm] [libc][bazel] Add generation for public headers (PR #184889)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Fri Mar 20 15:03:38 PDT 2026


https://github.com/michaelrj-google updated https://github.com/llvm/llvm-project/pull/184889

>From 5e358c07d806e17aa2723ab4f7a77c9d0347bd07 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Thu, 5 Mar 2026 18:39:51 +0000
Subject: [PATCH 1/5] [libc][bazel] Add generation for public headers

Previously there was a single rule for stdbit, this PR adds generated
header targets for the rest of the linux headers. It also adds a cc_library
for all of the public headers which also includes the types and macros
headers.
---
 .../llvm-project-overlay/libc/BUILD.bazel     | 530 ++++++++++++++++++
 .../libc/libc_build_rules.bzl                 |  18 +
 2 files changed, 548 insertions(+)

diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 87d1d88e971bf..c3d772e6da36b 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -5,9 +5,11 @@
 # LLVM libc project.
 load("@bazel_skylib//lib:selects.bzl", "selects")
 load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
+load("@rules_cc//cc:defs.bzl", "cc_library")
 load("@rules_python//python:defs.bzl", "py_binary")
 load(
     ":libc_build_rules.bzl",
+    "libc_copy_header",
     "libc_function",
     "libc_generated_header",
     "libc_header_library",
@@ -100,6 +102,534 @@ libc_generated_header(
     yaml_template = "include/stdbit.yaml",
 )
 
+libc_generated_header(
+    name = "include_stdio_h",
+    hdr = "staging/include/stdio.h",
+    other_srcs = ["include/stdio.h.def"],
+    yaml_template = "include/stdio.yaml",
+)
+
+libc_generated_header(
+    name = "include_string_h",
+    hdr = "staging/include/string.h",
+    yaml_template = "include/string.yaml",
+)
+
+libc_generated_header(
+    name = "include_stdlib_h",
+    hdr = "staging/include/stdlib.h",
+    other_srcs = [
+        "include/stdlib.h.def",
+        "include/stdlib-malloc.yaml",
+    ],
+    yaml_template = "include/stdlib.yaml",
+)
+
+libc_generated_header(
+    name = "include_malloc_h",
+    hdr = "staging/include/malloc.h",
+    other_srcs = ["include/stdlib-malloc.yaml"],
+    yaml_template = "include/malloc.yaml",
+)
+
+libc_generated_header(
+    name = "include_signal_h",
+    hdr = "staging/include/signal.h",
+    other_srcs = ["include/signal.h.def"],
+    yaml_template = "include/signal.yaml",
+)
+
+libc_generated_header(
+    name = "include_stdint_h",
+    hdr = "staging/include/stdint.h",
+    other_srcs = ["include/stdint.h.def"],
+    yaml_template = "include/stdint.yaml",
+)
+
+libc_generated_header(
+    name = "include_limits_h",
+    hdr = "staging/include/limits.h",
+    other_srcs = ["include/limits.h.def"],
+    yaml_template = "include/limits.yaml",
+)
+
+libc_generated_header(
+    name = "include_float_h",
+    hdr = "staging/include/float.h",
+    other_srcs = ["include/float.h.def"],
+    yaml_template = "include/float.yaml",
+)
+
+libc_generated_header(
+    name = "include_ctype_h",
+    hdr = "staging/include/ctype.h",
+    other_srcs = [],
+    yaml_template = "include/ctype.yaml",
+)
+
+libc_generated_header(
+    name = "include_fenv_h",
+    hdr = "staging/include/fenv.h",
+    other_srcs = [],
+    yaml_template = "include/fenv.yaml",
+)
+
+libc_generated_header(
+    name = "include_inttypes_h",
+    hdr = "staging/include/inttypes.h",
+    other_srcs = ["include/inttypes.h.def"],
+    yaml_template = "include/inttypes.yaml",
+)
+
+genrule(
+    name = "hdr_elf_proxy_h",
+    srcs = ["include/elf.yaml"],
+    outs = ["hdr/elf_proxy.h"],
+    cmd = "$(location //libc:hdrgen) $(location include/elf.yaml) -o $@ --proxy",
+    tools = ["//libc:hdrgen"],
+)
+
+libc_generated_header(
+    name = "include_assert_h",
+    hdr = "staging/include/assert.h",
+    other_srcs = ["include/assert.h.def"],
+    yaml_template = "include/assert.yaml",
+)
+
+libc_generated_header(
+    name = "include_math_h",
+    hdr = "staging/include/math.h",
+    other_srcs = ["include/math.h.def"],
+    yaml_template = "include/math.yaml",
+)
+
+libc_generated_header(
+    name = "include_fcntl_h",
+    hdr = "staging/include/fcntl.h",
+    other_srcs = ["include/fcntl.h.def"],
+    yaml_template = "include/fcntl.yaml",
+)
+
+libc_generated_header(
+    name = "include_unistd_h",
+    hdr = "staging/include/unistd.h",
+    other_srcs = ["include/unistd.h.def"],
+    yaml_template = "include/unistd.yaml",
+)
+
+libc_generated_header(
+    name = "include_time_h",
+    hdr = "staging/include/time.h",
+    other_srcs = ["include/time.h.def"],
+    yaml_template = "include/time.yaml",
+)
+
+libc_generated_header(
+    name = "include_errno_h",
+    hdr = "staging/include/errno.h",
+    other_srcs = ["include/errno.h.def"],
+    yaml_template = "include/errno.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_wait_h",
+    hdr = "staging/include/sys/wait.h",
+    other_srcs = ["include/sys/wait.h.def"],
+    yaml_template = "include/sys/wait.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_mman_h",
+    hdr = "staging/include/sys/mman.h",
+    other_srcs = ["include/sys/mman.h.def"],
+    yaml_template = "include/sys/mman.yaml",
+)
+
+libc_generated_header(
+    name = "include_poll_h",
+    hdr = "staging/include/poll.h",
+    other_srcs = ["include/poll.h.def"],
+    yaml_template = "include/poll.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_resource_h",
+    hdr = "staging/include/sys/resource.h",
+    other_srcs = ["include/sys/resource.h.def"],
+    yaml_template = "include/sys/resource.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_socket_h",
+    hdr = "staging/include/sys/socket.h",
+    other_srcs = ["include/sys/socket.h.def"],
+    yaml_template = "include/sys/socket.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_stat_h",
+    hdr = "staging/include/sys/stat.h",
+    other_srcs = ["include/sys/stat.h.def"],
+    yaml_template = "include/sys/stat.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_syscall_h",
+    hdr = "staging/include/sys/syscall.h",
+    other_srcs = ["include/sys/syscall.h.def"],
+    yaml_template = "include/sys/syscall.yaml",
+)
+
+libc_generated_header(
+    name = "include_dirent_h",
+    hdr = "staging/include/dirent.h",
+    yaml_template = "include/dirent.yaml",
+)
+
+libc_generated_header(
+    name = "include_dlfcn_h",
+    hdr = "staging/include/dlfcn.h",
+    yaml_template = "include/dlfcn.yaml",
+)
+
+libc_generated_header(
+    name = "include_endian_h",
+    hdr = "staging/include/endian.h",
+    other_srcs = ["include/endian.h.def"],
+    yaml_template = "include/endian.yaml",
+)
+
+libc_generated_header(
+    name = "include_features_h",
+    hdr = "staging/include/features.h",
+    other_srcs = ["include/features.h.def"],
+    yaml_template = "include/features.yaml",
+)
+
+libc_generated_header(
+    name = "include_stdfix_h",
+    hdr = "staging/include/stdfix.h",
+    other_srcs = ["include/stdfix.h.def"],
+    yaml_template = "include/stdfix.yaml",
+)
+
+libc_generated_header(
+    name = "include_sysexits_h",
+    hdr = "staging/include/sysexits.h",
+    other_srcs = ["include/sysexits.h.def"],
+    yaml_template = "include/sysexits.yaml",
+)
+
+libc_generated_header(
+    name = "include_arpa_inet_h",
+    hdr = "staging/include/arpa/inet.h",
+    other_srcs = ["include/arpa/inet.h.def"],
+    yaml_template = "include/arpa/inet.yaml",
+)
+
+libc_generated_header(
+    name = "include_netinet_in_h",
+    hdr = "staging/include/netinet/in.h",
+    other_srcs = ["include/netinet/in.h.def"],
+    yaml_template = "include/netinet/in.yaml",
+)
+
+libc_generated_header(
+    name = "include_complex_h",
+    hdr = "staging/include/complex.h",
+    other_srcs = ["include/complex.h.def"],
+    yaml_template = "include/complex.yaml",
+)
+
+libc_generated_header(
+    name = "include_setjmp_h",
+    hdr = "staging/include/setjmp.h",
+    yaml_template = "include/setjmp.yaml",
+)
+
+libc_generated_header(
+    name = "include_strings_h",
+    hdr = "staging/include/strings.h",
+    yaml_template = "include/strings.yaml",
+)
+
+libc_generated_header(
+    name = "include_search_h",
+    hdr = "staging/include/search.h",
+    yaml_template = "include/search.yaml",
+)
+
+libc_generated_header(
+    name = "include_threads_h",
+    hdr = "staging/include/threads.h",
+    yaml_template = "include/threads.yaml",
+)
+
+libc_generated_header(
+    name = "include_stdckdint_h",
+    hdr = "staging/include/stdckdint.h",
+    other_srcs = ["include/stdckdint.h.def"],
+    yaml_template = "include/stdckdint.yaml",
+)
+
+libc_generated_header(
+    name = "include_pthread_h",
+    hdr = "staging/include/pthread.h",
+    yaml_template = "include/pthread.yaml",
+)
+
+libc_generated_header(
+    name = "include_sched_h",
+    hdr = "staging/include/sched.h",
+    other_srcs = ["include/sched.h.def"],
+    yaml_template = "include/sched.yaml",
+)
+
+libc_generated_header(
+    name = "include_spawn_h",
+    hdr = "staging/include/spawn.h",
+    yaml_template = "include/spawn.yaml",
+)
+
+libc_generated_header(
+    name = "include_link_h",
+    hdr = "staging/include/link.h",
+    other_srcs = ["include/link.h.def"],
+    yaml_template = "include/link.yaml",
+)
+
+libc_generated_header(
+    name = "include_elf_h",
+    hdr = "staging/include/elf.h",
+    other_srcs = ["include/elf.h.def"],
+    yaml_template = "include/elf.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_auxv_h",
+    hdr = "staging/include/sys/auxv.h",
+    other_srcs = ["include/sys/auxv.h.def"],
+    yaml_template = "include/sys/auxv.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_epoll_h",
+    hdr = "staging/include/sys/epoll.h",
+    other_srcs = ["include/sys/epoll.h.def"],
+    yaml_template = "include/sys/epoll.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_ioctl_h",
+    hdr = "staging/include/sys/ioctl.h",
+    other_srcs = ["include/sys/ioctl.h.def"],
+    yaml_template = "include/sys/ioctl.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_ipc_h",
+    hdr = "staging/include/sys/ipc.h",
+    yaml_template = "include/sys/ipc.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_prctl_h",
+    hdr = "staging/include/sys/prctl.h",
+    other_srcs = ["include/sys/prctl.h.def"],
+    yaml_template = "include/sys/prctl.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_random_h",
+    hdr = "staging/include/sys/random.h",
+    other_srcs = ["include/sys/random.h.def"],
+    yaml_template = "include/sys/random.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_select_h",
+    hdr = "staging/include/sys/select.h",
+    other_srcs = ["include/sys/select.h.def"],
+    yaml_template = "include/sys/select.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_statvfs_h",
+    hdr = "staging/include/sys/statvfs.h",
+    yaml_template = "include/sys/statvfs.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_time_h",
+    hdr = "staging/include/sys/time.h",
+    other_srcs = ["include/sys/time.h.def"],
+    yaml_template = "include/sys/time.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_types_h",
+    hdr = "staging/include/sys/types.h",
+    other_srcs = ["include/sys/types.h.def"],
+    yaml_template = "include/sys/types.yaml",
+)
+
+libc_generated_header(
+    name = "include_sys_utsname_h",
+    hdr = "staging/include/sys/utsname.h",
+    yaml_template = "include/sys/utsname.yaml",
+)
+
+libc_generated_header(
+    name = "include_termios_h",
+    hdr = "staging/include/termios.h",
+    other_srcs = ["include/termios.h.def"],
+    yaml_template = "include/termios.yaml",
+)
+
+libc_generated_header(
+    name = "include_uchar_h",
+    hdr = "staging/include/uchar.h",
+    yaml_template = "include/uchar.yaml",
+)
+
+libc_generated_header(
+    name = "include_wchar_h",
+    hdr = "staging/include/wchar.h",
+    other_srcs = ["include/wchar.h.def"],
+    yaml_template = "include/wchar.yaml",
+)
+
+libc_generated_header(
+    name = "include_wctype_h",
+    hdr = "staging/include/wctype.h",
+    yaml_template = "include/wctype.yaml",
+)
+
+libc_generated_header(
+    name = "include_locale_h",
+    hdr = "staging/include/locale.h",
+    other_srcs = ["include/locale.h.def"],
+    yaml_template = "include/locale.yaml",
+)
+
+libc_generated_header(
+    name = "include_nl_types_h",
+    hdr = "staging/include/nl_types.h",
+    yaml_template = "include/nl_types.yaml",
+)
+
+# Static headers that need to be in staging/include
+libc_copy_header(
+    name = "copy_llvm_libc_common_h",
+    src = "include/__llvm-libc-common.h",
+    out = "staging/include/__llvm-libc-common.h",
+)
+
+TYPE_HEADERS = glob(["include/llvm-libc-types/**/*.h"])
+
+genrule(
+    name = "copy_llvm_libc_types",
+    srcs = TYPE_HEADERS,
+    outs = ["staging/include/" + f.replace("include/", "") for f in TYPE_HEADERS],
+    cmd = " && ".join([
+        "cp $(location %s) $(location %s)" % (
+            src,
+            "staging/include/" + src.replace("include/", ""),
+        )
+        for src in TYPE_HEADERS
+    ]),
+)
+
+MACRO_HEADERS = glob(["include/llvm-libc-macros/**/*.h"])
+
+genrule(
+    name = "copy_llvm_libc_macros",
+    srcs = MACRO_HEADERS,
+    outs = ["staging/include/" + f.replace("include/", "") for f in MACRO_HEADERS],
+    cmd = " && ".join([
+        "cp $(location %s) $(location %s)" % (
+            src,
+            "staging/include/" + src.replace("include/", ""),
+        )
+        for src in MACRO_HEADERS
+    ]),
+)
+
+cc_library(
+    name = "public_headers",
+    hdrs = [
+        ":copy_llvm_libc_common_h",
+        ":include_arpa_inet_h",
+        ":include_assert_h",
+        ":include_complex_h",
+        ":include_ctype_h",
+        ":include_dirent_h",
+        ":include_dlfcn_h",
+        ":include_elf_h",
+        ":include_endian_h",
+        ":include_errno_h",
+        ":include_fcntl_h",
+        ":include_features_h",
+        ":include_fenv_h",
+        ":include_float_h",
+        ":include_inttypes_h",
+        ":include_limits_h",
+        ":include_link_h",
+        ":include_locale_h",
+        ":include_malloc_h",
+        ":include_math_h",
+        ":include_netinet_in_h",
+        ":include_nl_types_h",
+        ":include_poll_h",
+        ":include_pthread_h",
+        ":include_sched_h",
+        ":include_search_h",
+        ":include_setjmp_h",
+        ":include_signal_h",
+        ":include_spawn_h",
+        ":include_stdbit_h",
+        ":include_stdckdint_h",
+        ":include_stdfix_h",
+        ":include_stdint_h",
+        ":include_stdio_h",
+        ":include_stdlib_h",
+        ":include_string_h",
+        ":include_strings_h",
+        ":include_sys_auxv_h",
+        ":include_sys_epoll_h",
+        ":include_sys_ioctl_h",
+        ":include_sys_ipc_h",
+        ":include_sys_mman_h",
+        ":include_sys_prctl_h",
+        ":include_sys_random_h",
+        ":include_sys_resource_h",
+        ":include_sys_select_h",
+        ":include_sys_socket_h",
+        ":include_sys_stat_h",
+        ":include_sys_statvfs_h",
+        ":include_sys_syscall_h",
+        ":include_sys_time_h",
+        ":include_sys_types_h",
+        ":include_sys_utsname_h",
+        ":include_sys_wait_h",
+        ":include_sysexits_h",
+        ":include_termios_h",
+        ":include_threads_h",
+        ":include_time_h",
+        ":include_uchar_h",
+        ":include_unistd_h",
+        ":include_wchar_h",
+        ":include_wctype_h",
+    ] + [
+        ":copy_llvm_libc_macros",
+        ":copy_llvm_libc_types",
+    ],
+    features = ["-parse_headers"],  # Needed due to stdbit-macros.h.
+    includes = ["staging/include"],
+    visibility = ["//visibility:public"],
+    deps = [":public_headers_deps"],
+)
+
 # Library containing all headers that can be transitively included by generated llvm-libc
 # public headers (or by the unit tests).
 libc_support_library(
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 3f9918df76f6b..58560b6068a18 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
@@ -285,6 +285,24 @@ def libc_generated_header(name, hdr, yaml_template, other_srcs = []):
         tools = [hdrgen],
     )
 
+def libc_copy_header(name, src, out):
+    """Copies a header file to the staging directory.
+
+    Args:
+      name: Name of the target.
+      src: Path of the source header file.
+      out: Path of the output header file (relative to staging/include/).
+    """
+    if not out.startswith("staging/include/"):
+        fail("Output header must be in staging/include/")
+
+    native.genrule(
+        name = name,
+        srcs = [src],
+        outs = [out],
+        cmd = "cp $< $@",
+    )
+
 def libc_math_function(
         name,
         additional_deps = None):

>From 5b1407dbdab8e569789cd732713d2258ca46eb9e Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Tue, 17 Mar 2026 21:42:59 +0000
Subject: [PATCH 2/5] cleanup header rules, overall simplify

---
 .../llvm-project-overlay/libc/BUILD.bazel     | 597 +++---------------
 .../libc/libc_build_rules.bzl                 |   5 +-
 2 files changed, 104 insertions(+), 498 deletions(-)

diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index c3d772e6da36b..90f4dbde09003 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -95,26 +95,95 @@ py_binary(
     deps = ["@pyyaml//:yaml"],
 )
 
-libc_generated_header(
-    name = "include_stdbit_h",
-    hdr = "staging/include/stdbit.h",
-    other_srcs = ["include/stdbit.h.def"],
-    yaml_template = "include/stdbit.yaml",
-)
+# the list of simple headers that only have name, hdr, other_srcs and
+# yaml_template. They also follow the pattern that the generated header is in
+# staging/include/<header>.h and the yaml template is in include/<header>.yaml.
+gen_headers_with_templates = [
+    "arpa/inet",
+    "assert",
+    "complex",
+    "elf",
+    "endian",
+    "errno",
+    "fcntl",
+    "features",
+    "float",
+    "inttypes",
+    "limits",
+    "link",
+    "locale",
+    "math",
+    "netinet/in",
+    "poll",
+    "sched",
+    "signal",
+    "stdbit",
+    "stdckdint",
+    "stdfix",
+    "stdint",
+    "stdio",
+    "sysexits",
+    "sys/auxv",
+    "sys/epoll",
+    "sys/ioctl",
+    "sys/mman",
+    "sys/prctl",
+    "sys/random",
+    "sys/resource",
+    "sys/select",
+    "sys/socket",
+    "sys/stat",
+    "sys/syscall",
+    "sys/time",
+    "sys/types",
+    "sys/wait",
+    "termios",
+    "time",
+    "unistd",
+    "wchar",
+]
 
-libc_generated_header(
-    name = "include_stdio_h",
-    hdr = "staging/include/stdio.h",
-    other_srcs = ["include/stdio.h.def"],
-    yaml_template = "include/stdio.yaml",
-)
+# same as above but they don't have a .h.def file listed.
+gen_headers_with_no_h_def = [
+    "ctype",
+    "dirent",
+    "dlfcn",
+    "fenv",
+    "nl_types",
+    "pthread",
+    "search",
+    "setjmp",
+    "spawn",
+    "string",
+    "strings",
+    "sys/ipc",
+    "sys/statvfs",
+    "sys/utsname",
+    "threads",
+    "uchar",
+    "wctype",
+]
 
-libc_generated_header(
-    name = "include_string_h",
-    hdr = "staging/include/string.h",
-    yaml_template = "include/string.yaml",
-)
+[
+    libc_generated_header(
+        name = "include_{}_h".format(header.replace("/", "_")),
+        hdr = "staging/include/{}.h".format(header),
+        other_srcs = ["include/{}.h.def".format(header)],
+        yaml_template = "include/{}.yaml".format(header),
+    )
+    for header in gen_headers_with_templates
+]
 
+[
+    libc_generated_header(
+        name = "include_{}_h".format(header.replace("/", "_")),
+        hdr = "staging/include/{}.h".format(header),
+        yaml_template = "include/{}.yaml".format(header),
+    )
+    for header in gen_headers_with_no_h_def
+]
+
+# headers which don't fit the standard patterns.
 libc_generated_header(
     name = "include_stdlib_h",
     hdr = "staging/include/stdlib.h",
@@ -132,514 +201,50 @@ libc_generated_header(
     yaml_template = "include/malloc.yaml",
 )
 
+# needed for startup and VDSO
 libc_generated_header(
-    name = "include_signal_h",
-    hdr = "staging/include/signal.h",
-    other_srcs = ["include/signal.h.def"],
-    yaml_template = "include/signal.yaml",
-)
-
-libc_generated_header(
-    name = "include_stdint_h",
-    hdr = "staging/include/stdint.h",
-    other_srcs = ["include/stdint.h.def"],
-    yaml_template = "include/stdint.yaml",
-)
-
-libc_generated_header(
-    name = "include_limits_h",
-    hdr = "staging/include/limits.h",
-    other_srcs = ["include/limits.h.def"],
-    yaml_template = "include/limits.yaml",
-)
-
-libc_generated_header(
-    name = "include_float_h",
-    hdr = "staging/include/float.h",
-    other_srcs = ["include/float.h.def"],
-    yaml_template = "include/float.yaml",
-)
-
-libc_generated_header(
-    name = "include_ctype_h",
-    hdr = "staging/include/ctype.h",
-    other_srcs = [],
-    yaml_template = "include/ctype.yaml",
-)
-
-libc_generated_header(
-    name = "include_fenv_h",
-    hdr = "staging/include/fenv.h",
-    other_srcs = [],
-    yaml_template = "include/fenv.yaml",
-)
-
-libc_generated_header(
-    name = "include_inttypes_h",
-    hdr = "staging/include/inttypes.h",
-    other_srcs = ["include/inttypes.h.def"],
-    yaml_template = "include/inttypes.yaml",
-)
-
-genrule(
     name = "hdr_elf_proxy_h",
-    srcs = ["include/elf.yaml"],
-    outs = ["hdr/elf_proxy.h"],
-    cmd = "$(location //libc:hdrgen) $(location include/elf.yaml) -o $@ --proxy",
-    tools = ["//libc:hdrgen"],
-)
-
-libc_generated_header(
-    name = "include_assert_h",
-    hdr = "staging/include/assert.h",
-    other_srcs = ["include/assert.h.def"],
-    yaml_template = "include/assert.yaml",
-)
-
-libc_generated_header(
-    name = "include_math_h",
-    hdr = "staging/include/math.h",
-    other_srcs = ["include/math.h.def"],
-    yaml_template = "include/math.yaml",
-)
-
-libc_generated_header(
-    name = "include_fcntl_h",
-    hdr = "staging/include/fcntl.h",
-    other_srcs = ["include/fcntl.h.def"],
-    yaml_template = "include/fcntl.yaml",
-)
-
-libc_generated_header(
-    name = "include_unistd_h",
-    hdr = "staging/include/unistd.h",
-    other_srcs = ["include/unistd.h.def"],
-    yaml_template = "include/unistd.yaml",
-)
-
-libc_generated_header(
-    name = "include_time_h",
-    hdr = "staging/include/time.h",
-    other_srcs = ["include/time.h.def"],
-    yaml_template = "include/time.yaml",
-)
-
-libc_generated_header(
-    name = "include_errno_h",
-    hdr = "staging/include/errno.h",
-    other_srcs = ["include/errno.h.def"],
-    yaml_template = "include/errno.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_wait_h",
-    hdr = "staging/include/sys/wait.h",
-    other_srcs = ["include/sys/wait.h.def"],
-    yaml_template = "include/sys/wait.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_mman_h",
-    hdr = "staging/include/sys/mman.h",
-    other_srcs = ["include/sys/mman.h.def"],
-    yaml_template = "include/sys/mman.yaml",
-)
-
-libc_generated_header(
-    name = "include_poll_h",
-    hdr = "staging/include/poll.h",
-    other_srcs = ["include/poll.h.def"],
-    yaml_template = "include/poll.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_resource_h",
-    hdr = "staging/include/sys/resource.h",
-    other_srcs = ["include/sys/resource.h.def"],
-    yaml_template = "include/sys/resource.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_socket_h",
-    hdr = "staging/include/sys/socket.h",
-    other_srcs = ["include/sys/socket.h.def"],
-    yaml_template = "include/sys/socket.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_stat_h",
-    hdr = "staging/include/sys/stat.h",
-    other_srcs = ["include/sys/stat.h.def"],
-    yaml_template = "include/sys/stat.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_syscall_h",
-    hdr = "staging/include/sys/syscall.h",
-    other_srcs = ["include/sys/syscall.h.def"],
-    yaml_template = "include/sys/syscall.yaml",
-)
-
-libc_generated_header(
-    name = "include_dirent_h",
-    hdr = "staging/include/dirent.h",
-    yaml_template = "include/dirent.yaml",
-)
-
-libc_generated_header(
-    name = "include_dlfcn_h",
-    hdr = "staging/include/dlfcn.h",
-    yaml_template = "include/dlfcn.yaml",
-)
-
-libc_generated_header(
-    name = "include_endian_h",
-    hdr = "staging/include/endian.h",
-    other_srcs = ["include/endian.h.def"],
-    yaml_template = "include/endian.yaml",
-)
-
-libc_generated_header(
-    name = "include_features_h",
-    hdr = "staging/include/features.h",
-    other_srcs = ["include/features.h.def"],
-    yaml_template = "include/features.yaml",
-)
-
-libc_generated_header(
-    name = "include_stdfix_h",
-    hdr = "staging/include/stdfix.h",
-    other_srcs = ["include/stdfix.h.def"],
-    yaml_template = "include/stdfix.yaml",
-)
-
-libc_generated_header(
-    name = "include_sysexits_h",
-    hdr = "staging/include/sysexits.h",
-    other_srcs = ["include/sysexits.h.def"],
-    yaml_template = "include/sysexits.yaml",
-)
-
-libc_generated_header(
-    name = "include_arpa_inet_h",
-    hdr = "staging/include/arpa/inet.h",
-    other_srcs = ["include/arpa/inet.h.def"],
-    yaml_template = "include/arpa/inet.yaml",
-)
-
-libc_generated_header(
-    name = "include_netinet_in_h",
-    hdr = "staging/include/netinet/in.h",
-    other_srcs = ["include/netinet/in.h.def"],
-    yaml_template = "include/netinet/in.yaml",
-)
-
-libc_generated_header(
-    name = "include_complex_h",
-    hdr = "staging/include/complex.h",
-    other_srcs = ["include/complex.h.def"],
-    yaml_template = "include/complex.yaml",
-)
-
-libc_generated_header(
-    name = "include_setjmp_h",
-    hdr = "staging/include/setjmp.h",
-    yaml_template = "include/setjmp.yaml",
-)
-
-libc_generated_header(
-    name = "include_strings_h",
-    hdr = "staging/include/strings.h",
-    yaml_template = "include/strings.yaml",
-)
-
-libc_generated_header(
-    name = "include_search_h",
-    hdr = "staging/include/search.h",
-    yaml_template = "include/search.yaml",
-)
-
-libc_generated_header(
-    name = "include_threads_h",
-    hdr = "staging/include/threads.h",
-    yaml_template = "include/threads.yaml",
-)
-
-libc_generated_header(
-    name = "include_stdckdint_h",
-    hdr = "staging/include/stdckdint.h",
-    other_srcs = ["include/stdckdint.h.def"],
-    yaml_template = "include/stdckdint.yaml",
-)
-
-libc_generated_header(
-    name = "include_pthread_h",
-    hdr = "staging/include/pthread.h",
-    yaml_template = "include/pthread.yaml",
-)
-
-libc_generated_header(
-    name = "include_sched_h",
-    hdr = "staging/include/sched.h",
-    other_srcs = ["include/sched.h.def"],
-    yaml_template = "include/sched.yaml",
-)
-
-libc_generated_header(
-    name = "include_spawn_h",
-    hdr = "staging/include/spawn.h",
-    yaml_template = "include/spawn.yaml",
-)
-
-libc_generated_header(
-    name = "include_link_h",
-    hdr = "staging/include/link.h",
-    other_srcs = ["include/link.h.def"],
-    yaml_template = "include/link.yaml",
-)
-
-libc_generated_header(
-    name = "include_elf_h",
-    hdr = "staging/include/elf.h",
-    other_srcs = ["include/elf.h.def"],
+    hdr = "staging/hdr/elf_proxy.h",
+    proxy = True,
     yaml_template = "include/elf.yaml",
 )
 
-libc_generated_header(
-    name = "include_sys_auxv_h",
-    hdr = "staging/include/sys/auxv.h",
-    other_srcs = ["include/sys/auxv.h.def"],
-    yaml_template = "include/sys/auxv.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_epoll_h",
-    hdr = "staging/include/sys/epoll.h",
-    other_srcs = ["include/sys/epoll.h.def"],
-    yaml_template = "include/sys/epoll.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_ioctl_h",
-    hdr = "staging/include/sys/ioctl.h",
-    other_srcs = ["include/sys/ioctl.h.def"],
-    yaml_template = "include/sys/ioctl.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_ipc_h",
-    hdr = "staging/include/sys/ipc.h",
-    yaml_template = "include/sys/ipc.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_prctl_h",
-    hdr = "staging/include/sys/prctl.h",
-    other_srcs = ["include/sys/prctl.h.def"],
-    yaml_template = "include/sys/prctl.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_random_h",
-    hdr = "staging/include/sys/random.h",
-    other_srcs = ["include/sys/random.h.def"],
-    yaml_template = "include/sys/random.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_select_h",
-    hdr = "staging/include/sys/select.h",
-    other_srcs = ["include/sys/select.h.def"],
-    yaml_template = "include/sys/select.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_statvfs_h",
-    hdr = "staging/include/sys/statvfs.h",
-    yaml_template = "include/sys/statvfs.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_time_h",
-    hdr = "staging/include/sys/time.h",
-    other_srcs = ["include/sys/time.h.def"],
-    yaml_template = "include/sys/time.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_types_h",
-    hdr = "staging/include/sys/types.h",
-    other_srcs = ["include/sys/types.h.def"],
-    yaml_template = "include/sys/types.yaml",
-)
-
-libc_generated_header(
-    name = "include_sys_utsname_h",
-    hdr = "staging/include/sys/utsname.h",
-    yaml_template = "include/sys/utsname.yaml",
-)
-
-libc_generated_header(
-    name = "include_termios_h",
-    hdr = "staging/include/termios.h",
-    other_srcs = ["include/termios.h.def"],
-    yaml_template = "include/termios.yaml",
-)
-
-libc_generated_header(
-    name = "include_uchar_h",
-    hdr = "staging/include/uchar.h",
-    yaml_template = "include/uchar.yaml",
-)
-
-libc_generated_header(
-    name = "include_wchar_h",
-    hdr = "staging/include/wchar.h",
-    other_srcs = ["include/wchar.h.def"],
-    yaml_template = "include/wchar.yaml",
-)
-
-libc_generated_header(
-    name = "include_wctype_h",
-    hdr = "staging/include/wctype.h",
-    yaml_template = "include/wctype.yaml",
-)
-
-libc_generated_header(
-    name = "include_locale_h",
-    hdr = "staging/include/locale.h",
-    other_srcs = ["include/locale.h.def"],
-    yaml_template = "include/locale.yaml",
-)
-
-libc_generated_header(
-    name = "include_nl_types_h",
-    hdr = "staging/include/nl_types.h",
-    yaml_template = "include/nl_types.yaml",
-)
-
 # Static headers that need to be in staging/include
-libc_copy_header(
-    name = "copy_llvm_libc_common_h",
-    src = "include/__llvm-libc-common.h",
-    out = "staging/include/__llvm-libc-common.h",
-)
-
-TYPE_HEADERS = glob(["include/llvm-libc-types/**/*.h"])
+STATIC_HEADERS = glob(["include/llvm-libc-types/**/*.h"]) + glob(["include/llvm-libc-macros/**/*.h"]) + ["include/__llvm-libc-common.h"]
 
 genrule(
-    name = "copy_llvm_libc_types",
-    srcs = TYPE_HEADERS,
-    outs = ["staging/include/" + f.replace("include/", "") for f in TYPE_HEADERS],
+    name = "copy_llvm_libc_static_headers",
+    srcs = STATIC_HEADERS,
+    outs = ["staging/include/" + f.replace("include/", "") for f in STATIC_HEADERS],
     cmd = " && ".join([
         "cp $(location %s) $(location %s)" % (
             src,
             "staging/include/" + src.replace("include/", ""),
         )
-        for src in TYPE_HEADERS
-    ]),
-)
-
-MACRO_HEADERS = glob(["include/llvm-libc-macros/**/*.h"])
-
-genrule(
-    name = "copy_llvm_libc_macros",
-    srcs = MACRO_HEADERS,
-    outs = ["staging/include/" + f.replace("include/", "") for f in MACRO_HEADERS],
-    cmd = " && ".join([
-        "cp $(location %s) $(location %s)" % (
-            src,
-            "staging/include/" + src.replace("include/", ""),
-        )
-        for src in MACRO_HEADERS
+        for src in STATIC_HEADERS
     ]),
 )
 
 cc_library(
     name = "public_headers",
     hdrs = [
-        ":copy_llvm_libc_common_h",
-        ":include_arpa_inet_h",
-        ":include_assert_h",
-        ":include_complex_h",
-        ":include_ctype_h",
-        ":include_dirent_h",
-        ":include_dlfcn_h",
-        ":include_elf_h",
-        ":include_endian_h",
-        ":include_errno_h",
-        ":include_fcntl_h",
-        ":include_features_h",
-        ":include_fenv_h",
-        ":include_float_h",
-        ":include_inttypes_h",
-        ":include_limits_h",
-        ":include_link_h",
-        ":include_locale_h",
+        ":copy_llvm_libc_static_headers",
         ":include_malloc_h",
-        ":include_math_h",
-        ":include_netinet_in_h",
-        ":include_nl_types_h",
-        ":include_poll_h",
-        ":include_pthread_h",
-        ":include_sched_h",
-        ":include_search_h",
-        ":include_setjmp_h",
-        ":include_signal_h",
-        ":include_spawn_h",
-        ":include_stdbit_h",
-        ":include_stdckdint_h",
-        ":include_stdfix_h",
-        ":include_stdint_h",
-        ":include_stdio_h",
         ":include_stdlib_h",
-        ":include_string_h",
-        ":include_strings_h",
-        ":include_sys_auxv_h",
-        ":include_sys_epoll_h",
-        ":include_sys_ioctl_h",
-        ":include_sys_ipc_h",
-        ":include_sys_mman_h",
-        ":include_sys_prctl_h",
-        ":include_sys_random_h",
-        ":include_sys_resource_h",
-        ":include_sys_select_h",
-        ":include_sys_socket_h",
-        ":include_sys_stat_h",
-        ":include_sys_statvfs_h",
-        ":include_sys_syscall_h",
-        ":include_sys_time_h",
-        ":include_sys_types_h",
-        ":include_sys_utsname_h",
-        ":include_sys_wait_h",
-        ":include_sysexits_h",
-        ":include_termios_h",
-        ":include_threads_h",
-        ":include_time_h",
-        ":include_uchar_h",
-        ":include_unistd_h",
-        ":include_wchar_h",
-        ":include_wctype_h",
     ] + [
-        ":copy_llvm_libc_macros",
-        ":copy_llvm_libc_types",
+        ":include_{}_h".format(header.replace("/", "_"))
+        for header in gen_headers_with_templates + gen_headers_with_no_h_def
     ],
     features = ["-parse_headers"],  # Needed due to stdbit-macros.h.
     includes = ["staging/include"],
-    visibility = ["//visibility:public"],
-    deps = [":public_headers_deps"],
 )
 
-# Library containing all headers that can be transitively included by generated llvm-libc
-# public headers (or by the unit tests).
+# 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(
     name = "public_headers_deps",
-    textual_hdrs = [
-        "include/__llvm-libc-common.h",
-    ] + glob([
-        "include/llvm-libc-types/**/*.h",
-        "include/llvm-libc-macros/**/*.h",
-    ]),
+    textual_hdrs = STATIC_HEADERS,
 )
 
 ################################## Base Config #################################
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 58560b6068a18..0844921749d6b 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
@@ -255,7 +255,7 @@ def libc_header_library(name, hdrs, deps = [], **kwargs):
         enforce_headers_only = True,
     )
 
-def libc_generated_header(name, hdr, yaml_template, other_srcs = []):
+def libc_generated_header(name, hdr, yaml_template, other_srcs = [], proxy = False):
     """Generates a libc header file from YAML template.
 
     Args:
@@ -263,12 +263,13 @@ def libc_generated_header(name, hdr, yaml_template, other_srcs = []):
       hdr: Path of the header file to generate.
       yaml_template: Path of the YAML template file.
       other_srcs: Other files required to generate the header, if any.
+      proxy: Whether this is a proxy header with slightly different generation results.
     """
     hdrgen = "//libc:hdrgen"
     cmd = "$(location {hdrgen}) $(location {yaml}) -o $@".format(
         hdrgen = hdrgen,
         yaml = yaml_template,
-    )
+    ) + ( " --proxy" if proxy else "")
 
     if not hdr.startswith("staging/"):
         fail(

>From da8785eaeb34614b695c3d61038a090bbf3a3d94 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Wed, 18 Mar 2026 17:02:18 +0000
Subject: [PATCH 3/5] fix formatting

---
 utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 0844921749d6b..e350ec5bf9681 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
@@ -269,7 +269,7 @@ def libc_generated_header(name, hdr, yaml_template, other_srcs = [], proxy = Fal
     cmd = "$(location {hdrgen}) $(location {yaml}) -o $@".format(
         hdrgen = hdrgen,
         yaml = yaml_template,
-    ) + ( " --proxy" if proxy else "")
+    ) + (" --proxy" if proxy else "")
 
     if not hdr.startswith("staging/"):
         fail(

>From 5069e17162ad6cdebe21b1f12f8dee09d4f6f469 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Thu, 19 Mar 2026 20:41:28 +0000
Subject: [PATCH 4/5] combine header info in struct, simplify genrule.

---
 .../llvm-project-overlay/libc/BUILD.bazel     | 248 +++++++++---------
 .../libc/libc_build_rules.bzl                 |  25 +-
 2 files changed, 140 insertions(+), 133 deletions(-)

diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 90f4dbde09003..04b4134067253 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -9,9 +9,9 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
 load("@rules_python//python:defs.bzl", "py_binary")
 load(
     ":libc_build_rules.bzl",
-    "libc_copy_header",
     "libc_function",
     "libc_generated_header",
+    "libc_header_info",
     "libc_header_library",
     "libc_math_function",
     "libc_support_library",
@@ -95,113 +95,140 @@ py_binary(
     deps = ["@pyyaml//:yaml"],
 )
 
-# the list of simple headers that only have name, hdr, other_srcs and
-# yaml_template. They also follow the pattern that the generated header is in
-# staging/include/<header>.h and the yaml template is in include/<header>.yaml.
-gen_headers_with_templates = [
-    "arpa/inet",
-    "assert",
-    "complex",
-    "elf",
-    "endian",
-    "errno",
-    "fcntl",
-    "features",
-    "float",
-    "inttypes",
-    "limits",
-    "link",
-    "locale",
-    "math",
-    "netinet/in",
-    "poll",
-    "sched",
-    "signal",
-    "stdbit",
-    "stdckdint",
-    "stdfix",
-    "stdint",
-    "stdio",
-    "sysexits",
-    "sys/auxv",
-    "sys/epoll",
-    "sys/ioctl",
-    "sys/mman",
-    "sys/prctl",
-    "sys/random",
-    "sys/resource",
-    "sys/select",
-    "sys/socket",
-    "sys/stat",
-    "sys/syscall",
-    "sys/time",
-    "sys/types",
-    "sys/wait",
-    "termios",
-    "time",
-    "unistd",
-    "wchar",
-]
-
-# same as above but they don't have a .h.def file listed.
-gen_headers_with_no_h_def = [
-    "ctype",
-    "dirent",
-    "dlfcn",
-    "fenv",
-    "nl_types",
-    "pthread",
-    "search",
-    "setjmp",
-    "spawn",
-    "string",
-    "strings",
-    "sys/ipc",
-    "sys/statvfs",
-    "sys/utsname",
-    "threads",
-    "uchar",
-    "wctype",
-]
-
-[
-    libc_generated_header(
-        name = "include_{}_h".format(header.replace("/", "_")),
-        hdr = "staging/include/{}.h".format(header),
-        other_srcs = ["include/{}.h.def".format(header)],
-        yaml_template = "include/{}.yaml".format(header),
-    )
-    for header in gen_headers_with_templates
+LLVM_LIBC_HEADERS = [
+    libc_header_info("arpa/inet"),
+    libc_header_info("assert"),
+    libc_header_info("complex"),
+    libc_header_info("elf"),
+    libc_header_info("endian"),
+    libc_header_info("errno"),
+    libc_header_info("fcntl"),
+    libc_header_info("features"),
+    libc_header_info("float"),
+    libc_header_info("inttypes"),
+    libc_header_info("limits"),
+    libc_header_info("link"),
+    libc_header_info("locale"),
+    libc_header_info("math"),
+    libc_header_info("netinet/in"),
+    libc_header_info("poll"),
+    libc_header_info("sched"),
+    libc_header_info("signal"),
+    libc_header_info("stdbit"),
+    libc_header_info("stdckdint"),
+    libc_header_info("stdfix"),
+    libc_header_info("stdint"),
+    libc_header_info("stdio"),
+    libc_header_info("sysexits"),
+    libc_header_info("sys/auxv"),
+    libc_header_info("sys/epoll"),
+    libc_header_info("sys/ioctl"),
+    libc_header_info("sys/mman"),
+    libc_header_info("sys/prctl"),
+    libc_header_info("sys/random"),
+    libc_header_info("sys/resource"),
+    libc_header_info("sys/select"),
+    libc_header_info("sys/socket"),
+    libc_header_info("sys/stat"),
+    libc_header_info("sys/syscall"),
+    libc_header_info("sys/time"),
+    libc_header_info("sys/types"),
+    libc_header_info("sys/wait"),
+    libc_header_info("termios"),
+    libc_header_info("time"),
+    libc_header_info("unistd"),
+    libc_header_info("wchar"),
+    libc_header_info(
+        "ctype",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "dirent",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "dlfcn",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "fenv",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "nl_types",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "pthread",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "search",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "setjmp",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "spawn",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "string",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "strings",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "sys/ipc",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "sys/statvfs",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "sys/utsname",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "threads",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "uchar",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "wctype",
+        has_def_template = False,
+    ),
+    libc_header_info(
+        "stdlib",
+        has_def_template = True,
+        other_srcs = ["include/stdlib-malloc.yaml"],
+    ),
+    libc_header_info(
+        "malloc",
+        has_def_template = False,
+        other_srcs = ["include/stdlib-malloc.yaml"],
+    ),
 ]
 
 [
     libc_generated_header(
-        name = "include_{}_h".format(header.replace("/", "_")),
-        hdr = "staging/include/{}.h".format(header),
-        yaml_template = "include/{}.yaml".format(header),
+        name = info.target_name,
+        hdr = info.staging_path,
+        other_srcs = info.other_srcs,
+        yaml_template = info.yaml_template,
     )
-    for header in gen_headers_with_no_h_def
+    for info in LLVM_LIBC_HEADERS
 ]
 
-# headers which don't fit the standard patterns.
-libc_generated_header(
-    name = "include_stdlib_h",
-    hdr = "staging/include/stdlib.h",
-    other_srcs = [
-        "include/stdlib.h.def",
-        "include/stdlib-malloc.yaml",
-    ],
-    yaml_template = "include/stdlib.yaml",
-)
-
-libc_generated_header(
-    name = "include_malloc_h",
-    hdr = "staging/include/malloc.h",
-    other_srcs = ["include/stdlib-malloc.yaml"],
-    yaml_template = "include/malloc.yaml",
-)
-
-# needed for startup and VDSO
+# needed for startup and VDSO. Doesn't get placed in /include so is handled separately.
 libc_generated_header(
     name = "hdr_elf_proxy_h",
     hdr = "staging/hdr/elf_proxy.h",
@@ -216,27 +243,14 @@ genrule(
     name = "copy_llvm_libc_static_headers",
     srcs = STATIC_HEADERS,
     outs = ["staging/include/" + f.replace("include/", "") for f in STATIC_HEADERS],
-    cmd = " && ".join([
-        "cp $(location %s) $(location %s)" % (
-            src,
-            "staging/include/" + src.replace("include/", ""),
-        )
-        for src in STATIC_HEADERS
-    ]),
+    cmd = """srcs=($(SRCS))\n outs=($(OUTS))\n for i in "$${!srcs[@]}"; do cp "$${srcs[$$i]}" "$${outs[$$i]}"; done""",
 )
 
 cc_library(
     name = "public_headers",
-    hdrs = [
-        ":copy_llvm_libc_static_headers",
-        ":include_malloc_h",
-        ":include_stdlib_h",
-    ] + [
-        ":include_{}_h".format(header.replace("/", "_"))
-        for header in gen_headers_with_templates + gen_headers_with_no_h_def
-    ],
-    features = ["-parse_headers"],  # Needed due to stdbit-macros.h.
+    hdrs = [header.target_name for header in LLVM_LIBC_HEADERS],
     includes = ["staging/include"],
+    textual_hdrs = STATIC_HEADERS,
 )
 
 # Textual versions of the static headers. These are taken from the source tree
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 e350ec5bf9681..b97c054363296 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
@@ -286,22 +286,15 @@ def libc_generated_header(name, hdr, yaml_template, other_srcs = [], proxy = Fal
         tools = [hdrgen],
     )
 
-def libc_copy_header(name, src, out):
-    """Copies a header file to the staging directory.
-
-    Args:
-      name: Name of the target.
-      src: Path of the source header file.
-      out: Path of the output header file (relative to staging/include/).
-    """
-    if not out.startswith("staging/include/"):
-        fail("Output header must be in staging/include/")
-
-    native.genrule(
-        name = name,
-        srcs = [src],
-        outs = [out],
-        cmd = "cp $< $@",
+def libc_header_info(
+        name,
+        has_def_template = True,
+        other_srcs = []):
+    return struct(
+        target_name = "include_{}_h".format(name.replace("/", "_")),
+        staging_path = "staging/include/{}.h".format(name),
+        yaml_template = "include/{}.yaml".format(name),
+        other_srcs = other_srcs + (["include/{}.h.def".format(name)] if has_def_template else []),
     )
 
 def libc_math_function(

>From e9902cfe150034911b8c9ddad3a83b0b84cf14f2 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Fri, 20 Mar 2026 21:56:35 +0000
Subject: [PATCH 5/5] Cleanup and fix incorrect type in socket.yaml

---
 libc/include/sys/socket.yaml                  |  2 +-
 .../llvm-project-overlay/libc/BUILD.bazel     | 90 +++++--------------
 2 files changed, 21 insertions(+), 71 deletions(-)

diff --git a/libc/include/sys/socket.yaml b/libc/include/sys/socket.yaml
index 00d5de6af8a80..2e1100b028f2d 100644
--- a/libc/include/sys/socket.yaml
+++ b/libc/include/sys/socket.yaml
@@ -19,7 +19,7 @@ functions:
     return_type: int
     arguments:
       - type: int
-      - type: sockaddr *__restrict
+      - type: struct sockaddr *__restrict
       - type: socklen_t *__restrict
   - name: bind
     standards:
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 04b4134067253..643d18c898680 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -138,74 +138,23 @@ LLVM_LIBC_HEADERS = [
     libc_header_info("time"),
     libc_header_info("unistd"),
     libc_header_info("wchar"),
-    libc_header_info(
-        "ctype",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "dirent",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "dlfcn",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "fenv",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "nl_types",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "pthread",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "search",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "setjmp",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "spawn",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "string",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "strings",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "sys/ipc",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "sys/statvfs",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "sys/utsname",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "threads",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "uchar",
-        has_def_template = False,
-    ),
-    libc_header_info(
-        "wctype",
-        has_def_template = False,
-    ),
+    libc_header_info("ctype", False),
+    libc_header_info("dirent", False),
+    libc_header_info("dlfcn", False),
+    libc_header_info("fenv", False),
+    libc_header_info("nl_types", False),
+    libc_header_info("pthread", False),
+    libc_header_info("search", False),
+    libc_header_info("setjmp", False),
+    libc_header_info("spawn", False),
+    libc_header_info("string", False),
+    libc_header_info("strings", False),
+    libc_header_info("sys/ipc", False),
+    libc_header_info("sys/statvfs", False),
+    libc_header_info("sys/utsname", False),
+    libc_header_info("threads", False),
+    libc_header_info("uchar", False),
+    libc_header_info("wctype", False),
     libc_header_info(
         "stdlib",
         has_def_template = True,
@@ -242,7 +191,7 @@ STATIC_HEADERS = glob(["include/llvm-libc-types/**/*.h"]) + glob(["include/llvm-
 genrule(
     name = "copy_llvm_libc_static_headers",
     srcs = STATIC_HEADERS,
-    outs = ["staging/include/" + f.replace("include/", "") for f in STATIC_HEADERS],
+    outs = ["staging/" + f for f in STATIC_HEADERS],
     cmd = """srcs=($(SRCS))\n outs=($(OUTS))\n for i in "$${!srcs[@]}"; do cp "$${srcs[$$i]}" "$${outs[$$i]}"; done""",
 )
 
@@ -250,7 +199,8 @@ cc_library(
     name = "public_headers",
     hdrs = [header.target_name for header in LLVM_LIBC_HEADERS],
     includes = ["staging/include"],
-    textual_hdrs = STATIC_HEADERS,
+    textual_hdrs = ["staging/" + f for f in STATIC_HEADERS],
+    deps = [":copy_llvm_libc_static_headers"],
 )
 
 # Textual versions of the static headers. These are taken from the source tree



More information about the libc-commits mailing list