From ccbdcac2a73f5b7b63b7ac410afe7c748ebcb2cf Mon Sep 17 00:00:00 2001 From: Nikola Radakovic Date: Thu, 23 Jul 2026 14:21:00 +0200 Subject: [PATCH] Add patches support for SDP toolchain archives Introduce a patches to the SDP tag class so patches can be applied to downloaded toolchain archives. The attributes are threaded through `_get_packages`, `_create_and_link_sdp`, and the archive download in `_impl`. Documentation is also update to follow up new attribute set. --- docs/extension_api.md | 91 ++++++++++++++++++++++++++------------- docs/generation_flow.md | 3 +- docs/repository_layout.md | 2 +- extensions/gcc.bzl | 47 ++++++++++++++++++++ rules/common.bzl | 4 +- tests/MODULE.bazel | 15 ++++++- tests/MODULE.bazel.lock | 79 +++++++++++++++++++++++++++------ 7 files changed, 195 insertions(+), 46 deletions(-) diff --git a/docs/extension_api.md b/docs/extension_api.md index 68d4bed..88c9675 100644 --- a/docs/extension_api.md +++ b/docs/extension_api.md @@ -48,53 +48,86 @@ Declares a toolchain repository to generate. Declares a package repository explicitly. This is used when the package is not taken from the default version matrix or when local QNX SDP generation is -required. +required. The tag is nothing more than a thin proxy to the native `http_archive` +repository rule: its attributes are passed straight through to `http_archive` +with no additional processing. ## `gcc.toolchain(...)` Attributes Required attributes: -- `name`: name of the generated repository -- `target_cpu`: target CPU, currently `x86_64` or `aarch64` -- `target_os`: target OS, currently `linux` or `qnx` +- `name` (mandatory): toolchain repo name, default set to `score_gcc_toolchain`. +- `target_cpu` (mandatory): target platform CPU, currently `x86_64` or `aarch64`. +- `target_os` (mandatory): target platform OS, currently `linux` or `qnx`. Common package selection attributes: -- `use_default_package`: resolve package metadata from `packages/version_matrix.bzl` +- `use_default_package`: whether to use the default package from the version + matrix, default set to `False`. - `version`: GCC version string for Linux toolchains (e.g. `12.2.0` or `15.3.0` — - see `packages/version_matrix.bzl` for all versions currently packaged) -- `sdp_version`: QNX SDP version string -- `sdk_version`: alternative SDK identifier used in matrix resolution -- `sdp_to_link`: override the package repository name that the toolchain uses + see `packages/version_matrix.bzl` for all versions currently packaged). +- `sdp_version`: version of the SDP package. +- `sdk_version`: SDK version info variable, an alternative identifier used in + matrix resolution. +- `sdp_to_link`: name of the toolchain package to be linked with this + toolchain, default set to toolchain name + `_pkg`. +- `use_system_toolchain`: TBD. Flag and runtime attributes: -- `extra_compile_flags` -- `extra_c_compile_flags` -- `extra_cxx_compile_flags` -- `extra_link_flags` -- `extra_known_features` -- `extra_enabled_features` -- `ld_library_paths` -- `runtime_ecosystem` -- `use_base_constraints_only` +- `extra_compile_flags`: list of additional flags to be passed to compiler. +- `extra_c_compile_flags`: list of additional flags to be passed to C compiler. +- `extra_cxx_compile_flags`: list of additional flags to be passed to C++ + compiler. +- `extra_link_flags`: list of additional flags to be passed to linker. +- `extra_known_features`: extra `cc_feature` features to add to this toolchain + in an initially disabled state. See [Feature Injection](#feature-injection). +- `extra_enabled_features`: extra `cc_feature` features to add to this + toolchain in an initially enabled state. See [Feature Injection](#feature-injection). +- `ld_library_paths`: list of paths relative to the sysroot which should build + up the runtime linker path of the tools of this toolchain. +- `runtime_ecosystem`: attribute for identifying the system-level runtime + environment a binary or target is built to run in. +- `use_base_constraints_only`: experimental. Attribute for flag toolchain + creation to use only base platform constraints. Limits toolchain + registration to 1 per base platform definition. QNX-specific attributes: -- `license_path` -- `license_info_variable` -- `license_info_url` +- `license_path`: path to the shared license file, default set to + `/opt/score_qnx/license/licenses`. +- `license_info_variable`: QNX license info variable. +- `license_info_url`: URL of the QNX license server. ## `gcc.sdp(...)` Attributes -The `gcc.sdp` tag defines the package side of the toolchain setup. Important -attributes are: - -- `name`: repository name for the package -- `build_file`: BUILD file that exposes the package contents as Bazel targets -- `url`: url of the archive, -- `sha256`: sha256 of the archive -- `strip_prefix`: extraction prefix for packaged archives +The `gcc.sdp` tag defines the package side of the toolchain setup. It is a +proxy to `http_archive`: every attribute below maps 1:1 to the identically +named `http_archive` attribute, so refer to the Bazel `http_archive` docs for +full semantics. Its attributes are: + +- `name`: package name of toolchain, default set to toolchain name + `_pkg`. +- `build_file`: the path to the BUILD file of selected archive. +- `url`: url to the toolchain archive. +- `sha256`: checksum of the archive. +- `strip_prefix`: strip prefix from toolchain archive. +- `files`: a map of relative paths (key) to a file label (value) that is + overlaid on the repo as a symlink. +- `patches`: list of patches to apply to the archive. +- `patch_args`: the arguments given to the patch tool. Defaults to `-p0` (see + the `patch_strip` attribute), however `-p1` will usually be needed for + patches generated by git. When arguments other than `-p` are specified, + Bazel falls back to the `patch` command line tool instead of the + Bazel-native patch implementation. Only affects patch files in the + `patches` attribute. +- `patch_cmds`: bash commands executed in the extracted archive root after + extraction. +- `patch_strip`: when set to `N`, this is equivalent to inserting `-pN` to the + beginning of `patch_args`. +- `patch_tool`: the patch(1) utility to use. If specified, Bazel uses the + specified patch tool instead of the Bazel-native patch implementation. + +Archive attributes can be supplied either directly through `gcc.sdp(...)` or through `packages/version_matrix.bzl`; the extension forwards matrix values for `patches`, `patch_args`, `patch_cmds`, `patch_strip`, `patch_tool`, and `files` to `http_archive` when present. Entries that omit these optional fields use the native `http_archive` defaults. ## Feature Injection diff --git a/docs/generation_flow.md b/docs/generation_flow.md index b8c5eb1..c7c0c3b 100644 --- a/docs/generation_flow.md +++ b/docs/generation_flow.md @@ -40,7 +40,8 @@ toolchain repository through these steps: `packages/version_matrix.bzl` Defines the supported package matrix. Each entry maps a logical toolchain key -to download metadata and, when needed, extra compiler or linker flags. +to download metadata and, when needed, extra compiler or linker flags and +archive patches. `rules/common.bzl` diff --git a/docs/repository_layout.md b/docs/repository_layout.md index df80351..5dfc53f 100644 --- a/docs/repository_layout.md +++ b/docs/repository_layout.md @@ -48,7 +48,7 @@ Contains the repository rules that materialize a toolchain repository. Stores package metadata and BUILD descriptors for supported toolchain archives. The most important file is `packages/version_matrix.bzl`, which maps -logical toolchain identifiers to URLs, checksums, build files, and any +logical toolchain identifiers to URLs, checksums, build files, patches, and any required extra flags. `features/` diff --git a/extensions/gcc.bzl b/extensions/gcc.bzl index 23fb14f..c16364f 100644 --- a/extensions/gcc.bzl +++ b/extensions/gcc.bzl @@ -35,15 +35,46 @@ _attrs_sdp = { default = None, doc = "The path to the BUILD file of selected archive.", ), + "files": attr.string_keyed_label_dict( + mandatory = False, + default = {}, + doc = "A map of relative paths (key) to a file label (value) that overlaid on the repo as a symlink.", + ), "name": attr.string( default = "", doc = "package name of toolchain, default set to toolchain toolchain name + `_pkg`.", ), + "patch_args": attr.string_list( + mandatory = False, + default = [], + doc = + "The arguments given to the patch tool. Defaults to -p0 (see the `patch_strip` " + + "attribute), however -p1 will usually be needed for patches generated by " + + "git. If multiple -p arguments are specified, the last one will take effect." + + "If arguments other than -p are specified, Bazel will fall back to use patch " + + "command line tool instead of the Bazel-native patch implementation. When falling " + + "back to patch command line tool and patch_tool attribute is not specified, " + + "`patch` will be used. This only affects patch files in the `patches` attribute.", + ), "patch_cmds": attr.string_list( mandatory = False, default = [], doc = "Bash commands executed in the extracted archive root after extraction.", ), + "patch_strip": attr.int( + default = 0, + doc = "When set to `N`, this is equivalent to inserting `-pN` to the beginning of `patch_args`.", + ), + "patch_tool": attr.string( + default = "", + doc = "The patch(1) utility to use. If this is specified, Bazel will use the specified " + + "patch tool instead of the Bazel-native patch implementation.", + ), + "patches": attr.label_list( + mandatory = False, + default = [], + doc = "List of patches to apply to the archive.", + ), "sha256": attr.string( mandatory = False, default = "", @@ -190,10 +221,15 @@ def _get_packages(tags): packages.append({ "build_file": tag.build_file, "name": tag.name, + "patch_args": tag.patch_args, "patch_cmds": tag.patch_cmds, + "patch_strip": tag.patch_strip, + "patch_tool": tag.patch_tool, "sha256": tag.sha256, "strip_prefix": tag.strip_prefix, "url": tag.url, + "patches": tag.patches, + "files": tag.files, }) return packages @@ -306,10 +342,16 @@ def _create_and_link_sdp(toolchain_info): return { "build_file": matrix["build_file"], "name": pkg_name, + # patch_args/patch_strip/patch_tool are not part of the version matrix; fall back to sdp tag defaults. + "patch_args": matrix.get("patch_args", []), "patch_cmds": matrix.get("patch_cmds", []), + "patch_strip": matrix.get("patch_strip", 0), + "patch_tool": matrix.get("patch_tool", ""), "sha256": matrix["sha256"], "strip_prefix": matrix["strip_prefix"], "url": matrix["url"], + "patches": matrix.get("patches"), + "files": matrix.get("files"), } def _resolve_identifier(toolchain_info): @@ -395,9 +437,14 @@ def _impl(mctx): name = archive_info["name"], urls = [archive_info["url"]], build_file = archive_info["build_file"], + patch_args = archive_info["patch_args"], patch_cmds = archive_info["patch_cmds"], + patch_strip = archive_info["patch_strip"], + patch_tool = archive_info["patch_tool"], sha256 = archive_info["sha256"], strip_prefix = archive_info["strip_prefix"], + patches = archive_info["patches"], + files = archive_info["files"], ) for toolchain_info in toolchains: diff --git a/rules/common.bzl b/rules/common.bzl index b61011c..6c5b3c2 100644 --- a/rules/common.bzl +++ b/rules/common.bzl @@ -20,7 +20,9 @@ load("@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", "flag_group") # Certain SDP versions are mapped to canonical versions used in platform constraints. # For example, SDP 8.0.4 is mapped to 8.0.0 because platform constraint support # uses the older identifier. -SDP_VERSION_MAPPING = {"8.0.4": "8.0.0"} +SDP_VERSION_MAPPING = { + "8.0.4": "8.0.0", +} def get_flag_strings(flags): """Converts a list of warning flags into a Bazel flag group representation. diff --git a/tests/MODULE.bazel b/tests/MODULE.bazel index f6d9352..3ed7906 100644 --- a/tests/MODULE.bazel +++ b/tests/MODULE.bazel @@ -148,7 +148,18 @@ gcc.toolchain( ) # ******************************************************************************* -# Setting GCC (CPU:x86_64|OS:QNX|version(sdp):8.0.0|ES:posix) +# Setting GCC (CPU:x86_64|OS:QNX|version(sdp):8.0.4|ES:posix) +# ******************************************************************************* +# gcc.toolchain( +# name = "score_qcc_toolchain", +# sdp_version = "8.0.4", +# target_cpu = "x86_64", +# target_os = "qnx", +# use_default_package = True, +# ) + +# ******************************************************************************* +# Setting GCC (CPU:x86_64|OS:QNX|version(sdp):8.0.4|ES:posix) # ******************************************************************************* gcc.toolchain( name = "score_qcc_toolchain", @@ -159,7 +170,7 @@ gcc.toolchain( ) # ******************************************************************************* -# Setting GCC (CPU:aarch64|OS:QNX|version(sdp):8.0.0|ES:posix) +# Setting GCC (CPU:aarch64|OS:QNX|version(sdp):8.0.4|ES:posix) # ******************************************************************************* gcc.toolchain( name = "score_qcc_arm_toolchain", diff --git a/tests/MODULE.bazel.lock b/tests/MODULE.bazel.lock index fc24e7e..d5aa492 100644 --- a/tests/MODULE.bazel.lock +++ b/tests/MODULE.bazel.lock @@ -1370,7 +1370,7 @@ }, "@@score_bazel_cpp_toolchains+//extensions:gcc.bzl%gcc": { "general": { - "bzlTransitiveDigest": "dffSoCJVMsbso/wS4jpQI/Uab9lB/i4ftLn6XkLcoAc=", + "bzlTransitiveDigest": "gZlCGThP57D/hTQYaaNd95n9FT81ZotPPk5G3m91ATA=", "usagesDigest": "3BxGiccNNlFja9y/vd4+7TlTcgtjWIybmed7P06K9QM=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -1383,9 +1383,14 @@ "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/0.0.1/x86_64-unknown-linux-gnu_gcc12.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/x86_64/gcc/12.2.0:gcc.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "457f5f20f57528033cb840d708b507050d711ae93e009388847e113b11bf3600", - "strip_prefix": "x86_64-unknown-linux-gnu" + "strip_prefix": "x86_64-unknown-linux-gnu", + "patches": [], + "files": {} } }, "score_gcc_toolchain_bp_pkg": { @@ -1395,9 +1400,14 @@ "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.4/x86_64-unknown-linux-gnu_gcc12.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/x86_64/gcc/12.2.0:gcc.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "e9b9a7a63a5f8271b76d6e2057906b95c7a244e4931a8e10edeaa241e9f7c11e", - "strip_prefix": "x86_64-unknown-linux-gnu" + "strip_prefix": "x86_64-unknown-linux-gnu", + "patches": [], + "files": {} } }, "score_gcc_toolchain_pkg": { @@ -1407,9 +1417,14 @@ "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.4/x86_64-unknown-linux-gnu_gcc12.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/x86_64/gcc/12.2.0:gcc.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "e9b9a7a63a5f8271b76d6e2057906b95c7a244e4931a8e10edeaa241e9f7c11e", - "strip_prefix": "x86_64-unknown-linux-gnu" + "strip_prefix": "x86_64-unknown-linux-gnu", + "patches": [], + "files": {} } }, "score_gcc_toolchain_15_pkg": { @@ -1419,9 +1434,14 @@ "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.5/x86_64-unknown-linux-gnu_gcc15.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/x86_64/gcc/15.3.0:gcc.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "c65e21725d4d9993bab0b4ef2aed7065a4bf1b0f232a068d778eb670f80daa60", - "strip_prefix": "x86_64-unknown-linux-gnu" + "strip_prefix": "x86_64-unknown-linux-gnu", + "patches": [], + "files": {} } }, "score_aarch64_gcc_toolchain_pkg": { @@ -1431,9 +1451,14 @@ "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.4/aarch64-unknown-linux-gnu_gcc12.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/aarch64/gcc/12.2.0:gcc.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "7279b1adb50361b21f5266b001980b6febb35fa8d83170901196b9edae3f06d9", - "strip_prefix": "aarch64-unknown-linux-gnu" + "strip_prefix": "aarch64-unknown-linux-gnu", + "patches": [], + "files": {} } }, "score_aarch64_gcc_toolchain_15_pkg": { @@ -1443,9 +1468,14 @@ "https://github.com/eclipse-score/toolchains_gcc_packages/releases/download/v0.0.5/aarch64-unknown-linux-gnu_gcc15.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/aarch64/gcc/15.3.0:gcc.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "ff9fe6caed22f15a1dd87a93bff5cfa1536b5dddcff3364827f97ebc01a494a1", - "strip_prefix": "aarch64-unknown-linux-gnu" + "strip_prefix": "aarch64-unknown-linux-gnu", + "patches": [], + "files": {} } }, "score_qcc_toolchain_pkg": { @@ -1455,9 +1485,14 @@ "https://www.qnx.com/download/download/88447/installation_qnx_804_260520.tar.xz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/qnx/x86_64/sdp/8.0.0:sdp.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "146312c0bf22aab66e8294a06403f2ec6cfeeb074d8fa11549faffd84b7fe778", - "strip_prefix": "" + "strip_prefix": "", + "patches": [], + "files": {} } }, "score_qcc_arm_toolchain_pkg": { @@ -1467,9 +1502,14 @@ "https://www.qnx.com/download/download/88447/installation_qnx_804_260520.tar.xz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/qnx/aarch64/sdp/8.0.0:sdp.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "146312c0bf22aab66e8294a06403f2ec6cfeeb074d8fa11549faffd84b7fe778", - "strip_prefix": "" + "strip_prefix": "", + "patches": [], + "files": {} } }, "score_autosd_10_toolchain_pkg": { @@ -1479,9 +1519,14 @@ "https://github.com/eclipse-score/os_autosd/releases/download/v0.0.2/autosd-toolchain-x86_64.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/x86_64/autosd/10.0:autosd.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "25991056bd29d4cb37b11e42d0c09f55dc61d0b9d703f75d854cf614f688c96f", - "strip_prefix": "sysroot" + "strip_prefix": "sysroot", + "patches": [], + "files": {} } }, "score_ebclfsa_toolchain_pkg": { @@ -1491,9 +1536,14 @@ "https://github.com/Elektrobit/eb_corbos_toolkit/releases/download/v2.0.0-beta1/fastdev-sdk-ubuntu-ebclfsa-ebcl-qemuarm64.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/aarch64/ebclfsa/0.1.0:ebclfsa.BUILD", + "patch_args": [], "patch_cmds": [], + "patch_strip": 0, + "patch_tool": "", "sha256": "f44286c28d831dc40acdac08ef49f38a2e9cbb057bea38c25834964693785287", - "strip_prefix": "fastdev-sdk-ubuntu-ebclfsa-ebcl-qemuarm64" + "strip_prefix": "fastdev-sdk-ubuntu-ebclfsa-ebcl-qemuarm64", + "patches": [], + "files": {} } }, "score_ebclfsa_2.0.0-beta2_toolchain_pkg": { @@ -1503,11 +1553,16 @@ "https://github.com/Elektrobit/eb_corbos_toolkit/releases/download/v2.0.0-beta2/fastdev-sdk-trixie-ebclfsa-ebcl-qemuarm64.tar.gz" ], "build_file": "@@score_bazel_cpp_toolchains+//packages/linux/aarch64/ebclfsa/2.0.0-beta2:ebclfsa.BUILD", + "patch_args": [], "patch_cmds": [ "sdk=$(pwd); loader=$sdk/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2; test -x \"$loader\" -a -x \"$sdk/usr/bin/patchelf\" || exit 1; tmp=$(mktemp -d); cp \"$sdk/usr/bin/patchelf\" \"$tmp/patchelf\"; run_patchelf() { \"$loader\" --library-path \"$sdk/usr/lib/x86_64-linux-gnu:$sdk/lib/x86_64-linux-gnu\" \"$tmp/patchelf\" \"$@\"; }; for binary in $(find usr/bin usr/sbin usr/libexec/gcc* usr/lib/gcc-cross usr/lib/llvm-*/bin -type f -perm -u+x 2>/dev/null); do interpreter=$(run_patchelf --print-interpreter \"$binary\" 2>/dev/null) || continue; test -n \"$interpreter\" || continue; run_patchelf --set-interpreter \"$loader\" \"$binary\" >/dev/null 2>&1 || true; done; rm -rf \"$tmp\"" ], + "patch_strip": 0, + "patch_tool": "", "sha256": "4cf7f0191988795f316f276b56e370ad60fc371954a881d158ebba0284d9d3f5", - "strip_prefix": "fastdev-sdk-trixie-ebclfsa-ebcl-qemuarm64" + "strip_prefix": "fastdev-sdk-trixie-ebclfsa-ebcl-qemuarm64", + "patches": [], + "files": {} } }, "score_gcc_toolchain_bp": {