From 7d34b2ebba3765501e4eee6eea5666f74ccb6729 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 10 Feb 2026 08:58:06 +0100 Subject: [PATCH 1/6] Allow providing extra C/C++ flags As well as allowing to have a %{toolchain_pkg}% placeholder in the flags that would be replaced with the canonical name of the toolchain. --- extensions/gcc.bzl | 14 +++++++++ rules/gcc.bzl | 28 +++++++++++++++-- .../linux/cc_toolchain_config.bzl.template | 30 +++++++++++++++++-- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/extensions/gcc.bzl b/extensions/gcc.bzl index 6b6b8fe..1d44e74 100644 --- a/extensions/gcc.bzl +++ b/extensions/gcc.bzl @@ -115,6 +115,16 @@ _attrs_tc = { default = [], doc = "List of additional flags to be passed to compiler.", ), + "extra_c_compile_flags": attr.string_list( + mandatory = False, + default = [], + doc = "List of additional flags to be passed to C compiler.", + ), + "extra_cxx_compile_flags": attr.string_list( + mandatory = False, + default = [], + doc = "List of additional flags to be passed to C++ compiler.", + ), "extra_link_flags": attr.string_list( mandatory = False, default = [], @@ -163,6 +173,8 @@ def _get_toolchains(tags): "use_default_package": tag.use_default_package, "use_system_toolchain": tag.use_system_toolchain, "tc_extra_compile_flags": tag.extra_compile_flags, + "tc_extra_c_compile_flags": tag.extra_c_compile_flags, + "tc_extra_cxx_compile_flags": tag.extra_cxx_compile_flags, "tc_extra_link_flags": tag.extra_link_flags, "sdp_version": tag.sdp_version, "tc_license_info_variable": tag.license_info_variable, @@ -250,6 +262,8 @@ def _impl(mctx): gcc_toolchain( name = toolchain_info["name"], extra_compile_flags = toolchain_info["tc_extra_compile_flags"], + extra_c_compile_flags = toolchain_info["tc_extra_c_compile_flags"], + extra_cxx_compile_flags = toolchain_info["tc_extra_cxx_compile_flags"], extra_link_flags = toolchain_info["tc_extra_link_flags"], license_info_variable = toolchain_info["tc_license_info_variable"], license_info_value = toolchain_info["tc_license_info_url"], diff --git a/rules/gcc.bzl b/rules/gcc.bzl index dc209d1..69263f8 100644 --- a/rules/gcc.bzl +++ b/rules/gcc.bzl @@ -115,8 +115,26 @@ def _impl(rctx): }, ) - extra_compile_flags = get_flag_groups(rctx.attr.extra_compile_flags) - extra_link_flags = get_flag_groups(rctx.attr.extra_link_flags) + # Get canonical repository name for the toolchain package + # In bzlmod, repos created by module extensions follow the pattern: module++extension+repo_name + # Get our own canonical name (e.g., "score_bazel_cpp_toolchains++gcc+score_autosd_10_toolchain") + # and replace our repo name with the package repo name + my_canonical_name = rctx.name + if "++" in my_canonical_name: + parts = my_canonical_name.rsplit("+", 1) + prefix = parts[0] + "+" + canonical_pkg_name = prefix + rctx.attr.tc_pkg_repo + else: + canonical_pkg_name = rctx.attr.tc_pkg_repo + + # Replace %{toolchain_pkg}% placeholder in extra flags with canonical name + def replace_placeholder(flags): + return [flag.replace("%{toolchain_pkg}%", canonical_pkg_name) for flag in flags] + + extra_compile_flags = get_flag_groups(replace_placeholder(rctx.attr.extra_compile_flags)) + extra_c_compile_flags = get_flag_groups(replace_placeholder(rctx.attr.extra_c_compile_flags)) + extra_cxx_compile_flags = get_flag_groups(replace_placeholder(rctx.attr.extra_cxx_compile_flags)) + extra_link_flags = get_flag_groups(replace_placeholder(rctx.attr.extra_link_flags)) template_dict = { @@ -126,6 +144,10 @@ def _impl(rctx): "%{tc_runtime_es}": rctx.attr.tc_runtime_ecosystem, "%{extra_compile_flags_switch}": "True" if len(rctx.attr.extra_compile_flags) else "False", "%{extra_compile_flags}":extra_compile_flags, + "%{extra_c_compile_flags_switch}": "True" if len(rctx.attr.extra_c_compile_flags) else "False", + "%{extra_c_compile_flags}": extra_c_compile_flags, + "%{extra_cxx_compile_flags_switch}": "True" if len(rctx.attr.extra_cxx_compile_flags) else "False", + "%{extra_cxx_compile_flags}": extra_cxx_compile_flags, "%{extra_link_flags_switch}": "True" if len(rctx.attr.extra_link_flags) else "False", "%{extra_link_flags}": extra_link_flags, } @@ -175,6 +197,8 @@ gcc_toolchain = repository_rule( "tc_os": attr.string(doc="Target platform OS."), "gcc_version": attr.string(doc="GCC version number"), "extra_compile_flags": attr.string_list(doc="Extra/Additional compile flags."), + "extra_c_compile_flags": attr.string_list(doc="Extra/Additional C-specific compile flags."), + "extra_cxx_compile_flags": attr.string_list(doc="Extra/Additional C++-specific compile flags."), "extra_link_flags": attr.string_list(doc="Extra/Additional link flags."), "sdp_version": attr.string(doc="SDP version number"), "license_path": attr.string(doc="Lincese path"), diff --git a/templates/linux/cc_toolchain_config.bzl.template b/templates/linux/cc_toolchain_config.bzl.template index 23412f8..848fd68 100644 --- a/templates/linux/cc_toolchain_config.bzl.template +++ b/templates/linux/cc_toolchain_config.bzl.template @@ -501,6 +501,32 @@ def _impl(ctx): ], ) + extra_c_compile_flags = %{extra_c_compile_flags} + extra_c_compile_flags_feature = feature( + name = "extra_c_compile_flags", + enabled = %{extra_c_compile_flags_switch}, + implies = ["default_compile_flags"], + flag_sets = [ + flag_set( + actions = all_c_compile_actions, + flag_groups = extra_c_compile_flags, + ), + ], + ) + + extra_cxx_compile_flags = %{extra_cxx_compile_flags} + extra_cxx_compile_flags_feature = feature( + name = "extra_cxx_compile_flags", + enabled = %{extra_cxx_compile_flags_switch}, + implies = ["default_compile_flags"], + flag_sets = [ + flag_set( + actions = all_cpp_compile_actions, + flag_groups = extra_cxx_compile_flags, + ), + ], + ) + extra_link_flags = %{extra_link_flags} extra_link_flags_feature = feature( name = "extra_link_flags", @@ -574,8 +600,8 @@ def _impl(ctx): all_wall_warnings_feature, warnings_as_errors_feature, extra_compile_flags_feature, - # extra_c_compile_flags_feature, - # extra_cxx_compile_flags_feature, + extra_c_compile_flags_feature, + extra_cxx_compile_flags_feature, extra_link_flags_feature, opt_feature, supports_dynamic_linker_feature, From d498e4c4b13f4391443f92a855b7b29fd6c1858a Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 10 Feb 2026 09:00:13 +0100 Subject: [PATCH 2/6] Enable header path normalization feature Needed for toolchains like autosd. --- templates/linux/cc_toolchain_config.bzl.template | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/templates/linux/cc_toolchain_config.bzl.template b/templates/linux/cc_toolchain_config.bzl.template index 848fd68..0ea0e85 100644 --- a/templates/linux/cc_toolchain_config.bzl.template +++ b/templates/linux/cc_toolchain_config.bzl.template @@ -555,6 +555,12 @@ def _impl(ctx): supports_pic_feature = feature(name = "supports_pic", enabled = True) + # Feature to disable absolute path warnings for system headers + supports_header_path_normalization = feature( + name = "supports_header_path_normalization", + enabled = True, + ) + coverage_feature = feature(name = "coverage") gcc_coverage_map_format_feature = feature( name = "gcc_coverage_map_format", @@ -606,6 +612,7 @@ def _impl(ctx): opt_feature, supports_dynamic_linker_feature, supports_pic_feature, + supports_header_path_normalization, supports_fission_feature, coverage_feature, gcc_coverage_map_format_feature, From 7ed0e6df7ddff2a4596b36520e1c19c71c1b2eb1 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 10 Feb 2026 09:02:18 +0100 Subject: [PATCH 3/6] Pass include_directories from the toolchain So that a toolchain can define it own include directories. --- templates/linux/cc_toolchain_config.bzl.template | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/linux/cc_toolchain_config.bzl.template b/templates/linux/cc_toolchain_config.bzl.template index 0ea0e85..bce76e4 100644 --- a/templates/linux/cc_toolchain_config.bzl.template +++ b/templates/linux/cc_toolchain_config.bzl.template @@ -618,7 +618,10 @@ def _impl(ctx): gcc_coverage_map_format_feature, ] + # Get builtin include directories from attribute if provided cxx_builtin_include_directories = [] + if hasattr(ctx.attr, "builtin_include_directories") and ctx.attr.builtin_include_directories: + cxx_builtin_include_directories = ctx.attr.builtin_include_directories # TODO: Once https://github.com/bazelbuild/rules_cc/issues/351 is fixed remove this. tool_paths = [tool_path(name = "gcov", path = "gcov_wrapper")] @@ -658,6 +661,6 @@ cc_toolchain_config = rule( "sysroot": attr.label(default = None), "host_dir": attr.label(default = None), "target_dir": attr.label(default = None), - "cxx_builtin_include_directories": attr.label(default = None), + "cxx_builtin_include_directories": attr.label(allow_files = True, default = None), }, ) \ No newline at end of file From 97dc61b952b67066964080d63452bf9518d23938 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 10 Feb 2026 09:03:19 +0100 Subject: [PATCH 4/6] Various linker flags tweaks Mostly adding a sysroot if provided as well as tweaking the default flags handling so that a toolchain can override the linking flags. Given that the default ones are not compatible with autosd. --- .../linux/cc_toolchain_config.bzl.template | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/templates/linux/cc_toolchain_config.bzl.template b/templates/linux/cc_toolchain_config.bzl.template index bce76e4..fedd80a 100644 --- a/templates/linux/cc_toolchain_config.bzl.template +++ b/templates/linux/cc_toolchain_config.bzl.template @@ -210,9 +210,33 @@ def _impl(ctx): ], ) + # Add sysroot linker flags as a separate feature (always enabled) + sysroot_link_flags_feature_flag_sets = [] + if ctx.attr.sysroot != None: + sysroot_files = ctx.attr.sysroot[DefaultInfo].files.to_list() + if sysroot_files: + sysroot_path = sysroot_files[0].path + sysroot_link_flags_feature_flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = [ + "--sysroot=" + sysroot_path, + "-Wl,--sysroot=" + sysroot_path, + ])], + ), + ] + + sysroot_link_flags_feature = feature( + name = "sysroot_link_flags", + enabled = True, + flag_sets = sysroot_link_flags_feature_flag_sets, + ) + + # Only enable default link flags if extra link flags are not provided + default_link_flags_enabled = not %{extra_link_flags_switch} default_link_flags_feature = feature( name = "default_link_flags", - enabled = True, + enabled = default_link_flags_enabled, flag_sets = [ flag_set( actions = all_link_actions, @@ -531,7 +555,6 @@ def _impl(ctx): extra_link_flags_feature = feature( name = "extra_link_flags", enabled = %{extra_link_flags_switch}, - implies = ["default_link_flags"], flag_sets = [ flag_set( actions = all_link_actions, @@ -600,6 +623,7 @@ def _impl(ctx): unfiltered_compile_flags_feature, default_compile_flags_feature, default_link_flags_feature, + sysroot_link_flags_feature, pthread_feature, minimal_warnings_feature, strict_warnings_feature, From ae99156b150b377c71a171489a747cba1e128bc7 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 10 Feb 2026 09:04:31 +0100 Subject: [PATCH 5/6] Allow toolchains to define their own build/link flags In versions_matrix for now, no idea if we could that better... --- extensions/gcc.bzl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/extensions/gcc.bzl b/extensions/gcc.bzl index 1d44e74..8b847d0 100644 --- a/extensions/gcc.bzl +++ b/extensions/gcc.bzl @@ -204,6 +204,14 @@ def _create_and_link_sdp(toolchain_info): ) matrix = VERSION_MATRIX[matrix_key] toolchain_info["sdp_to_link"] = pkg_name + + if "extra_c_compile_flags" in matrix and not toolchain_info["tc_extra_c_compile_flags"]: + toolchain_info["tc_extra_c_compile_flags"] = matrix["extra_c_compile_flags"] + if "extra_cxx_compile_flags" in matrix and not toolchain_info["tc_extra_cxx_compile_flags"]: + toolchain_info["tc_extra_cxx_compile_flags"] = matrix["extra_cxx_compile_flags"] + if "extra_link_flags" in matrix and not toolchain_info["tc_extra_link_flags"]: + toolchain_info["tc_extra_link_flags"] = matrix["extra_link_flags"] + return { "name": pkg_name, "url": matrix["url"], From ef7ab7682cce86ade66013afd214571044901b64 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Tue, 3 Feb 2026 11:10:08 +0100 Subject: [PATCH 6/6] packages: Add AutoSD 10 support --- examples/MODULE.bazel | 20 +++--- packages/linux/aarch64/autosd/10.0/BUILD | 16 +++++ .../linux/aarch64/autosd/10.0/autosd.BUILD | 61 ++++++++++++++++ packages/linux/x86_64/autosd/10.0/BUILD | 16 +++++ .../linux/x86_64/autosd/10.0/autosd.BUILD | 71 +++++++++++++++++++ packages/version_matrix.bzl | 52 ++++++++++++++ 6 files changed, 226 insertions(+), 10 deletions(-) create mode 100644 packages/linux/aarch64/autosd/10.0/BUILD create mode 100644 packages/linux/aarch64/autosd/10.0/autosd.BUILD create mode 100644 packages/linux/x86_64/autosd/10.0/BUILD create mode 100644 packages/linux/x86_64/autosd/10.0/autosd.BUILD diff --git a/examples/MODULE.bazel b/examples/MODULE.bazel index 2456ac2..73e8d1e 100644 --- a/examples/MODULE.bazel +++ b/examples/MODULE.bazel @@ -139,18 +139,17 @@ gcc.toolchain( # use_system_toolchain = True, # ) -# TODO: Not yet supported # ******************************************************************************* -# Setting AutoSD GCC (CPU:x86_64|OS:Linux|V:unknown|ES:autosd) +# Setting AutoSD 10 GCC (CPU:x86_64|OS:Linux|V:autosd-10.0|ES:autosd) # ******************************************************************************* -# gcc.toolchain( -# name = "score_autosd_9_toolchain", -# target_cpu = "x86_64", -# target_os = "linux", -# runtime_ecosystem = "autosd", -# version = "9", -# use_system_toolchain = True, -# ) +gcc.toolchain( + name = "score_autosd_10_toolchain", + target_cpu = "x86_64", + target_os = "linux", + runtime_ecosystem = "autosd", + version = "autosd-10.0", + use_default_package = True, +) use_repo( gcc, @@ -159,4 +158,5 @@ use_repo( "my_toolchain", "score_qcc_toolchain", "score_qcc_arm_toolchain", + "score_autosd_10_toolchain", ) \ No newline at end of file diff --git a/packages/linux/aarch64/autosd/10.0/BUILD b/packages/linux/aarch64/autosd/10.0/BUILD new file mode 100644 index 0000000..3f98d7c --- /dev/null +++ b/packages/linux/aarch64/autosd/10.0/BUILD @@ -0,0 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2025 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 +# ******************************************************************************* + +exports_files([ + "autosd.BUILD", +]) \ No newline at end of file diff --git a/packages/linux/aarch64/autosd/10.0/autosd.BUILD b/packages/linux/aarch64/autosd/10.0/autosd.BUILD new file mode 100644 index 0000000..daedfc5 --- /dev/null +++ b/packages/linux/aarch64/autosd/10.0/autosd.BUILD @@ -0,0 +1,61 @@ +# ******************************************************************************* +# Copyright (c) 2025 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 +# ******************************************************************************* + +"""Build file for AutoSD 10 GCC toolchain package""" + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "all_files", + srcs = glob(["*/**/*"]), +) + +filegroup( + name = "bin", + srcs = ["usr/bin"], +) + +filegroup( + name = "ar", + srcs = ["usr/bin/ar"], +) + +filegroup( + name = "cc", + srcs = ["usr/bin/gcc"], +) + +filegroup( + name = "gcov", + srcs = ["usr/bin/gcov"], +) + +filegroup( + name = "cxx", + srcs = ["usr/bin/g++"], +) + +filegroup( + name = "strip", + srcs = ["usr/bin/strip"], +) + +# The sysroot for AutoSD is the entire extracted directory +# since it contains usr/ and lib64/ at the root +filegroup( + name = "sysroot_dir", + srcs = glob([ + "usr/**", + "lib64/**", + ]), +) diff --git a/packages/linux/x86_64/autosd/10.0/BUILD b/packages/linux/x86_64/autosd/10.0/BUILD new file mode 100644 index 0000000..3f98d7c --- /dev/null +++ b/packages/linux/x86_64/autosd/10.0/BUILD @@ -0,0 +1,16 @@ +# ******************************************************************************* +# Copyright (c) 2025 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 +# ******************************************************************************* + +exports_files([ + "autosd.BUILD", +]) \ No newline at end of file diff --git a/packages/linux/x86_64/autosd/10.0/autosd.BUILD b/packages/linux/x86_64/autosd/10.0/autosd.BUILD new file mode 100644 index 0000000..d8c3077 --- /dev/null +++ b/packages/linux/x86_64/autosd/10.0/autosd.BUILD @@ -0,0 +1,71 @@ +# ******************************************************************************* +# Copyright (c) 2025 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 +# ******************************************************************************* + +"""Build file for AutoSD 10 GCC toolchain package""" + +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "all_files", + srcs = glob(["*/**/*"]), +) + +filegroup( + name = "bin", + srcs = ["usr/bin"], +) + +filegroup( + name = "ar", + srcs = ["usr/bin/ar"], +) + +filegroup( + name = "cc", + srcs = ["usr/bin/gcc"], +) + +filegroup( + name = "gcov", + srcs = ["usr/bin/gcov"], +) + +filegroup( + name = "cxx", + srcs = ["usr/bin/g++"], +) + +filegroup( + name = "strip", + srcs = ["usr/bin/strip"], +) + +# The sysroot for AutoSD is the entire extracted directory +# since it contains usr/ and lib64/ at the root +filegroup( + name = "sysroot_dir", + srcs = ["."], +) + +# Builtin include directories for the compiler +# List directory paths directly (like QNX does) +filegroup( + name = "cxx_builtin_include_directories", + srcs = [ + "usr/lib/gcc/x86_64-redhat-linux/14/include", + "usr/include", + "usr/include/c++/14", + "usr/include/c++/14/x86_64-redhat-linux", + "usr/include/c++/14/backward", + ], +) diff --git a/packages/version_matrix.bzl b/packages/version_matrix.bzl index 6a52379..14e0c06 100644 --- a/packages/version_matrix.bzl +++ b/packages/version_matrix.bzl @@ -39,4 +39,56 @@ VERSION_MATRIX = { "strip_prefix": "installation", "sha256": "f2e0cb21c6baddbcb65f6a70610ce498e7685de8ea2e0f1648f01b327f6bac63", }, + "x86_64-linux-gcc-autosd-10.0": { + "url": "https://github.com/eclipse-score/inc_os_autosd/releases/download/v0.1.0/autosd-toolchain-x86_64.tar.gz", + "build_file": "@score_bazel_cpp_toolchains//packages/linux/x86_64/autosd/10.0:autosd.BUILD", + "strip_prefix": "sysroot", + "sha256": "472e312711efab98022b14f2af288d47e1891674eaf9ab6a0a8dec60cae0ac75", + "extra_c_compile_flags": [ + "-nostdinc", + "-isystem", "external/%{toolchain_pkg}%/usr/lib/gcc/x86_64-redhat-linux/14/include", + "-isystem", "external/%{toolchain_pkg}%/usr/include", + ], + "extra_cxx_compile_flags": [ + "-nostdinc++", + "-isystem", "external/%{toolchain_pkg}%/usr/include/c++/14", + "-isystem", "external/%{toolchain_pkg}%/usr/include/c++/14/x86_64-redhat-linux", + "-isystem", "external/%{toolchain_pkg}%/usr/include/c++/14/backward", + "-nostdinc", + "-isystem", "external/%{toolchain_pkg}%/usr/lib/gcc/x86_64-redhat-linux/14/include", + "-isystem", "external/%{toolchain_pkg}%/usr/include", + ], + "extra_link_flags": [ + "-lm", + "-ldl", + "-lrt", + "-lstdc++", + ], + }, + "aarch64-linux-gcc-autosd-10.0": { + "url": "https://github.com/eclipse-score/inc_os_autosd/releases/download/v0.1.0/autosd-toolchain-aarch64.tar.gz", + "build_file": "@score_bazel_cpp_toolchains//packages/linux/aarch64/autosd/10.0:autosd.BUILD", + "strip_prefix": "sysroot", + "sha256": "b5128954339b9ace240de36233f910966c4760f70e4d4f2772033b3cb8d4ae22", + "extra_c_compile_flags": [ + "-nostdinc", + "-isystem", "external/%{toolchain_pkg}%/usr/lib/gcc/aarch64-redhat-linux/14/include", + "-isystem", "external/%{toolchain_pkg}%/usr/include", + ], + "extra_cxx_compile_flags": [ + "-nostdinc++", + "-isystem", "external/%{toolchain_pkg}%/usr/include/c++/14", + "-isystem", "external/%{toolchain_pkg}%/usr/include/c++/14/aarch64-redhat-linux", + "-isystem", "external/%{toolchain_pkg}%/usr/include/c++/14/backward", + "-nostdinc", + "-isystem", "external/%{toolchain_pkg}%/usr/lib/gcc/aarch64-redhat-linux/14/include", + "-isystem", "external/%{toolchain_pkg}%/usr/include", + ], + "extra_link_flags": [ + "-lm", + "-ldl", + "-lrt", + "-lstdc++", + ], + }, } \ No newline at end of file