https://github.com/jtstogel updated https://github.com/llvm/llvm-project/pull/218995
>From dfedd86473f30ea975a5adb42c68281cbbc852cf Mon Sep 17 00:00:00 2001 From: jtstogel <[email protected]> Date: Thu, 16 Jul 2026 14:11:45 -0700 Subject: [PATCH] [libc][bazel] Add targets for startup objects [libc][bazel] more startup object rules [libc][bazel] Refactor internal_copts for libc_support_library --- libc/startup/linux/x86_64/tls.cpp | 2 +- .../llvm-project-overlay/libc/BUILD.bazel | 1 + .../libc/libc_build_rules.bzl | 43 ++++- .../libc/startup/BUILD.bazel | 3 + .../libc/startup/linux/BUILD.bazel | 103 ++++++++++ .../libc/startup/linux/x86_64/BUILD.bazel | 46 +++++ .../libc/startup/startup_rules.bzl | 176 ++++++++++++++++++ 7 files changed, 371 insertions(+), 3 deletions(-) create mode 100644 utils/bazel/llvm-project-overlay/libc/startup/BUILD.bazel create mode 100644 utils/bazel/llvm-project-overlay/libc/startup/linux/BUILD.bazel create mode 100644 utils/bazel/llvm-project-overlay/libc/startup/linux/x86_64/BUILD.bazel create mode 100644 utils/bazel/llvm-project-overlay/libc/startup/startup_rules.bzl diff --git a/libc/startup/linux/x86_64/tls.cpp b/libc/startup/linux/x86_64/tls.cpp index 98c5fbeb9d84b..13f6491295fe8 100644 --- a/libc/startup/linux/x86_64/tls.cpp +++ b/libc/startup/linux/x86_64/tls.cpp @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// +#include "config/app.h" #include "hdr/sys_mman_macros.h" #include "src/__support/OSUtil/linux/syscall_wrappers/getrandom.h" #include "src/__support/OSUtil/linux/syscall_wrappers/mmap.h" #include "src/__support/OSUtil/linux/syscall_wrappers/munmap.h" #include "src/__support/macros/config.h" #include "src/string/memory_utils/inline_memcpy.h" -#include "startup/linux/do_start.h" #include <asm/prctl.h> #include <sys/syscall.h> diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index c545d6bbde68d..1119735ad0243 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -4300,6 +4300,7 @@ libc_support_library( ], "//conditions:default": [], }), + copt_sets = ["threading"], deps = [ ":__support_common", ":__support_cpp_array", 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 a8021776c1bc6..8ae46c8b9adca 100644 --- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl +++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl @@ -75,21 +75,46 @@ def libc_release_copts(): }) return copts + platform_copts -def _libc_library(name, deps = [], **kwargs): +# Adding copts here is discouraged, as it complicates the build. +# The only use cases for per-TU copts are currently startup objects and threads. +_LIBC_LIBRARY_COPT_SETS = { + "startup_object": [ + "-ffreestanding", + "-fno-builtin", + "-fno-omit-frame-pointer", + "-fno-stack-protector", + ], + "threading": [ + "-fno-omit-frame-pointer", + "-Wno-frame-address", + ], +} + +def _libc_library( + name, + deps = [], + copt_sets = [], + **kwargs): """Internal macro to serve as a base for all other libc library rules. Args: name: Target name. deps: cc_library deps. + copt_sets: Which sets of allow-listed copts to include. **kwargs: All other attributes relevant for the cc_library rule. """ for attr in ["copts", "local_defines"]: if attr in kwargs: fail("disallowed attribute: '{}' in rule: '{}'".format(attr, name)) + + copts = [] + for feature in copt_sets: + copts.extend(_LIBC_LIBRARY_COPT_SETS[feature]) + cc_library( name = name, - copts = libc_common_copts(), + copts = libc_common_copts() + copts, local_defines = LIBC_CONFIGURE_OPTIONS, deps = deps + libc_common_deps(), linkstatic = 1, @@ -102,6 +127,20 @@ def _libc_library(name, deps = [], **kwargs): def libc_support_library(name, **kwargs): _libc_library(name = name, **kwargs) +def libc_startup_library(name, **kwargs): + """Add target for a libc startup library. + + Args: + name: Target name. + **kwargs: Other attributes relevant for a cc_library. + """ + + _libc_library( + name = name, + copt_sets = ["startup_object"], + **kwargs + ) + def libc_function(name, **kwargs): """Add target for a libc function. diff --git a/utils/bazel/llvm-project-overlay/libc/startup/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/startup/BUILD.bazel new file mode 100644 index 0000000000000..3b65f08ee74a1 --- /dev/null +++ b/utils/bazel/llvm-project-overlay/libc/startup/BUILD.bazel @@ -0,0 +1,3 @@ +# This file is licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception diff --git a/utils/bazel/llvm-project-overlay/libc/startup/linux/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/startup/linux/BUILD.bazel new file mode 100644 index 0000000000000..a141dd8452dcf --- /dev/null +++ b/utils/bazel/llvm-project-overlay/libc/startup/linux/BUILD.bazel @@ -0,0 +1,103 @@ +# This file is licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +load("//libc:libc_build_rules.bzl", "libc_startup_library", "libc_support_library") +load("//libc:platforms.bzl", "PLATFORM_CPU_X86_64") +load("//libc/startup:startup_rules.bzl", "libc_startup_object", "merge_relocatable_object") + +package( + default_visibility = ["//visibility:public"], +) + +libc_support_library( + name = "gnu_property_section", + srcs = ["gnu_property_section.cpp"], + hdrs = ["gnu_property_section.h"], + deps = [ + "//libc:__support_cpp_string_view", + "//libc:__support_macros_attributes", + "//libc:__support_macros_config", + "//libc:hdr_elf_proxy", + "//libc:hdr_link_macros", + "//libc:string_memory_utils", + ], +) + +libc_support_library( + name = "irelative_hdr", + hdrs = ["irelative.h"], + deps = [ + "//libc:__support_macros_config", + "//libc:hdr_link_macros", + "//libc:hdr_stdint_proxy", + ], +) + +libc_startup_library( + name = "do_start", + srcs = ["do_start.cpp"], + hdrs = [ + "do_start.h", + ], + target_compatible_with = select({ + "@platforms//os:linux": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + deps = [ + ":gnu_property_section", + ":irelative_hdr", + "//libc:__support_macros_config", + "//libc:__support_osutil_linux_auxv", + "//libc:__support_osutil_syscall", + "//libc:__support_threads_thread", + "//libc:__support_threads_thread_headers", + "//libc:_r_debug", + "//libc:atexit", + "//libc:config_app_h", + "//libc:config_linux_app_h", + "//libc:environ", + "//libc:exit", + "//libc:hdr_elf_proxy", + "//libc:hdr_link_macros", + "//libc:hdr_pthread_macros", + "//libc:hdr_stdint_proxy", + "//libc:hdr_sys_auxv_macros", + "//libc:hdr_sys_mman_macros", + "//libc:hdr_types_struct_link_map", + "//libc:hdr_types_struct_r_debug", + "//libc:program_invocation_name", + "//libc:program_invocation_short_name", + ] + select({ + PLATFORM_CPU_X86_64: [ + "//libc/startup/linux/x86_64:irelative", + "//libc/startup/linux/x86_64:tls", + ], + "//conditions:default": [], + }), +) + +merge_relocatable_object( + name = "crt1", + deps = [ + ":do_start", + ":gnu_property_section", + ] + select({ + PLATFORM_CPU_X86_64: [ + "//libc/startup/linux/x86_64:irelative", + "//libc/startup/linux/x86_64:start", + "//libc/startup/linux/x86_64:tls", + ], + "//conditions:default": [], + }), +) + +libc_startup_object( + name = "crti", + src = "crti.cpp", +) + +libc_startup_object( + name = "crtn", + src = "crtn.cpp", +) diff --git a/utils/bazel/llvm-project-overlay/libc/startup/linux/x86_64/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/startup/linux/x86_64/BUILD.bazel new file mode 100644 index 0000000000000..b9936609522b9 --- /dev/null +++ b/utils/bazel/llvm-project-overlay/libc/startup/linux/x86_64/BUILD.bazel @@ -0,0 +1,46 @@ +# This file is licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +load("//libc:libc_build_rules.bzl", "libc_startup_library") + +package( + default_visibility = ["//visibility:public"], +) + +libc_startup_library( + name = "tls", + srcs = ["tls.cpp"], + deps = [ + "//libc:__support_macros_config", + "//libc:__support_osutil_linux_syscall_wrappers_getrandom", + "//libc:__support_osutil_linux_syscall_wrappers_mmap", + "//libc:__support_osutil_linux_syscall_wrappers_munmap", + "//libc:config_app_h", + "//libc:hdr_sys_mman_macros", + "//libc:string_memory_utils", + ], +) + +libc_startup_library( + name = "start", + srcs = ["start.cpp"], + deps = [ + "//libc:__support_macros_attributes", + "//libc:config_app_h", + "//libc/startup/linux:do_start", + ], +) + +libc_startup_library( + name = "irelative", + srcs = ["irelative.cpp"], + deps = [ + "//libc:__support_macros_config", + "//libc:hdr_elf_macros", + "//libc:hdr_elf_proxy", + "//libc:hdr_link_macros", + "//libc:hdr_stdint_proxy", + "//libc/startup/linux:irelative_hdr", + ], +) diff --git a/utils/bazel/llvm-project-overlay/libc/startup/startup_rules.bzl b/utils/bazel/llvm-project-overlay/libc/startup/startup_rules.bzl new file mode 100644 index 0000000000000..db518e1ffddb7 --- /dev/null +++ b/utils/bazel/llvm-project-overlay/libc/startup/startup_rules.bzl @@ -0,0 +1,176 @@ +# This file is licensed under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +"""LLVM libc starlark rules for building startup objects.""" + +load("@bazel_skylib//lib:paths.bzl", "paths") +load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES") +load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain", "use_cc_toolchain") +load("@rules_cc//cc/common:cc_common.bzl", "cc_common") +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") +load("//libc:libc_build_rules.bzl", "libc_startup_library") + +def _get_compilation_outputs(deps): + outputs = [] + for dep in deps: + if OutputGroupInfo in dep and "compilation_outputs" in dep[OutputGroupInfo]: + outputs.extend(dep[OutputGroupInfo].compilation_outputs.to_list()) + return outputs + +def _extract_object_file_impl(ctx): + output = ctx.actions.declare_file(ctx.label.name + ".o") + input_objs = _get_compilation_outputs([ctx.attr.dep]) + if len(input_objs) != 1: + fail("Expected exactly one input object, got: {}".format(input_objs)) + + input_obj = input_objs[0] + + ctx.actions.symlink( + output = output, + target_file = input_obj, + ) + + return [DefaultInfo(files = depset([output]))] + +_extract_object_file = rule( + implementation = _extract_object_file_impl, + attrs = { + "dep": attr.label( + mandatory = True, + providers = [CcInfo], + ), + }, +) + +def libc_startup_object(name, src, visibility = None, **kwargs): + """Compiles a C++ source file into a startup object file. + + Args: + name: The name of the target. + src: The C++ source file to compile. + visibility: Visibility of targets created by this macro. + **kwargs: Other arguments to + """ + library_name = name + "_lib" + libc_startup_library( + name = library_name, + srcs = [src], + visibility = visibility, + **kwargs + ) + _extract_object_file( + name = name, + dep = ":" + library_name, + visibility = visibility, + ) + +def _filter_flags( + flags, + separate_flag_names, + joined_flag_prefixes): + """Filters flags to those in joined_flag_prefixes or separate_flag_names. + + Args: + flags: The flags to filter. + separate_flag_names: Names of flags whose value is specified separately + from the flag (for example "--target value"). + joined_flag_prefixes: Prefixes of flags whose value is joined to the + flag name (for example, --target=value). + """ + filtered_flags = [] + skip_next = False + for i, flag in enumerate(flags): + if skip_next: + skip_next = False + continue + + if flag in separate_flag_names: + if i + 1 < len(flags): + filtered_flags.append(flag) + filtered_flags.append(flags[i + 1]) + skip_next = True + continue + + for prefix in joined_flag_prefixes: + if flag.startswith(prefix): + filtered_flags.append(flag) + continue + + return filtered_flags + +def _merge_relocatable_object_impl(ctx): + cc_toolchain = find_cc_toolchain(ctx) + output = ctx.actions.declare_file(ctx.label.name + ".o") + + input_objs = _get_compilation_outputs(ctx.attr.deps) + + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + link_variables = cc_common.create_link_variables( + cc_toolchain = cc_toolchain, + feature_configuration = feature_configuration, + is_linking_dynamic_library = False, + ) + link_flags = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_configuration, + action_name = ACTION_NAMES.cpp_link_executable, + variables = link_variables, + ) + linker = cc_common.get_tool_for_action( + feature_configuration = feature_configuration, + action_name = ACTION_NAMES.cpp_link_executable, + ) + relocatable_link_flags = _filter_flags( + link_flags, + ("-target", "--target", "--sysroot", "-isysroot"), + ("-fuse-ld=", "-m", "--target=", "--sysroot="), + ) + + args = ctx.actions.args() + args.add_all(relocatable_link_flags) + + bindir = paths.dirname(linker) + if bindir: + args.add("-B" + bindir) + + args.add("-r") + args.add("-nostdlib") + args.add("-o", output) + args.add_all(input_objs) + + ctx.actions.run( + outputs = [output], + inputs = depset( + input_objs, + transitive = [cc_toolchain.all_files], + ), + executable = linker, + arguments = [args], + mnemonic = "MergeRelocatableObject", + use_default_shell_env = True, + ) + + return [DefaultInfo(files = depset([output]))] + +merge_relocatable_object = rule( + implementation = _merge_relocatable_object_impl, + doc = """Merges multiple object files into a single relocatable object file. + + This rule mimics CMake's `merge_relocatable_object`, + running the toolchain's linker driver `-r -nostdlib` on all direct deps. + """, + attrs = { + "deps": attr.label_list( + mandatory = True, + providers = [CcInfo], + doc = "The list of cc targets whose object files should be merged.", + ), + }, + toolchains = use_cc_toolchain(), + fragments = ["cpp"], +) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
