From c5051288d8bac66438b06be7f6461895da8a8439 Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Mon, 9 Nov 2026 17:03:15 +0000 Subject: [PATCH 1/2] feat: Add EBcLfSA 2.0.0-beta3 high integrity toolchain The toolchain is used to build ASIL-B applications and has a limited feature set. Therefore feature selection needs some changes to accomodate toolchain supported features. --- .github/workflows/ebclfsa.yml | 19 +++ features/custom/linux/ebclfsa_hi/BUILD | 20 +++ features/custom/linux/make_cc_features.bzl | 32 ++++- features/native/default_compile_flags/BUILD | 6 + .../linux/aarch64/ebclfsa/2.0.0-beta3/BUILD | 1 + .../ebclfsa/2.0.0-beta3/ebclfsa_hi.BUILD | 67 ++++++++++ packages/version_matrix.bzl | 58 ++++++++ templates/BUILD.template | 5 +- tests/.bazelrc | 4 + tests/BUILD | 11 ++ tests/MODULE.bazel | 12 ++ tests/MODULE.bazel.lock | 87 +++++++++++- tests/README.md | 28 ++++ tests/ebclfsa_hi/BUILD | 40 ++++++ tests/ebclfsa_hi/c_runtime.c | 25 ++++ tests/ebclfsa_hi/configuration_test.bzl | 125 ++++++++++++++++++ tests/ebclfsa_hi/exceptions.cpp | 8 ++ tests/ebclfsa_hi/rtti.cpp | 14 ++ tests/ebclfsa_hi/runtime_test.cpp | 49 +++++++ tests/patches/BUILD | 5 + .../score_bazel_platforms-ebclfsa-hi.patch | 34 +++++ 21 files changed, 645 insertions(+), 5 deletions(-) create mode 100644 features/custom/linux/ebclfsa_hi/BUILD create mode 100644 packages/linux/aarch64/ebclfsa/2.0.0-beta3/ebclfsa_hi.BUILD create mode 100644 tests/ebclfsa_hi/BUILD create mode 100644 tests/ebclfsa_hi/c_runtime.c create mode 100644 tests/ebclfsa_hi/configuration_test.bzl create mode 100644 tests/ebclfsa_hi/exceptions.cpp create mode 100644 tests/ebclfsa_hi/rtti.cpp create mode 100644 tests/ebclfsa_hi/runtime_test.cpp create mode 100644 tests/patches/BUILD create mode 100644 tests/patches/score_bazel_platforms-ebclfsa-hi.patch diff --git a/.github/workflows/ebclfsa.yml b/.github/workflows/ebclfsa.yml index d95d444..50fe308 100644 --- a/.github/workflows/ebclfsa.yml +++ b/.github/workflows/ebclfsa.yml @@ -24,6 +24,25 @@ on: types: [checks_requested] workflow_call: jobs: + aarch64-ebclfsa-hi: + runs-on: ubuntu-24.04 + name: Bazel Test (Aarch64-Linux)(ebclfsa HI) + defaults: + run: + working-directory: ./tests + steps: + - name: Checkout Repository + uses: actions/checkout@v6 + - name: Setup Bazel + uses: bazel-contrib/setup-bazel@0.18.0 + - name: Install AArch64 userspace emulator + run: sudo apt-get update && sudo apt-get install -y --no-install-recommends qemu-user + - name: Verify high-integrity configuration and restrictions + run: | + bazel test --lockfile_mode=error --config=aarch64-linux-ebclfsa-hi --test_lang_filters=-cc -- //:ebclfsa_hi_tests //:guardrail_tests + - name: Run high-integrity runtime test + run: | + bazel test --lockfile_mode=error --config=aarch64-linux-ebclfsa-hi --run_under=/usr/bin/qemu-aarch64 -- //ebclfsa_hi:runtime_test aarch64-ebclfsa: runs-on: ubuntu-24.04 strategy: diff --git a/features/custom/linux/ebclfsa_hi/BUILD b/features/custom/linux/ebclfsa_hi/BUILD new file mode 100644 index 0000000..a1a3ced --- /dev/null +++ b/features/custom/linux/ebclfsa_hi/BUILD @@ -0,0 +1,20 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature") + +package(default_visibility = ["//visibility:public"]) + +cc_feature( + name = "compile_flags", + args = [ + "//features/native/default_compile_flags:c_std_c11_args", + "//features/native/default_compile_flags:c_std_gnu11_args", + "//features/native/default_compile_flags:c_std_c99_args", + "//features/native/default_compile_flags:default_cxx_compile_flags_args", + "//features/native/default_compile_flags:dbg_compile_flags_args", + "//features/native/default_compile_flags:opt_compile_flags_args", + ], + feature_name = "default_compile_flags", +) diff --git a/features/custom/linux/make_cc_features.bzl b/features/custom/linux/make_cc_features.bzl index 54a7e0a..3624c09 100644 --- a/features/custom/linux/make_cc_features.bzl +++ b/features/custom/linux/make_cc_features.bzl @@ -67,10 +67,38 @@ def linux_enabled_features(): """Subset of Linux feature labels that start enabled — order is irrelevant here.""" return [label for label, enabled in _LINUX_FEATURES if enabled] -def get_feature_lists(): +def get_feature_lists(runtime_ecosystem = ""): """Returns the flat known/enabled feature label lists for Linux. + Args: + runtime_ecosystem: Select the feature profile for this runtime. + Returns: (known_features, enabled_features) tuple of flat label lists. """ - return linux_known_features(), linux_enabled_features() + if runtime_ecosystem != "ebclfsa-hi": + return linux_known_features(), linux_enabled_features() + + omitted = [ + "default_link_flags", + "static_libgcc", + "gcc_coverage_map_format", + "coverage", + "supports_dynamic_linker", + "shared_flag", + "runtime_library_search_directories", + "fission_support", + "supports_fission", + ] + features = [ + ( + "@score_bazel_cpp_toolchains//features/custom/linux/ebclfsa_hi:compile_flags" if label == "@score_bazel_cpp_toolchains//features/native/default_compile_flags" else label, + enabled, + ) + for label, enabled in _LINUX_FEATURES + if label.split(":")[-1].split("/")[-1] not in omitted + ] + return ( + [label for label, _enabled in features], + [label for label, enabled in features if enabled], + ) diff --git a/features/native/default_compile_flags/BUILD b/features/native/default_compile_flags/BUILD index 291816c..8ac5bb4 100644 --- a/features/native/default_compile_flags/BUILD +++ b/features/native/default_compile_flags/BUILD @@ -79,6 +79,7 @@ cc_args( requires_any_of = [ ":is_c99", ], + visibility = ["//visibility:public"], ) cc_args( @@ -86,6 +87,7 @@ cc_args( actions = ["@rules_cc//cc/toolchains/actions:c_compile"], args = ["-std=c11"], requires_any_of = [":is_c11"], + visibility = ["//visibility:public"], ) cc_args( @@ -93,6 +95,7 @@ cc_args( actions = ["@rules_cc//cc/toolchains/actions:c_compile"], args = ["-std=gnu11"], requires_any_of = [":is_gnu11"], + visibility = ["//visibility:public"], ) cc_args( @@ -105,6 +108,7 @@ cc_args( ], "//conditions:default": [], }), + visibility = ["//visibility:public"], ) cc_feature_constraint( @@ -120,6 +124,7 @@ cc_args( "-g3", ], requires_any_of = [":is_dbg"], + visibility = ["//visibility:public"], ) cc_feature_constraint( @@ -143,6 +148,7 @@ cc_args( ":is_opt", ":is_fastbuild", ], + visibility = ["//visibility:public"], ) cc_args( diff --git a/packages/linux/aarch64/ebclfsa/2.0.0-beta3/BUILD b/packages/linux/aarch64/ebclfsa/2.0.0-beta3/BUILD index 89c2b98..c38979f 100644 --- a/packages/linux/aarch64/ebclfsa/2.0.0-beta3/BUILD +++ b/packages/linux/aarch64/ebclfsa/2.0.0-beta3/BUILD @@ -13,4 +13,5 @@ exports_files([ "ebclfsa.BUILD", + "ebclfsa_hi.BUILD", ]) diff --git a/packages/linux/aarch64/ebclfsa/2.0.0-beta3/ebclfsa_hi.BUILD b/packages/linux/aarch64/ebclfsa/2.0.0-beta3/ebclfsa_hi.BUILD new file mode 100644 index 0000000..a978455 --- /dev/null +++ b/packages/linux/aarch64/ebclfsa/2.0.0-beta3/ebclfsa_hi.BUILD @@ -0,0 +1,67 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +"""Clang/musl/libc++ tools from the EBcLfSA beta3 SDK.""" + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "all_files", + srcs = glob( + [ + "opt/**/*", + "usr/**/*", + "lib/**/*", + ], + exclude = [ + "usr/share/ca-certificates/**", + "usr/lib/ssl/certs/**", + "lib/ssl/certs/**", + "usr/share/man/**", + "usr/share/perl/**", + ], + ), +) + +filegroup( + name = "ar", + srcs = ["usr/bin/aarch64-linux-gnu-ar"], +) + +filegroup( + name = "cc", + srcs = ["usr/lib/llvm-20/bin/clang"], +) + +filegroup( + name = "cxx", + srcs = ["usr/lib/llvm-20/bin/clang++"], +) + +filegroup( + name = "gcov", + srcs = ["usr/bin/aarch64-linux-gnu-gcov-14"], +) + +filegroup( + name = "strip", + srcs = ["usr/bin/aarch64-linux-gnu-strip"], +) + +filegroup( + name = "readelf", + srcs = ["usr/bin/aarch64-linux-gnu-readelf"], +) + +filegroup( + name = "elf-enabler", + srcs = ["usr/bin/lisa-elf-enabler"], +) + +filegroup( + name = "sysroot_dir", + srcs = ["."], +) + +filegroup(name = "cxx_builtin_include_directories") diff --git a/packages/version_matrix.bzl b/packages/version_matrix.bzl index 3a4b479..9838ac2 100644 --- a/packages/version_matrix.bzl +++ b/packages/version_matrix.bzl @@ -384,3 +384,61 @@ VERSION_MATRIX = { "gcc_version": "12.2.0", }, } + +# Both integrity variants share archive metadata; the HI profile additionally +# repairs LLVM's host-library lookup without exporting LD_LIBRARY_PATH. +_EBCLFSA_HI_ROOT = "external/%{toolchain_pkg}%" +_EBCLFSA_HI_C_FLAGS = [ + "--target=aarch64-linux-gnu", + "-nostdinc", + "-isystem", + _EBCLFSA_HI_ROOT + "/opt/lisa-libc/include", + "-isystem", + _EBCLFSA_HI_ROOT + "/usr/lib/llvm-20/lib/clang/20/include", + "-fno-omit-frame-pointer", + "-ffunction-sections", + "-fdata-sections", +] +VERSION_MATRIX["aarch64-linux-sdk_2.0.0-beta3-ebclfsa-hi"] = dict( + VERSION_MATRIX["aarch64-linux-sdk_2.0.0-beta3-ebclfsa"], + compiler = "clang", + target_libc = "musl", + build_file = "@score_bazel_cpp_toolchains//packages/linux/aarch64/ebclfsa/2.0.0-beta3:ebclfsa_hi.BUILD", + # Keep host libraries local to the tools, not in the action environment: + # LD_LIBRARY_PATH would also affect Bazel's host process-wrapper. + patch_cmds = [ + "set -eu; sdk=$(pwd); libs=$sdk/usr/lib/x86_64-linux-gnu; " + + "loader=$libs/ld-linux-x86-64.so.2; " + + "tmp=$(mktemp -d); trap 'rm -rf \"$tmp\"' EXIT; " + + "cp \"$sdk/usr/bin/patchelf\" \"$tmp/patchelf\"; " + + "run_patchelf() { \"$loader\" --library-path \"$libs/sdk-libc:$libs\" \"$tmp/patchelf\" \"$@\"; }; " + + "for binary in usr/lib/llvm-20/bin/clang usr/lib/llvm-20/bin/lld " + + "usr/bin/aarch64-linux-gnu-ar usr/bin/aarch64-linux-gnu-strip " + + "usr/bin/aarch64-linux-gnu-readelf usr/bin/lisa-elf-enabler; do " + + "run_patchelf --set-interpreter \"$loader\" \"$binary\"; " + + "run_patchelf --force-rpath --set-rpath \"$libs/sdk-libc:$libs\" \"$binary\"; " + + "done; " + + "run_patchelf --force-rpath --set-rpath '$ORIGIN/sdk-libc:$ORIGIN' \"$libs/libLLVM.so.20.1\"", + ], + extra_c_compile_flags = _EBCLFSA_HI_C_FLAGS, + extra_cxx_compile_flags = [ + "-nostdinc++", + "-isystem", + _EBCLFSA_HI_ROOT + "/opt/lisa-libcxx/include/c++/v1", + "-fno-exceptions", + "-fno-rtti", + ] + _EBCLFSA_HI_C_FLAGS, + extra_link_flags = [ + "--target=aarch64-linux-gnu", + "--ld-path=" + _EBCLFSA_HI_ROOT + "/usr/lib/llvm-20/bin/ld.lld", + "-nostdlib", + "-static", + "-Wl,--start-group", + _EBCLFSA_HI_ROOT + "/opt/lisa-libcxx/lib/libc++.a", + _EBCLFSA_HI_ROOT + "/opt/lisa-libcxx/lib/libc++abi.a", + _EBCLFSA_HI_ROOT + "/usr/lib/llvm-20/lib/clang/20/lib/linux/libclang_rt.builtins-aarch64.a", + _EBCLFSA_HI_ROOT + "/opt/lisa-libc/lib/aarch64-linux-gnu/crt1.o", + _EBCLFSA_HI_ROOT + "/opt/lisa-libc/lib/aarch64-linux-gnu/libc.a", + "-Wl,--end-group", + ], +) diff --git a/templates/BUILD.template b/templates/BUILD.template index 6d1d822..7abf62a 100644 --- a/templates/BUILD.template +++ b/templates/BUILD.template @@ -44,7 +44,10 @@ make_sysroot_link_flags( %{tc_custom_features} # known_features must list every feature (enabled or opt-in); enabled_features is # the order-irrelevant subset that should start on. See get_feature_lists(). -_KNOWN_FEATURES, _ENABLED_FEATURES = get_feature_lists() +_KNOWN_FEATURES, _ENABLED_FEATURES = ( + get_feature_lists(runtime_ecosystem = "%{tc_runtime_es}") + if "%{tc_os}" == "linux" else get_feature_lists() +) filegroup( name = "empty", diff --git a/tests/.bazelrc b/tests/.bazelrc index cb4ad1f..3e3d728 100644 --- a/tests/.bazelrc +++ b/tests/.bazelrc @@ -114,3 +114,7 @@ build:aarch64-linux-ebclfsa-2.0.0-beta2 --extra_toolchains=@score_ebclfsa_2.0.0- build:aarch64-linux-ebclfsa-2.0.0-beta3 --config=shared build:aarch64-linux-ebclfsa-2.0.0-beta3 --platforms=@score_bazel_platforms//:aarch64-linux-sdk_2.0.0-beta3-ebclfsa build:aarch64-linux-ebclfsa-2.0.0-beta3 --extra_toolchains=@score_ebclfsa_2.0.0-beta3_toolchain//:aarch64-linux-sdk_2.0.0-beta3-ebclfsa + +build:aarch64-linux-ebclfsa-hi --config=shared +build:aarch64-linux-ebclfsa-hi --platforms=@score_bazel_platforms//:aarch64-linux-sdk_2.0.0-beta3-ebclfsa-hi +build:aarch64-linux-ebclfsa-hi --extra_toolchains=@score_ebclfsa_hi_toolchain//:aarch64-linux-sdk_2.0.0-beta3-ebclfsa-hi diff --git a/tests/BUILD b/tests/BUILD index 501e233..a753289 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -71,9 +71,20 @@ test_suite( # target so new tests only need to be added to the relevant suite above. # ============================================================================ +test_suite( + name = "ebclfsa_hi_tests", + tests = [ + "//ebclfsa_hi:configuration_test", + "//ebclfsa_hi:exceptions_rejected_test", + "//ebclfsa_hi:rtti_rejected_test", + "//ebclfsa_hi:runtime_test", + ], +) + test_suite( name = "all_tests", tests = [ + ":ebclfsa_hi_tests", ":feature_verification_tests", ":guardrail_tests", ":language_and_standards_tests", diff --git a/tests/MODULE.bazel b/tests/MODULE.bazel index 0bca1f7..10e1a0d 100644 --- a/tests/MODULE.bazel +++ b/tests/MODULE.bazel @@ -35,6 +35,8 @@ bazel_dep(name = "score_bazel_platforms", version = "1.1.0") git_override( module_name = "score_bazel_platforms", commit = "081dcf7bdbc94d05bbe354291e13a775dbf8f3e6", + patch_strip = 1, + patches = ["//patches:score_bazel_platforms-ebclfsa-hi.patch"], remote = "https://github.com/eclipse-score/bazel_platforms.git", ) @@ -224,6 +226,14 @@ gcc.toolchain( target_os = "linux", use_default_package = True, ) +gcc.toolchain( + name = "score_ebclfsa_hi_toolchain", + runtime_ecosystem = "ebclfsa-hi", + sdk_version = "2.0.0-beta3", + target_cpu = "aarch64", + target_os = "linux", + use_default_package = True, +) use_repo( gcc, "my_toolchain", @@ -233,6 +243,8 @@ use_repo( "score_autosd_10_toolchain", "score_ebclfsa_2.0.0-beta2_toolchain", "score_ebclfsa_2.0.0-beta3_toolchain", + "score_ebclfsa_hi_toolchain", + "score_ebclfsa_hi_toolchain_pkg", "score_gcc_toolchain", "score_gcc_toolchain_15", "score_gcc_toolchain_bp", diff --git a/tests/MODULE.bazel.lock b/tests/MODULE.bazel.lock index d182a48..ed9782a 100644 --- a/tests/MODULE.bazel.lock +++ b/tests/MODULE.bazel.lock @@ -1400,8 +1400,8 @@ }, "@@score_bazel_cpp_toolchains+//extensions:gcc.bzl%gcc": { "general": { - "bzlTransitiveDigest": "nsbKejNA4VOLaazXnN2o7EG2He4yPLlWVRa7tJ7JK0Q=", - "usagesDigest": "BkOcTZ5iNKR+5duxzNN9Vybfv5/191KgNSvkoOHbhGE=", + "bzlTransitiveDigest": "izgy/ujYOiU7xY3U8lVNBGhhr7Vq82WmtNDmKBWhRCk=", + "usagesDigest": "pR+TVhlRpqjkxePeXQSg5d+/ipnXwGImTIWJwzaKH+U=", "recordedInputs": [ "REPO_MAPPING:,score_bazel_cpp_toolchains score_bazel_cpp_toolchains+", "REPO_MAPPING:bazel_tools,rules_cc rules_cc+", @@ -1629,6 +1629,26 @@ "type": "" } }, + "score_ebclfsa_hi_toolchain_pkg": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/Elektrobit/eb_corbos_toolkit/releases/download/v2.0.0-beta3/fastdev-sdk-trixie-ebclfsa-ebcl-qemuarm64.tar.gz" + ], + "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/aarch64/ebclfsa/2.0.0-beta3:ebclfsa_hi.BUILD", + "files": {}, + "patch_args": [], + "patch_cmds": [ + "set -eu; sdk=$(pwd); libs=$sdk/usr/lib/x86_64-linux-gnu; loader=$libs/ld-linux-x86-64.so.2; tmp=$(mktemp -d); trap 'rm -rf \"$tmp\"' EXIT; cp \"$sdk/usr/bin/patchelf\" \"$tmp/patchelf\"; run_patchelf() { \"$loader\" --library-path \"$libs/sdk-libc:$libs\" \"$tmp/patchelf\" \"$@\"; }; for binary in usr/lib/llvm-20/bin/clang usr/lib/llvm-20/bin/lld usr/bin/aarch64-linux-gnu-ar usr/bin/aarch64-linux-gnu-strip usr/bin/aarch64-linux-gnu-readelf usr/bin/lisa-elf-enabler; do run_patchelf --set-interpreter \"$loader\" \"$binary\"; run_patchelf --force-rpath --set-rpath \"$libs/sdk-libc:$libs\" \"$binary\"; done; run_patchelf --force-rpath --set-rpath '$ORIGIN/sdk-libc:$ORIGIN' \"$libs/libLLVM.so.20.1\"" + ], + "patch_strip": 0, + "patch_tool": "", + "patches": [], + "sha256": "72632b0925b1440e6470b429a97c62fb391bb3bf304adb11e6b79fa4410affc3", + "strip_prefix": "fastdev-sdk-trixie-ebclfsa-ebcl-qemuarm64", + "type": "" + } + }, "score_gcc_toolchain_bp": { "repoRuleId": "@@score_bazel_cpp_toolchains+//rules:gcc.bzl%gcc_toolchain", "attributes": { @@ -2120,6 +2140,69 @@ "cc_toolchain_config": "@@score_bazel_cpp_toolchains+//templates:cc_toolchain_config.bzl.template", "use_base_constraints_only": false } + }, + "score_ebclfsa_hi_toolchain": { + "repoRuleId": "@@score_bazel_cpp_toolchains+//rules:gcc.bzl%gcc_toolchain", + "attributes": { + "extra_compile_flags": [], + "extra_c_compile_flags": [ + "--target=aarch64-linux-gnu", + "-nostdinc", + "-isystem", + "external/%{toolchain_pkg}%/opt/lisa-libc/include", + "-isystem", + "external/%{toolchain_pkg}%/usr/lib/llvm-20/lib/clang/20/include", + "-fno-omit-frame-pointer", + "-ffunction-sections", + "-fdata-sections" + ], + "extra_cxx_compile_flags": [ + "-nostdinc++", + "-isystem", + "external/%{toolchain_pkg}%/opt/lisa-libcxx/include/c++/v1", + "-fno-exceptions", + "-fno-rtti", + "--target=aarch64-linux-gnu", + "-nostdinc", + "-isystem", + "external/%{toolchain_pkg}%/opt/lisa-libc/include", + "-isystem", + "external/%{toolchain_pkg}%/usr/lib/llvm-20/lib/clang/20/include", + "-fno-omit-frame-pointer", + "-ffunction-sections", + "-fdata-sections" + ], + "extra_known_features": [], + "extra_enabled_features": [], + "extra_link_flags": [ + "--target=aarch64-linux-gnu", + "--ld-path=external/%{toolchain_pkg}%/usr/lib/llvm-20/bin/ld.lld", + "-nostdlib", + "-static", + "-Wl,--start-group", + "external/%{toolchain_pkg}%/opt/lisa-libcxx/lib/libc++.a", + "external/%{toolchain_pkg}%/opt/lisa-libcxx/lib/libc++abi.a", + "external/%{toolchain_pkg}%/usr/lib/llvm-20/lib/clang/20/lib/linux/libclang_rt.builtins-aarch64.a", + "external/%{toolchain_pkg}%/opt/lisa-libc/lib/aarch64-linux-gnu/crt1.o", + "external/%{toolchain_pkg}%/opt/lisa-libc/lib/aarch64-linux-gnu/libc.a", + "-Wl,--end-group" + ], + "license_info_variable": "", + "license_info_value": "", + "license_path": "/opt/score_qnx/license/licenses", + "sdk_version": "2.0.0-beta3", + "sdp_version": "", + "tc_compiler_library_search_paths": [], + "tc_cpu": "aarch64", + "tc_identifier": "sdk_2.0.0-beta3", + "tc_os": "linux", + "tc_pkg_repo": "score_ebclfsa_hi_toolchain_pkg", + "tc_system_toolchain": false, + "tc_runtime_ecosystem": "ebclfsa-hi", + "gcc_version": "", + "cc_toolchain_config": "@@score_bazel_cpp_toolchains+//templates:cc_toolchain_config.bzl.template", + "use_base_constraints_only": false + } } } } diff --git a/tests/README.md b/tests/README.md index fb3d011..de58ab2 100644 --- a/tests/README.md +++ b/tests/README.md @@ -43,6 +43,34 @@ bazel test --config x86_64-linux //:language_and_standards_tests - **`feature_verification/`** - Toolchain feature validation tests - **`language_and_standards/`** - C and C++ standard version tests +- **`ebclfsa_hi/`** - Restricted Clang/musl/libc++ SDK verification + +### EBcLfSA High Integrity (SDK 2.0.0-beta3) + +Run these commands from this directory: + +The test module applies the supplied platform patch and selects +`runtime_ecosystem = "ebclfsa-hi"`; the existing `ebclfsa` configuration remains QM. + +```bash +# Host-side configuration, static AArch64 ELF and rejected-language-feature checks +bazel test --config=aarch64-linux-ebclfsa-hi --test_lang_filters=-cc \ + //:ebclfsa_hi_tests //:guardrail_tests + +# Execute the cross-compiled C/C++ runtime test (requires qemu-user on the host) +bazel test --config=aarch64-linux-ebclfsa-hi \ + --run_under=/usr/bin/qemu-aarch64 //ebclfsa_hi:runtime_test +``` + +The runtime test checks Clang/AArch64, musl rather than glibc, libc++ rather than +libstdc++, disabled RTTI/exceptions, C11/C++17, C archiving and mixed C/C++ linking. +It exercises formatted C I/O and libc++ containers, algorithms and strings. +The host-side tests also verify that exception and `dynamic_cast` expressions +are rejected, and that the ELF has no interpreter or dynamic dependencies. +These tests are incompatible with QM platforms and are skipped there. + +Use the dedicated suite, not the unrestricted feature suite: the HI runtime +deliberately lacks features required by some general-purpose/GoogleTest tests. ## Documentation diff --git a/tests/ebclfsa_hi/BUILD b/tests/ebclfsa_hi/BUILD new file mode 100644 index 0000000..8870064 --- /dev/null +++ b/tests/ebclfsa_hi/BUILD @@ -0,0 +1,40 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") +load(":configuration_test.bzl", "configuration_test", "restriction_test") + +restriction_test( + name = "exceptions_rejected_test", + src = "exceptions.cpp", + diagnostic = "cannot use 'throw' with exceptions disabled", + target_compatible_with = ["@score_bazel_platforms//runtime_es:ebclfsa-hi"], +) + +restriction_test( + name = "rtti_rejected_test", + src = "rtti.cpp", + diagnostic = "use of dynamic_cast requires -frtti", + target_compatible_with = ["@score_bazel_platforms//runtime_es:ebclfsa-hi"], +) + +configuration_test( + name = "configuration_test", + binary = ":runtime_test", + readelf = "@score_ebclfsa_hi_toolchain_pkg//:readelf", + target_compatible_with = ["@score_bazel_platforms//runtime_es:ebclfsa-hi"], +) + +cc_library( + name = "c_runtime", + srcs = ["c_runtime.c"], + target_compatible_with = ["@score_bazel_platforms//runtime_es:ebclfsa-hi"], +) + +cc_test( + name = "runtime_test", + srcs = ["runtime_test.cpp"], + target_compatible_with = ["@score_bazel_platforms//runtime_es:ebclfsa-hi"], + deps = [":c_runtime"], +) diff --git a/tests/ebclfsa_hi/c_runtime.c b/tests/ebclfsa_hi/c_runtime.c new file mode 100644 index 0000000..3980729 --- /dev/null +++ b/tests/ebclfsa_hi/c_runtime.c @@ -0,0 +1,25 @@ +/* Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#if !defined(__clang__) || !defined(__aarch64__) +#error "The high-integrity toolchain must use Clang targeting AArch64" +#endif + +#ifdef __GLIBC__ +#error "High-integrity applications must not use glibc" +#endif + +_Static_assert(__STDC_VERSION__ >= 201112L, "C11 is required"); + +int check_c_runtime(void) { + char buffer[32]; + const uint64_t value = UINT64_C(123456789); + int length = snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)value); + return length == 9 && strcmp(buffer, "123456789") == 0; +} diff --git a/tests/ebclfsa_hi/configuration_test.bzl b/tests/ebclfsa_hi/configuration_test.bzl new file mode 100644 index 0000000..21e9f45 --- /dev/null +++ b/tests/ebclfsa_hi/configuration_test.bzl @@ -0,0 +1,125 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +"""Host-executed checks of the resolved high-integrity toolchain.""" + +load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") +load("@rules_cc//cc:defs.bzl", "cc_common") +load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cpp_toolchain", "use_cc_toolchain") + +def _impl(ctx): + toolchain = find_cpp_toolchain(ctx) + configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + for name in ["no_legacy_features", "default_compile_flags", "extra_c_compile_flags", "extra_cxx_compile_flags", "extra_link_flags"]: + if not cc_common.is_enabled(feature_configuration = configuration, feature_name = name): + fail("Required high-integrity feature is not enabled: " + name) + for name in ["supports_dynamic_linker", "shared_flag", "gcc_coverage_map_format", "coverage", "static_libgcc", "supports_fission"]: + if cc_common.is_enabled(feature_configuration = configuration, feature_name = name): + fail("Unsupported high-integrity feature is enabled: " + name) + + report = ctx.actions.declare_file(ctx.label.name + ".elf") + ctx.actions.run_shell( + inputs = depset([ctx.executable.binary], transitive = [toolchain.all_files]), + tools = [ctx.executable.readelf], + outputs = [report], + arguments = [ctx.executable.readelf.path, ctx.executable.binary.path, report.path], + command = """ +set -eu +"$1" -h -l -d "$2" > "$3" +if ! grep -q 'Machine:.*AArch64' "$3" || grep -Eq 'INTERP|NEEDED' "$3"; then + cat "$3" >&2 + echo "Expected a static AArch64 ELF with no dynamic loader or dependencies" >&2 + exit 1 +fi +""", + mnemonic = "HighIntegrityElf", + ) + script = ctx.actions.declare_file(ctx.label.name + ".sh") + ctx.actions.write( + script, + "#!/usr/bin/env bash\nset -eu\ncat \"$TEST_SRCDIR/" + ctx.workspace_name + "/" + report.short_path + "\"\n", + is_executable = True, + ) + return DefaultInfo(executable = script, runfiles = ctx.runfiles(files = [report])) + +configuration_test = rule( + implementation = _impl, + attrs = { + "binary": attr.label(executable = True, cfg = "target", mandatory = True), + "readelf": attr.label(executable = True, cfg = "exec", allow_single_file = True, mandatory = True), + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, + fragments = ["cpp"], + toolchains = use_cc_toolchain(), + test = True, +) + +def _restriction_impl(ctx): + toolchain = find_cpp_toolchain(ctx) + configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + variables = cc_common.create_compile_variables( + cc_toolchain = toolchain, + feature_configuration = configuration, + source_file = ctx.file.src.path, + ) + args = cc_common.get_memory_inefficient_command_line( + feature_configuration = configuration, + action_name = ACTION_NAMES.cpp_compile, + variables = variables, + ) + compiler = cc_common.get_tool_for_action( + feature_configuration = configuration, + action_name = ACTION_NAMES.cpp_compile, + ) + log = ctx.actions.declare_file(ctx.label.name + ".log") + ctx.actions.run_shell( + inputs = depset([ctx.file.src], transitive = [toolchain.all_files]), + outputs = [log], + arguments = [log.path, ctx.attr.diagnostic, compiler] + args + ["-fsyntax-only"], + command = """ +set -eu +log=$1 +diagnostic=$2 +shift 2 +if "$@" > "$log" 2>&1; then + echo "High-integrity compiler unexpectedly accepted restricted C++" >&2 + exit 1 +fi +if ! grep -Fq "$diagnostic" "$log"; then + cat "$log" >&2 + echo "Compilation failed for an unexpected reason" >&2 + exit 1 +fi +""", + mnemonic = "HighIntegrityRestriction", + ) + script = ctx.actions.declare_file(ctx.label.name + ".sh") + ctx.actions.write( + script, + "#!/usr/bin/env bash\nset -eu\ncat \"$TEST_SRCDIR/" + ctx.workspace_name + "/" + log.short_path + "\"\n", + is_executable = True, + ) + return DefaultInfo(executable = script, runfiles = ctx.runfiles(files = [log])) + +restriction_test = rule( + implementation = _restriction_impl, + attrs = { + "src": attr.label(allow_single_file = [".cpp"], mandatory = True), + "diagnostic": attr.string(mandatory = True), + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, + fragments = ["cpp"], + toolchains = use_cc_toolchain(), + test = True, +) diff --git a/tests/ebclfsa_hi/exceptions.cpp b/tests/ebclfsa_hi/exceptions.cpp new file mode 100644 index 0000000..edc92f4 --- /dev/null +++ b/tests/ebclfsa_hi/exceptions.cpp @@ -0,0 +1,8 @@ +/* Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void forbidden_exception() { + throw 1; +} diff --git a/tests/ebclfsa_hi/rtti.cpp b/tests/ebclfsa_hi/rtti.cpp new file mode 100644 index 0000000..a58f626 --- /dev/null +++ b/tests/ebclfsa_hi/rtti.cpp @@ -0,0 +1,14 @@ +/* Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +struct Base { + virtual ~Base() = default; +}; + +struct Derived : Base {}; + +Derived* forbidden_rtti(Base* object) { + return dynamic_cast(object); +} diff --git a/tests/ebclfsa_hi/runtime_test.cpp b/tests/ebclfsa_hi/runtime_test.cpp new file mode 100644 index 0000000..cc73de5 --- /dev/null +++ b/tests/ebclfsa_hi/runtime_test.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#if !defined(__clang__) || !defined(__aarch64__) +#error "The high-integrity toolchain must use Clang targeting AArch64" +#endif + +#ifndef _LIBCPP_VERSION +#error "High-integrity applications must use libc++" +#endif + +#if defined(__GLIBC__) || defined(__GLIBCXX__) +#error "QM runtime headers leaked into the high-integrity toolchain" +#endif + +#if defined(__EXCEPTIONS) || defined(__GXX_RTTI) || defined(__cpp_exceptions) || defined(__cpp_rtti) +#error "Exceptions and RTTI must be disabled" +#endif + +static_assert(__cplusplus >= 201703L, "C++17 is required"); + +extern "C" int check_c_runtime(void); + +int main() { + if (!check_c_runtime()) { + std::fputs("musl C runtime check failed\n", stderr); + return 1; + } + + std::vector values{3, 1, 2}; + std::sort(values.begin(), values.end()); + const std::array expected{1, 2, 3}; + const std::string message = std::string("high-integrity ") + "libc++"; + if (!std::equal(values.begin(), values.end(), expected.begin()) || + message != "high-integrity libc++") { + std::fputs("libc++ runtime check failed\n", stderr); + return 1; + } + return 0; +} diff --git a/tests/patches/BUILD b/tests/patches/BUILD new file mode 100644 index 0000000..3d205d5 --- /dev/null +++ b/tests/patches/BUILD @@ -0,0 +1,5 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +exports_files(["score_bazel_platforms-ebclfsa-hi.patch"]) diff --git a/tests/patches/score_bazel_platforms-ebclfsa-hi.patch b/tests/patches/score_bazel_platforms-ebclfsa-hi.patch new file mode 100644 index 0000000..45cd94c --- /dev/null +++ b/tests/patches/score_bazel_platforms-ebclfsa-hi.patch @@ -0,0 +1,34 @@ +diff --git a/runtime_es/BUILD b/runtime_es/BUILD +--- a/runtime_es/BUILD ++++ b/runtime_es/BUILD +@@ -38,6 +38,11 @@ constraint_value( + constraint_setting = ":runtime_ecosystem", + ) + ++constraint_value( ++ name = "ebclfsa-hi", ++ constraint_setting = ":runtime_ecosystem", ++) ++ + constraint_value( + name = "posix", + constraint_setting = ":runtime_ecosystem", +diff --git a/BUILD b/BUILD +--- a/BUILD ++++ b/BUILD +@@ -184,6 +184,15 @@ platform( + parents = [":aarch64-linux"], + ) + ++platform( ++ name = "aarch64-linux-sdk_2.0.0-beta3-ebclfsa-hi", ++ constraint_values = [ ++ "@score_bazel_platforms//version:sdk_2.0.0-beta3", ++ "@score_bazel_platforms//runtime_es:ebclfsa-hi", ++ ], ++ parents = [":aarch64-linux"], ++) ++ + # -------------------------------------------------------------------------------- + # List of aliases (deprecated targets) to keep compatibility + # -------------------------------------------------------------------------------- From 4483d9bac448faec98ae71fd5b25cc75ae8f654a Mon Sep 17 00:00:00 2001 From: Lutz Reinhardt Date: Mon, 9 Nov 2026 21:19:57 +0000 Subject: [PATCH 2/2] handle EBcLfSA as separate OS next to generic Linux due to different compiler flags --- docs/maintenance.md | 10 ++- docs/repository_layout.md | 6 +- features/custom/{linux => }/ebclfsa_hi/BUILD | 2 + .../custom/ebclfsa_hi/make_cc_features.bzl | 62 +++++++++++++++++++ features/custom/linux/make_cc_features.bzl | 32 +--------- rules/gcc.bzl | 1 + templates/BUILD.template | 7 +-- tests/BUILD | 1 + tests/MODULE.bazel.lock | 2 +- tests/guardrails/BUILD | 6 ++ tests/guardrails/feature_lists_test.bzl | 45 ++++++++++++++ 11 files changed, 134 insertions(+), 40 deletions(-) rename features/custom/{linux => }/ebclfsa_hi/BUILD (92%) create mode 100644 features/custom/ebclfsa_hi/make_cc_features.bzl create mode 100644 tests/guardrails/feature_lists_test.bzl diff --git a/docs/maintenance.md b/docs/maintenance.md index 979af71..5f6f63d 100644 --- a/docs/maintenance.md +++ b/docs/maintenance.md @@ -88,16 +88,22 @@ it defines no features of its own. `sysroot_link_flags`, ...), including the capability markers (`dbg`, `opt`, `supports_pic`, ...). These mirror the removed legacy Bazel C++ features one-for-one. -- `features/custom/linux/` and `features/custom/qnx/`: OS-specific features +- `features/custom/linux/`, `features/custom/qnx/`, and + `features/custom/ebclfsa_hi/`: OS-specific features not covered by the native set (QNX `sdp_env`, `gcc_version_flags`), plus `make_cc_features.bzl`, which defines the ordered `_LINUX_FEATURES` / - `_QNX_FEATURES` lists of `(label, initially_enabled)` pairs. Order here + `_QNX_FEATURES` / `_EBCLFSA_HI_FEATURES` lists of + `(label, initially_enabled)` pairs. Order here mirrors the previous templates' `features = [...]` order exactly, since feature order determines command-line flag order. `get_feature_lists()` returns `(known_features, enabled_features)`, and `templates/BUILD.template` passes those straight into `cc_toolchain_config`'s `known_features` / `enabled_features` attributes — this is what the generated toolchain actually uses. + The repository rule selects `ebclfsa_hi` for Linux toolchains with + `runtime_ecosystem = "ebclfsa-hi"`; otherwise it selects the target OS. + This keeps the restricted HI compile flags and feature list separate from + generic Linux without changing platform OS constraints. - Per-instance features whose content is dynamic per toolchain instance — `extra_compile_flags`, `extra_c_compile_flags`, `extra_cxx_compile_flags`, `extra_link_flags`, `compiler_library_search_paths`, `sysroot_link_flags` — diff --git a/docs/repository_layout.md b/docs/repository_layout.md index e0870b6..91f2ea6 100644 --- a/docs/repository_layout.md +++ b/docs/repository_layout.md @@ -54,7 +54,8 @@ required extra flags. Holds declarative `cc_feature` / `cc_args` toolchain-feature definitions built with `@rules_cc//cc/toolchains`. `features/native/` has one reusable target per toolchain feature (mirroring the legacy Bazel C++ features); the -OS-specific `features/custom/linux/` and `features/custom/qnx/` packages hold +OS-specific `features/custom/linux/`, `features/custom/qnx/`, and +`features/custom/ebclfsa_hi/` packages hold platform-only features (e.g. QNX `sdp_env`, `gcc_version_flags`) plus the ordered `known_features`/`enabled_features` lists that `templates/BUILD.template` passes to `cc_toolchain_config`. @@ -64,7 +65,8 @@ ordered `known_features`/`enabled_features` lists that Holds the shared template files rendered by repository rules into the generated toolchain repository: `BUILD.template`, `cc_toolchain_config.bzl.template`, and `cc_gcov_wrapper.template`. A single -template pair now covers both Linux and QNX; OS-specific behavior comes from +template pair covers Linux, QNX, and the EBcLfSA HI feature profile; +OS-specific behavior comes from placeholder substitution in `rules/gcc.bzl` and from the OS-specific feature lists in `features/custom/`, not from separate template directories. diff --git a/features/custom/linux/ebclfsa_hi/BUILD b/features/custom/ebclfsa_hi/BUILD similarity index 92% rename from features/custom/linux/ebclfsa_hi/BUILD rename to features/custom/ebclfsa_hi/BUILD index a1a3ced..055d25c 100644 --- a/features/custom/linux/ebclfsa_hi/BUILD +++ b/features/custom/ebclfsa_hi/BUILD @@ -2,6 +2,8 @@ # # SPDX-License-Identifier: Apache-2.0 +"""EBcLfSA High Integrity-specific compiler features.""" + load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature") package(default_visibility = ["//visibility:public"]) diff --git a/features/custom/ebclfsa_hi/make_cc_features.bzl b/features/custom/ebclfsa_hi/make_cc_features.bzl new file mode 100644 index 0000000..1a875c7 --- /dev/null +++ b/features/custom/ebclfsa_hi/make_cc_features.bzl @@ -0,0 +1,62 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* + +_EBCLFSA_HI_FEATURES = [ + ("@score_bazel_cpp_toolchains//features/native/markers:no_legacy_features", True), + (":compiler_library_search_paths", True), # per-instance, see templates/BUILD.template + ("@score_bazel_cpp_toolchains//features/native/markers:dbg", False), + ("@score_bazel_cpp_toolchains//features/native/unfiltered_compile_flags", True), + ("@score_bazel_cpp_toolchains//features/native/markers:gnu11", False), + ("@score_bazel_cpp_toolchains//features/native/markers:c_std_c99", False), + ("@score_bazel_cpp_toolchains//features/custom/ebclfsa_hi:compile_flags", True), + ("@score_bazel_cpp_toolchains//features/native/random_seed", True), + ("@score_bazel_cpp_toolchains//features/native/include_paths", True), + ("@score_bazel_cpp_toolchains//features/native/preprocessor_defines", True), + (":extra_compile_flags", True), # per-instance, see templates/BUILD.template + (":extra_c_compile_flags", True), # per-instance, see templates/BUILD.template + (":extra_cxx_compile_flags", True), # per-instance, see templates/BUILD.template + ("@score_bazel_cpp_toolchains//features/native/user_compile_flags", True), + ("@score_bazel_cpp_toolchains//features/native/compiler_input_flags", True), + ("@score_bazel_cpp_toolchains//features/native/compiler_output_flags", True), + ("@score_bazel_cpp_toolchains//features/native/dependency_file", True), + ("@score_bazel_cpp_toolchains//features/native/per_object_debug_info", True), + ("@score_bazel_cpp_toolchains//features/native/includes", True), + ("@score_bazel_cpp_toolchains//features/native/archiver_flags", True), + ("@score_bazel_cpp_toolchains//features/native/linker_param_file", True), + ("@score_bazel_cpp_toolchains//features/native/library_search_directories", True), + ("@score_bazel_cpp_toolchains//features/native/output_execpath_flags", True), + ("@score_bazel_cpp_toolchains//features/native/libraries_to_link", True), + ("@score_bazel_cpp_toolchains//features/native/user_link_flags", True), + (":extra_link_flags", True), # per-instance, see templates/BUILD.template + ("@score_bazel_cpp_toolchains//features/native/linkstamps", True), + ("@score_bazel_cpp_toolchains//features/native/force_pic_flags", True), + ("@score_bazel_cpp_toolchains//features/native/strip_debug_symbols", True), + ("@score_bazel_cpp_toolchains//features/native/fully_static_link", False), + (":sysroot_link_flags", True), # per-instance, see templates/BUILD.template + ("@score_bazel_cpp_toolchains//features/native/use_pthread", True), + ("@score_bazel_cpp_toolchains//features/native/markers:opt", False), + ("@score_bazel_cpp_toolchains//features/native/markers:supports_pic", True), + ("@score_bazel_cpp_toolchains//features/native/pic", True), + ("@score_bazel_cpp_toolchains//features/native/markers:supports_header_path_normalization", True), +] + +def get_feature_lists(): + """Returns ordered known/enabled feature labels for EBcLfSA High Integrity. + + Returns: + (known_features, enabled_features) tuple of flat label lists. + """ + return ( + [label for label, _enabled in _EBCLFSA_HI_FEATURES], + [label for label, enabled in _EBCLFSA_HI_FEATURES if enabled], + ) diff --git a/features/custom/linux/make_cc_features.bzl b/features/custom/linux/make_cc_features.bzl index 3624c09..54a7e0a 100644 --- a/features/custom/linux/make_cc_features.bzl +++ b/features/custom/linux/make_cc_features.bzl @@ -67,38 +67,10 @@ def linux_enabled_features(): """Subset of Linux feature labels that start enabled — order is irrelevant here.""" return [label for label, enabled in _LINUX_FEATURES if enabled] -def get_feature_lists(runtime_ecosystem = ""): +def get_feature_lists(): """Returns the flat known/enabled feature label lists for Linux. - Args: - runtime_ecosystem: Select the feature profile for this runtime. - Returns: (known_features, enabled_features) tuple of flat label lists. """ - if runtime_ecosystem != "ebclfsa-hi": - return linux_known_features(), linux_enabled_features() - - omitted = [ - "default_link_flags", - "static_libgcc", - "gcc_coverage_map_format", - "coverage", - "supports_dynamic_linker", - "shared_flag", - "runtime_library_search_directories", - "fission_support", - "supports_fission", - ] - features = [ - ( - "@score_bazel_cpp_toolchains//features/custom/linux/ebclfsa_hi:compile_flags" if label == "@score_bazel_cpp_toolchains//features/native/default_compile_flags" else label, - enabled, - ) - for label, enabled in _LINUX_FEATURES - if label.split(":")[-1].split("/")[-1] not in omitted - ] - return ( - [label for label, _enabled in features], - [label for label, enabled in features if enabled], - ) + return linux_known_features(), linux_enabled_features() diff --git a/rules/gcc.bzl b/rules/gcc.bzl index 05dd175..efcaaa8 100644 --- a/rules/gcc.bzl +++ b/rules/gcc.bzl @@ -280,6 +280,7 @@ def _impl(rctx): "%{tc_cpu}": rctx.attr.tc_cpu, "%{tc_identifier}": tc_identifier, "%{tc_os}": rctx.attr.tc_os, + "%{tc_feature_os}": "ebclfsa_hi" if rctx.attr.tc_os == _OS_LINUX and rctx.attr.tc_runtime_ecosystem == "ebclfsa-hi" else rctx.attr.tc_os, "%{tc_pkg_repo}": rctx.attr.tc_pkg_repo, "%{tc_runtime_es}": rctx.attr.tc_runtime_ecosystem, "%{tc_version}": rctx.attr.gcc_version, diff --git a/templates/BUILD.template b/templates/BUILD.template index 7abf62a..3ba32be 100644 --- a/templates/BUILD.template +++ b/templates/BUILD.template @@ -15,7 +15,7 @@ """ load("@rules_cc//cc:defs.bzl", "cc_toolchain") -load("@score_bazel_cpp_toolchains//features/custom/%{tc_os}:make_cc_features.bzl", "get_feature_lists") +load("@score_bazel_cpp_toolchains//features/custom/%{tc_feature_os}:make_cc_features.bzl", "get_feature_lists") load("@score_bazel_cpp_toolchains//features/native/extra_compile_flags:features.bzl", "make_extra_compile_features") load("@score_bazel_cpp_toolchains//features/native/extra_link_flags:features.bzl", "make_extra_link_features") load("@score_bazel_cpp_toolchains//features/native/compiler_library_search_paths:features.bzl", "make_compiler_library_search_paths") @@ -44,10 +44,7 @@ make_sysroot_link_flags( %{tc_custom_features} # known_features must list every feature (enabled or opt-in); enabled_features is # the order-irrelevant subset that should start on. See get_feature_lists(). -_KNOWN_FEATURES, _ENABLED_FEATURES = ( - get_feature_lists(runtime_ecosystem = "%{tc_runtime_es}") - if "%{tc_os}" == "linux" else get_feature_lists() -) +_KNOWN_FEATURES, _ENABLED_FEATURES = get_feature_lists() filegroup( name = "empty", diff --git a/tests/BUILD b/tests/BUILD index a753289..0b186bc 100644 --- a/tests/BUILD +++ b/tests/BUILD @@ -60,6 +60,7 @@ test_suite( test_suite( name = "guardrail_tests", tests = [ + "//guardrails:feature_lists_test", "//guardrails:no_legacy_features_guard_test", ], ) diff --git a/tests/MODULE.bazel.lock b/tests/MODULE.bazel.lock index ed9782a..89012ba 100644 --- a/tests/MODULE.bazel.lock +++ b/tests/MODULE.bazel.lock @@ -1400,7 +1400,7 @@ }, "@@score_bazel_cpp_toolchains+//extensions:gcc.bzl%gcc": { "general": { - "bzlTransitiveDigest": "izgy/ujYOiU7xY3U8lVNBGhhr7Vq82WmtNDmKBWhRCk=", + "bzlTransitiveDigest": "JGlxCTNSgVs79PkM9q+OKNohhtSpSE8tHCBKaYwNyFg=", "usagesDigest": "pR+TVhlRpqjkxePeXQSg5d+/ipnXwGImTIWJwzaKH+U=", "recordedInputs": [ "REPO_MAPPING:,score_bazel_cpp_toolchains score_bazel_cpp_toolchains+", diff --git a/tests/guardrails/BUILD b/tests/guardrails/BUILD index a81eb99..1fcaa58 100644 --- a/tests/guardrails/BUILD +++ b/tests/guardrails/BUILD @@ -13,8 +13,14 @@ """Regression guardrail for the explicit-feature (`no_legacy_features`) model.""" +load(":feature_lists_test.bzl", "feature_lists_test") load(":legacy_feature_guard.bzl", "no_legacy_features_guard_test") +feature_lists_test( + name = "feature_lists_test", + visibility = ["//visibility:public"], +) + # Validates the C++ toolchain resolved for the current --config. Run it under # each platform config (x86_64-linux, aarch64-linux, x86_64-qnx, ...) to cover # the whole toolchain matrix. diff --git a/tests/guardrails/feature_lists_test.bzl b/tests/guardrails/feature_lists_test.bzl new file mode 100644 index 0000000..0156689 --- /dev/null +++ b/tests/guardrails/feature_lists_test.bzl @@ -0,0 +1,45 @@ +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# SPDX-License-Identifier: Apache-2.0 + +"""Regression checks for the independent Linux and EBcLfSA HI feature lists.""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("@score_bazel_cpp_toolchains//features/custom/ebclfsa_hi:make_cc_features.bzl", hi_features = "get_feature_lists") +load("@score_bazel_cpp_toolchains//features/custom/linux:make_cc_features.bzl", linux_features = "get_feature_lists") + +def _feature_lists_test_impl(ctx): + env = unittest.begin(ctx) + linux_known, linux_enabled = linux_features() + hi_known, hi_enabled = hi_features() + native = "@score_bazel_cpp_toolchains//features/native/" + compile_flags = "@score_bazel_cpp_toolchains//features/custom/ebclfsa_hi:compile_flags" + omitted = [ + native + "default_link_flags", + native + "static_libgcc", + native + "gcc_coverage_map_format", + native + "markers:coverage", + native + "markers:supports_dynamic_linker", + native + "shared_flag", + native + "runtime_library_search_directories", + native + "fission_support", + native + "markers:supports_fission", + ] + for label in omitted: + asserts.true(env, label in linux_known, "Linux must retain " + label) + asserts.false(env, label in hi_known, "HI must not offer " + label) + asserts.false(env, compile_flags in linux_known) + asserts.true(env, native + "default_compile_flags" in linux_enabled) + asserts.true(env, compile_flags in hi_enabled) + + # Preserve the existing flag order and defaults when separating the profiles. + for linux, hi in [(linux_known, hi_known), (linux_enabled, hi_enabled)]: + expected = [ + compile_flags if label == native + "default_compile_flags" else label + for label in linux + if label not in omitted + ] + asserts.equals(env, expected, hi) + return unittest.end(env) + +feature_lists_test = unittest.make(_feature_lists_test_impl)