From 5d8168946dbe7b7aceeb8167ccad20468a9e013a Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Fri, 17 Jul 2026 23:19:19 +0200 Subject: [PATCH 1/5] Add //cc/libc config settings for C standard libraries Adds a libc_flag rule that exposes the current CC toolchain's target_libc value to select() via config settings for common C standard libraries in //cc/libc, mirroring //cc/compiler. Version suffixes in the "glibc-2.2.2" format documented for cc_common.create_cc_toolchain_config_info are ignored when matching. --- cc/libc/BUILD | 168 ++++++++++++++++++ cc/private/toolchain/BUILD.windows.tpl | 16 +- .../toolchain/armeabi_cc_toolchain_config.bzl | 2 +- .../toolchain/bsd_cc_toolchain_config.bzl | 2 +- .../toolchain/empty_cc_toolchain_config.bzl | 2 +- cc/private/toolchain/unix_cc_configure.bzl | 59 +++++- cc/toolchains/impl/libc_version.bzl | 34 ++++ cc/toolchains/libc_flag.bzl | 28 +++ cc/toolchains/toolchain.bzl | 15 +- docs/toolchain_api.md | 3 +- .../cc_static_library/test/mock_toolchain.bzl | 2 +- tests/cc/testutil/toolchains/BUILD | 2 +- .../toolchains/cc_toolchain_config.bzl | 2 +- tests/libc_settings/BUILD | 38 ++++ tests/libc_settings/libc_flag_test.bzl | 52 ++++++ tests/libc_settings/main.cc | 22 +++ 16 files changed, 424 insertions(+), 23 deletions(-) create mode 100644 cc/libc/BUILD create mode 100644 cc/toolchains/impl/libc_version.bzl create mode 100644 cc/toolchains/libc_flag.bzl create mode 100644 tests/libc_settings/BUILD create mode 100644 tests/libc_settings/libc_flag_test.bzl create mode 100644 tests/libc_settings/main.cc diff --git a/cc/libc/BUILD b/cc/libc/BUILD new file mode 100644 index 000000000..71fdfeed6 --- /dev/null +++ b/cc/libc/BUILD @@ -0,0 +1,168 @@ +# Copyright 2026 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Config settings for C standard libraries identified by Bazel. + +Targets that require libc-specific flags can use the config_settings defined in +this package in their select() statements. + +Toolchains not shipped with Bazel are encouraged to use the same names to +identify C standard libraries as used below, but this is not enforced. A +toolchain's `target_libc` value may carry a semantic version suffix in the form +(e.g. "glibc-2.31"), which is ignored when matching the config settings below. + +Example: + + cc_binary( + name = "foo", + srcs = ["foo.cc"], + copts = select({ + "//cc/libc:glibc": [...], + "//cc/libc:musl": [...], + "//cc/libc:ucrt": [...], + # Fallback case for an undetected C standard library. + "//conditions:default": [...], + }), + ) + +If multiple targets use the same set of conditionally enabled flags, this can be +simplified by extracting the select expression into a Starlark constant. +""" + +load("//cc/toolchains:libc_flag.bzl", "libc_flag") + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) + +libc_flag(name = "libc") + +### Linux + +# The GNU C Library (https://www.gnu.org/software/libc/). +config_setting( + name = "glibc", + flag_values = {":libc": "glibc"}, +) + +# musl libc (https://musl.libc.org). Also used by Emscripten and, in the form +# of the derived wasi-libc, by WASI toolchains. +config_setting( + name = "musl", + flag_values = {":libc": "musl"}, +) + +# uClibc and its successor uClibc-ng (https://uclibc-ng.org). +config_setting( + name = "uclibc", + flag_values = {":libc": "uclibc"}, +) + +### Android + +# Bionic, the C standard library of Android +# (https://android.googlesource.com/platform/bionic/). +config_setting( + name = "bionic", + flag_values = {":libc": "bionic"}, +) + +### Apple + +# On Apple platforms, the C standard library is provided by libSystem. For +# historical reasons, toolchains identify it via the value "macosx" on all +# Apple platforms, not just macOS. +config_setting( + name = "macosx", + flag_values = {":libc": "macosx"}, +) + +### BSDs + +# The C standard libraries developed as part of the respective BSD operating +# system. +config_setting( + name = "freebsd", + flag_values = {":libc": "freebsd"}, +) + +config_setting( + name = "netbsd", + flag_values = {":libc": "netbsd"}, +) + +config_setting( + name = "openbsd", + flag_values = {":libc": "openbsd"}, +) + +### Windows + +# The legacy Microsoft Visual C++ Runtime (msvcrt.dll), which is also targeted +# by MinGW-w64 toolchains by default. +config_setting( + name = "msvcrt", + flag_values = {":libc": "msvcrt"}, +) + +# The Universal C Runtime (ucrtbase.dll), used by MSVC and clang-cl as well as +# the UCRT flavor of MinGW-w64 toolchains. +config_setting( + name = "ucrt", + flag_values = {":libc": "ucrt"}, +) + +# The MSYS2 runtime (msys-2.0.dll), a Cygwin-derived POSIX emulation layer +# targeted by MSYS2's gcc. +config_setting( + name = "msys", + flag_values = {":libc": "msys"}, +) + +### Embedded + +# Newlib (https://sourceware.org/newlib/), commonly used by bare-metal +# toolchains such as arm-none-eabi-gcc. +config_setting( + name = "newlib", + flag_values = {":libc": "newlib"}, +) + +# Picolibc (https://github.com/picolibc/picolibc). +config_setting( + name = "picolibc", + flag_values = {":libc": "picolibc"}, +) + +# LLVM libc (https://libc.llvm.org). +config_setting( + name = "llvm-libc", + flag_values = {":libc": "llvm-libc"}, +) + +### WebAssembly + +# wasi-libc (https://github.com/WebAssembly/wasi-libc), the musl-derived C +# standard library of WASI SDK toolchains. +config_setting( + name = "wasi-libc", + flag_values = {":libc": "wasi-libc"}, +) + +### Generic + +config_setting( + name = "none", + flag_values = {":libc": "none"}, +) diff --git a/cc/private/toolchain/BUILD.windows.tpl b/cc/private/toolchain/BUILD.windows.tpl index afbc00d98..4ce902288 100644 --- a/cc/private/toolchain/BUILD.windows.tpl +++ b/cc/private/toolchain/BUILD.windows.tpl @@ -218,7 +218,7 @@ cc_toolchain_config( compiler = "mingw-gcc", host_system_name = "local", target_system_name = "local", - target_libc = "mingw", + target_libc = "msvcrt", abi_version = "local", abi_libc_version = "local", tool_bin_path = "%{mingw_tool_bin_path}", @@ -267,7 +267,7 @@ cc_toolchain_config( compiler = "mingw-gcc", host_system_name = "local", target_system_name = "local", - target_libc = "mingw", + target_libc = "msvcrt", abi_version = "local", abi_libc_version = "local", tool_bin_path = "%{mingw_tool_bin_path}", @@ -318,7 +318,7 @@ cc_toolchain_config( compiler = "msvc-cl", host_system_name = "local", target_system_name = "local", - target_libc = "msvcrt", + target_libc = "ucrt", abi_version = "local", abi_libc_version = "local", toolchain_identifier = "msvc_x64", @@ -393,7 +393,7 @@ cc_toolchain_config( compiler = "msvc-cl", host_system_name = "local", target_system_name = "local", - target_libc = "msvcrt", + target_libc = "ucrt", abi_version = "local", abi_libc_version = "local", toolchain_identifier = "msvc_x64_x86", @@ -468,7 +468,7 @@ cc_toolchain_config( compiler = "msvc-cl", host_system_name = "local", target_system_name = "local", - target_libc = "msvcrt", + target_libc = "ucrt", abi_version = "local", abi_libc_version = "local", toolchain_identifier = "msvc_x64_arm", @@ -543,7 +543,7 @@ cc_toolchain_config( compiler = "msvc-cl", host_system_name = "local", target_system_name = "local", - target_libc = "msvcrt", + target_libc = "ucrt", abi_version = "local", abi_libc_version = "local", toolchain_identifier = "msvc_arm64", @@ -618,7 +618,7 @@ cc_toolchain_config( compiler = "clang-cl", host_system_name = "local", target_system_name = "local", - target_libc = "msvcrt", + target_libc = "ucrt", abi_version = "local", abi_libc_version = "local", toolchain_identifier = "clang_cl_x64", @@ -691,7 +691,7 @@ cc_toolchain_config( compiler = "clang-cl", host_system_name = "local", target_system_name = "aarch64-pc-windows-msvc", - target_libc = "msvcrt", + target_libc = "ucrt", abi_version = "local", abi_libc_version = "local", toolchain_identifier = "clang_cl_arm64", diff --git a/cc/private/toolchain/armeabi_cc_toolchain_config.bzl b/cc/private/toolchain/armeabi_cc_toolchain_config.bzl index b35e43fe3..30cb09f46 100644 --- a/cc/private/toolchain/armeabi_cc_toolchain_config.bzl +++ b/cc/private/toolchain/armeabi_cc_toolchain_config.bzl @@ -26,7 +26,7 @@ def _impl(ctx): host_system_name = "armeabi-v7a" target_system_name = "armeabi-v7a" target_cpu = "armeabi-v7a" - target_libc = "armeabi-v7a" + target_libc = "unknown" compiler = "compiler" abi_version = "armeabi-v7a" abi_libc_version = "armeabi-v7a" diff --git a/cc/private/toolchain/bsd_cc_toolchain_config.bzl b/cc/private/toolchain/bsd_cc_toolchain_config.bzl index 83b9313f0..ced21ba57 100644 --- a/cc/private/toolchain/bsd_cc_toolchain_config.bzl +++ b/cc/private/toolchain/bsd_cc_toolchain_config.bzl @@ -62,7 +62,7 @@ def _impl(ctx): toolchain_identifier = "local_{}".format(cpu) if is_bsd else "stub_armeabi-v7a" host_system_name = "local" if is_bsd else "armeabi-v7a" target_system_name = "local" if is_bsd else "armeabi-v7a" - target_libc = "local" if is_bsd else "armeabi-v7a" + target_libc = cpu if is_bsd else "unknown" abi_version = "local" if is_bsd else "armeabi-v7a" abi_libc_version = "local" if is_bsd else "armeabi-v7a" diff --git a/cc/private/toolchain/empty_cc_toolchain_config.bzl b/cc/private/toolchain/empty_cc_toolchain_config.bzl index 5b2e49cdd..f5ca6fe8e 100644 --- a/cc/private/toolchain/empty_cc_toolchain_config.bzl +++ b/cc/private/toolchain/empty_cc_toolchain_config.bzl @@ -26,7 +26,7 @@ def _impl(ctx): host_system_name = "local", target_system_name = "local", target_cpu = "local", - target_libc = "local", + target_libc = "unknown", compiler = "compiler", abi_version = "local", abi_libc_version = "local", diff --git a/cc/private/toolchain/unix_cc_configure.bzl b/cc/private/toolchain/unix_cc_configure.bzl index 80a4f642b..2d1d21def 100644 --- a/cc/private/toolchain/unix_cc_configure.bzl +++ b/cc/private/toolchain/unix_cc_configure.bzl @@ -59,6 +59,58 @@ def _prepare_include_path(repo_ctx, path): return path[len(repo_root):] return path +def _get_target_libc(repository_ctx, cc, darwin, compile_opts): + """Detect the C standard library targeted by the compiler. + + Returns one of the canonical names used by the config_settings in + @rules_cc//cc/libc if the C standard library is recognized and "unknown" + otherwise. Can be overridden via the BAZEL_TARGET_LIBC environment + variable. + + Args: + repository_ctx: The repository context. + cc: Path of the compiler. + darwin: Whether the target platform is macOS. + compile_opts: User-configured C compile flags, which may affect the + targeted libc (e.g. via --sysroot or --target). + """ + if darwin: + return "macosx" + libc = get_env_var(repository_ctx, "BAZEL_TARGET_LIBC", "", False) + if libc: + return escape_string(libc) + + # Preprocessing any standard library header defines macros that identify + # most implementations. + repository_ctx.file("tools/cpp/detect_libc.c", "#include \n") + result = repository_ctx.execute([cc] + compile_opts + ["-E", "-dM", "tools/cpp/detect_libc.c"]) + if result.return_code == 0: + for macro, libc in [ + # uClibc also defines __GLIBC__ for compatibility, so check for it + # first. + ("__UCLIBC__", "uclibc"), + ("__GLIBC__", "glibc"), + ("__BIONIC__", "bionic"), + ("__LLVM_LIBC__", "llvm-libc"), + ("__FreeBSD__", "freebsd"), + ("__NetBSD__", "netbsd"), + ("__OpenBSD__", "openbsd"), + ]: + if ("#define %s " % macro) in result.stdout: + return libc + + # musl intentionally doesn't define an identifying macro, but is usually + # mentioned in the compiler's target triple. + result = repository_ctx.execute([cc] + compile_opts + ["-dumpmachine"]) + if result.return_code == 0: + triple = result.stdout.strip() + if "musl" in triple: + return "musl" + if "android" in triple: + return "bionic" + + return "unknown" + def _find_tool(repository_ctx, tool, overridden_tools): """Find a tool for repository, taking overridden tools into account.""" if tool in overridden_tools: @@ -770,12 +822,7 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overridden_tools): cpu_value, False, )), - "%{target_libc}": "macosx" if darwin else escape_string(get_env_var( - repository_ctx, - "BAZEL_TARGET_LIBC", - "local", - False, - )), + "%{target_libc}": _get_target_libc(repository_ctx, cc, darwin, all_compile_opts + conly_opts), "%{target_system_name}": escape_string(get_env_var( repository_ctx, "BAZEL_TARGET_SYSTEM", diff --git a/cc/toolchains/impl/libc_version.bzl b/cc/toolchains/impl/libc_version.bzl new file mode 100644 index 000000000..c3f8ef659 --- /dev/null +++ b/cc/toolchains/impl/libc_version.bzl @@ -0,0 +1,34 @@ +# Copyright 2026 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Helper function for parsing target_libc values.""" + +visibility([ + "//cc/toolchains", + "//tests/libc_settings", +]) + +def libc_without_version(libc): + """Strips a version suffix from a target_libc value. + + Args: + libc: (str) The value of cc_toolchain.libc. + + Returns: + The name of the C standard library without a version suffix. + """ + for i in range(1, len(libc) - 1): + if libc[i] == "-" and libc[i + 1].isdigit(): + return libc[:i] + return libc diff --git a/cc/toolchains/libc_flag.bzl b/cc/toolchains/libc_flag.bzl new file mode 100644 index 000000000..e06db80b5 --- /dev/null +++ b/cc/toolchains/libc_flag.bzl @@ -0,0 +1,28 @@ +# Copyright 2026 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Rule that allows select() to differentiate between C standard libraries.""" + +load("//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_ATTRS", "find_cpp_toolchain", "use_cc_toolchain") +load("//cc/toolchains/impl:libc_version.bzl", "libc_without_version") + +def _libc_flag_impl(ctx): + toolchain = find_cpp_toolchain(ctx) + return [config_common.FeatureFlagInfo(value = libc_without_version(toolchain.libc))] + +libc_flag = rule( + implementation = _libc_flag_impl, + attrs = CC_TOOLCHAIN_ATTRS, + toolchains = use_cc_toolchain(), +) diff --git a/cc/toolchains/toolchain.bzl b/cc/toolchains/toolchain.bzl index 6637d4481..4c26c675c 100644 --- a/cc/toolchains/toolchain.bzl +++ b/cc/toolchains/toolchain.bzl @@ -52,6 +52,7 @@ def cc_toolchain( supports_param_files = False, compiler = "", cpu = "", + target_libc = None, target_system_name = None, **kwargs): """A C/C++ toolchain configuration. @@ -148,6 +149,11 @@ def cc_toolchain( through the `target_cpu` attribute of the toolchain configuration. We should not add new readers of this value, but there are many existing ones in the wild. + target_libc: (str) The name of the C standard library targeted by this toolchain + (e.g. "glibc", "musl"), optionally followed by a version suffix (e.g. + "glibc-2.2.2"). The current toolchain's C standard library is exposed to + `select()` statements via the config settings in `@rules_cc//cc/libc`. If not provided, + a best effort default is selected. target_system_name: (str) The target system name for this toolchain. Bazel doesn't use this but starlark rules can read this value through `toolchain_info.target_gnu_system_name`. This string is commonly the target triple you would pass to `clang -target` (e.g. "x86_64-unknown-linux-gnu"). @@ -172,8 +178,13 @@ def cc_toolchain( "//conditions:default": "", }) - target_libc = select({ - Label("//cc/settings:apple_constraint"): "macosx", + target_libc = target_libc or select({ + Label("//cc/toolchains/impl:darwin_aarch64"): "macosx", + Label("//cc/toolchains/impl:darwin_x86_64"): "macosx", + Label("//cc/toolchains/impl:linux_aarch64"): "glibc", + Label("//cc/toolchains/impl:linux_x86_64"): "glibc", + Label("//cc/toolchains/impl:windows_x86_32"): "ucrt", + Label("//cc/toolchains/impl:windows_x86_64"): "ucrt", "//conditions:default": "", }) diff --git a/docs/toolchain_api.md b/docs/toolchain_api.md index 95f57af4f..9c68ae3a3 100644 --- a/docs/toolchain_api.md +++ b/docs/toolchain_api.md @@ -795,7 +795,7 @@ load("@rules_cc//cc/toolchains/impl:documented_api.bzl", "cc_toolchain") cc_toolchain(*, name, tool_map, args, artifact_name_patterns, make_variables, legacy_tools, known_features, enabled_features, libc_top, module_map, dynamic_runtime_lib, static_runtime_lib, supports_header_parsing, supports_param_files, compiler, cpu, - target_system_name, **kwargs) + target_libc, target_system_name, **kwargs) A C/C++ toolchain configuration. @@ -859,6 +859,7 @@ Generated rules: | supports_param_files | (bool) Whether or not this toolchain supports linking via param files. See [`cc_toolchain.supports_param_files`](https://bazel.build/reference/be/c-cpp#cc_toolchain.supports_param_files) for more information. | `False` | | compiler | (str) The type of compiler used by this toolchain (e.g. "gcc", "clang"). The current toolchain's compiler is exposed to `@rules_cc//cc/private/toolchain:compiler (compiler_flag)` as a flag value. | `""` | | cpu | (str) DEPRECATED: CPU string (ex: "darwin_arm64", "k8") exposed through the `target_cpu` attribute of the toolchain configuration. We should not add new readers of this value, but there are many existing ones in the wild. | `""` | +| target_libc | (str) The name of the C standard library targeted by this toolchain (e.g. "glibc", "musl"), optionally followed by a version suffix (e.g. "glibc-2.2.2"). The current toolchain's C standard library is exposed to `select()` statements via the config settings in `@rules_cc//cc/libc`. If not provided, a best effort default is selected. | `None` | | target_system_name | (str) The target system name for this toolchain. Bazel doesn't use this but starlark rules can read this value through `toolchain_info.target_gnu_system_name`. This string is commonly the target triple you would pass to `clang -target` (e.g. "x86_64-unknown-linux-gnu"). If not provided, a best effort default is selected. | `None` | | kwargs | [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) that should be applied to all rules created by this macro. | none | diff --git a/tests/builtins_bzl/cc/cc_static_library/test/mock_toolchain.bzl b/tests/builtins_bzl/cc/cc_static_library/test/mock_toolchain.bzl index 5aa120100..58b3c0129 100644 --- a/tests/builtins_bzl/cc/cc_static_library/test/mock_toolchain.bzl +++ b/tests/builtins_bzl/cc/cc_static_library/test/mock_toolchain.bzl @@ -100,7 +100,7 @@ def _mock_cc_toolchain_config_impl(ctx): host_system_name = "local", target_system_name = "local", target_cpu = "local", - target_libc = "local", + target_libc = "unknown", compiler = "compiler", ) diff --git a/tests/cc/testutil/toolchains/BUILD b/tests/cc/testutil/toolchains/BUILD index 1d5965de7..5d207e6a7 100644 --- a/tests/cc/testutil/toolchains/BUILD +++ b/tests/cc/testutil/toolchains/BUILD @@ -296,7 +296,7 @@ cc_toolchain_config( feature_names = [], host_system_name = "local", make_variables = {}, - target_libc = "local", + target_libc = "glibc", target_system_name = "local", tool_paths = {}, toolchain_identifier = "mock-toolchain-k8", diff --git a/tests/cc/testutil/toolchains/cc_toolchain_config.bzl b/tests/cc/testutil/toolchains/cc_toolchain_config.bzl index a4220dbd0..931fb778a 100644 --- a/tests/cc/testutil/toolchains/cc_toolchain_config.bzl +++ b/tests/cc/testutil/toolchains/cc_toolchain_config.bzl @@ -1794,7 +1794,7 @@ cc_toolchain_config = rule( "toolchain_identifier": attr.string(default = "mock-llvm-toolchain-k8"), "host_system_name": attr.string(default = "local"), "target_system_name": attr.string(default = "local"), - "target_libc": attr.string(default = "local"), + "target_libc": attr.string(default = "unknown"), "abi_version": attr.string(default = "local"), "abi_libc_version": attr.string(default = "local"), "feature_names": attr.string_list(), diff --git a/tests/libc_settings/BUILD b/tests/libc_settings/BUILD new file mode 100644 index 000000000..45b1ee3a7 --- /dev/null +++ b/tests/libc_settings/BUILD @@ -0,0 +1,38 @@ +# Copyright 2026 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("//cc:cc_binary.bzl", "cc_binary") +load(":libc_flag_test.bzl", "libc_flag_test_suite") + +licenses(["notice"]) + +libc_flag_test_suite(name = "libc_flag_tests") + +cc_binary( + name = "main", + srcs = ["main.cc"], + local_defines = select( + { + "//cc/libc:bionic": ["LIBC=bionic"], + "//cc/libc:glibc": ["LIBC=glibc"], + "//cc/libc:macosx": ["LIBC=macosx"], + "//cc/libc:msvcrt": ["LIBC=msvcrt"], + "//cc/libc:msys": ["LIBC=msys"], + "//cc/libc:musl": ["LIBC=musl"], + "//cc/libc:ucrt": ["LIBC=ucrt"], + "//conditions:default": [], + }, + no_match_error = "C standard library not detected by Bazel", + ), +) diff --git a/tests/libc_settings/libc_flag_test.bzl b/tests/libc_settings/libc_flag_test.bzl new file mode 100644 index 000000000..2ad17036f --- /dev/null +++ b/tests/libc_settings/libc_flag_test.bzl @@ -0,0 +1,52 @@ +# Copyright 2026 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for libc_without_version()""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//cc/toolchains/impl:libc_version.bzl", "libc_without_version") + +def _libc_without_version_impl(ctx): + env = unittest.begin(ctx) + + # Unversioned values are returned unchanged. + asserts.equals(env, "glibc", libc_without_version("glibc")) + asserts.equals(env, "macosx", libc_without_version("macosx")) + asserts.equals(env, "unknown", libc_without_version("unknown")) + asserts.equals(env, "", libc_without_version("")) + + # Version suffixes in the "glibc-2.2.2" format documented for + # cc_common.create_cc_toolchain_config_info are stripped. + asserts.equals(env, "glibc", libc_without_version("glibc-2.2.2")) + asserts.equals(env, "glibc", libc_without_version("glibc-2")) + asserts.equals(env, "musl", libc_without_version("musl-1.2.4")) + asserts.equals(env, "newlib", libc_without_version("newlib-4.3.0.20230120")) + + # A "-" followed by a non-digit is part of the name, not a version suffix. + asserts.equals(env, "wasi-libc", libc_without_version("wasi-libc")) + asserts.equals(env, "llvm-libc", libc_without_version("llvm-libc")) + asserts.equals(env, "wasi-libc", libc_without_version("wasi-libc-25")) + + # A trailing "-" is not a version suffix. + asserts.equals(env, "glibc-", libc_without_version("glibc-")) + + return unittest.end(env) + +libc_without_version_test = unittest.make(_libc_without_version_impl) + +def libc_flag_test_suite(name): + unittest.suite( + name, + libc_without_version_test, + ) diff --git a/tests/libc_settings/main.cc b/tests/libc_settings/main.cc new file mode 100644 index 000000000..ee5b1bf74 --- /dev/null +++ b/tests/libc_settings/main.cc @@ -0,0 +1,22 @@ +// Copyright 2026 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#define STRINGIFY(x) #x +#define TO_STRING(x) STRINGIFY(x) + +int main() { + std::cout << "Hello, " << TO_STRING(LIBC) << "!" << std::endl; +} From 98a38d1da4d1f9df5f3c00151d0756014b61fc68 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Tue, 21 Jul 2026 19:14:58 +0200 Subject: [PATCH 2/5] Apply suggestion from @keith Co-authored-by: Keith Smiley --- cc/toolchains/toolchain.bzl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cc/toolchains/toolchain.bzl b/cc/toolchains/toolchain.bzl index 4c26c675c..886193652 100644 --- a/cc/toolchains/toolchain.bzl +++ b/cc/toolchains/toolchain.bzl @@ -179,8 +179,7 @@ def cc_toolchain( }) target_libc = target_libc or select({ - Label("//cc/toolchains/impl:darwin_aarch64"): "macosx", - Label("//cc/toolchains/impl:darwin_x86_64"): "macosx", + Label("//cc/toolchains/impl:apple_constraint"): "macosx", Label("//cc/toolchains/impl:linux_aarch64"): "glibc", Label("//cc/toolchains/impl:linux_x86_64"): "glibc", Label("//cc/toolchains/impl:windows_x86_32"): "ucrt", From c19978c6ee8867104c9fd10fa1730544e41c06f6 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Tue, 21 Jul 2026 19:15:19 +0200 Subject: [PATCH 3/5] Apply suggestion from @fmeum --- tests/libc_settings/BUILD | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/libc_settings/BUILD b/tests/libc_settings/BUILD index 45b1ee3a7..a2f263b8d 100644 --- a/tests/libc_settings/BUILD +++ b/tests/libc_settings/BUILD @@ -33,6 +33,5 @@ cc_binary( "//cc/libc:ucrt": ["LIBC=ucrt"], "//conditions:default": [], }, - no_match_error = "C standard library not detected by Bazel", ), ) From 16cf2115608796da22753286bb581ad71d953321 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Tue, 21 Jul 2026 19:17:07 +0200 Subject: [PATCH 4/5] Fix apple_constraints label --- cc/toolchains/toolchain.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cc/toolchains/toolchain.bzl b/cc/toolchains/toolchain.bzl index 886193652..b5941184a 100644 --- a/cc/toolchains/toolchain.bzl +++ b/cc/toolchains/toolchain.bzl @@ -179,7 +179,7 @@ def cc_toolchain( }) target_libc = target_libc or select({ - Label("//cc/toolchains/impl:apple_constraint"): "macosx", + Label("//cc/settings:apple_constraint"): "macosx", Label("//cc/toolchains/impl:linux_aarch64"): "glibc", Label("//cc/toolchains/impl:linux_x86_64"): "glibc", Label("//cc/toolchains/impl:windows_x86_32"): "ucrt", From 7215a9ced75b2d01816d25b87e76c8387b0eee34 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 22 Jul 2026 10:50:54 +0200 Subject: [PATCH 5/5] Update cc/toolchains/toolchain.bzl Co-authored-by: Keith Smiley --- cc/toolchains/toolchain.bzl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cc/toolchains/toolchain.bzl b/cc/toolchains/toolchain.bzl index b5941184a..255d06b99 100644 --- a/cc/toolchains/toolchain.bzl +++ b/cc/toolchains/toolchain.bzl @@ -180,10 +180,8 @@ def cc_toolchain( target_libc = target_libc or select({ Label("//cc/settings:apple_constraint"): "macosx", - Label("//cc/toolchains/impl:linux_aarch64"): "glibc", - Label("//cc/toolchains/impl:linux_x86_64"): "glibc", - Label("//cc/toolchains/impl:windows_x86_32"): "ucrt", - Label("//cc/toolchains/impl:windows_x86_64"): "ucrt", + Label("@platforms//os:linux"): "glibc", + Label("@platforms//os:windows"): "ucrt", "//conditions:default": "", })