From 51e25a2d4091749c4a2cc247a636f9c484c72b8b Mon Sep 17 00:00:00 2001 From: "Ethan D. Twardy" Date: Thu, 14 Mar 2024 18:10:42 -0500 Subject: [PATCH] Use MSV to select the version of the toolchain This commit fixes an issue with the bzlmod extension that prevents consuming MODULE.bazel files from being able to select the version of the toolchain. Now, the bzlmod extension selects the minimum version from the modules that have requested the toolchain and uses that for the system. This allows consumers to upgrade the version of arm_gnu_toolchain without needing to ugprade their compiler version, as well. --- MODULE.bazel | 4 +++ MODULE.bazel.lock | 38 +++++++++++++------------ extensions.bzl | 72 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 86 insertions(+), 28 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 1a55f32..aa72dae 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,6 +7,10 @@ module( bazel_dep(name = "platforms", version = "0.0.8") arm_toolchain = use_extension("@arm_gnu_toolchain//:extensions.bzl", "arm_toolchain") +# NOTE: It's important that we update these versions whenever a new toolchain +# version is added--otherwise the Minimum Selected Version algorithm in the +# module extension will select the version here if a consumer attempts to use +# the newer toolchain. arm_toolchain.arm_none_eabi(version = "13.2.1") use_repo( arm_toolchain, diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6ef1e0c..21c80b2 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1,6 +1,6 @@ { "lockFileVersion": 3, - "moduleFileHash": "83a3bf69a53475bc86fe8eb51a0e3b024ad186d35aad4d1d4b5d5b54a44c66e9", + "moduleFileHash": "cc7772f488e471a657eb70ac10d6e02215a54e58fa654a90b9fdfbf5e0cfb2e3", "flags": { "cmdRegistries": [ "https://bcr.bazel.build/" @@ -53,12 +53,12 @@ { "tagName": "arm_none_eabi", "attributeValues": { - "version": "9.2.1" + "version": "13.2.1" }, "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 10, + "line": 14, "column": 28 } }, @@ -70,7 +70,7 @@ "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 20, + "line": 24, "column": 39 } } @@ -850,7 +850,7 @@ "moduleExtensions": { "//:extensions.bzl%arm_toolchain": { "general": { - "bzlTransitiveDigest": "GgKuN4WAh5Tik/jTT4oagJlZyWxr4aeL592sQqzLUKM=", + "bzlTransitiveDigest": "nABIo5MPqdeY9ulas4PTAWCcl835IUiTJpM/wuIMWnw=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { @@ -861,8 +861,8 @@ "toolchain_prefix": "arm-none-eabi", "name": "_main~arm_toolchain~arm_none_eabi_windows_x86_64", "build_file": "@@//toolchain:compiler/win.BUILD", - "sha256": "e4c964add8d0fdcc6b14f323e277a0946456082a84a1cc560da265b357762b62", - "url": "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-win32.zip?revision=20c5df9c-9870-47e2-b994-2a652fb99075&la=en&hash=347C07EEEB848CC8944F943D8E1EAAB55A6CA0BC" + "sha256": "51d933f00578aa28016c5e3c84f94403274ea7915539f8e56c13e2196437d18f", + "url": "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-mingw-w64-i686-arm-none-eabi.zip?rev=93fda279901c4c0299e03e5c4899b51f&hash=A3C5FF788BE90810E121091C873E3532336C8D46" } }, "arm_none_linux_gnueabihf_linux_x86_64": { @@ -915,7 +915,8 @@ "attributes": { "name": "_main~arm_toolchain~arm_none_eabi", "toolchain_name": "arm_none_eabi", - "toolchain_prefix": "arm-none-eabi" + "toolchain_prefix": "arm-none-eabi", + "version": "13.2.1" } }, "arm_none_eabi_linux_x86_64": { @@ -924,10 +925,10 @@ "attributes": { "toolchain_prefix": "arm-none-eabi", "name": "_main~arm_toolchain~arm_none_eabi_linux_x86_64", - "sha256": "bcd840f839d5bf49279638e9f67890b2ef3a7c9c7a9b25271e83ec4ff41d177a", + "sha256": "6cd1bbc1d9ae57312bcd169ae283153a9572bd6a8e4eeae2fedfbc33b115fdbb", "build_file": "@@//toolchain:compiler/nix.BUILD", - "strip_prefix": "gcc-arm-none-eabi-9-2019-q4-major", - "url": "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=108bd959-44bd-4619-9c19-26187abf5225&la=en&hash=E788CE92E5DFD64B2A8C246BBA91A249CB8E2D2D" + "strip_prefix": "arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi", + "url": "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-eabi.tar.xz?rev=e434b9ea4afc4ed7998329566b764309&hash=688C370BF08399033CA9DE3C1CC8CF8E31D8C441" } }, "arm_none_eabi_darwin_x86_64": { @@ -936,10 +937,10 @@ "attributes": { "toolchain_prefix": "arm-none-eabi", "name": "_main~arm_toolchain~arm_none_eabi_darwin_x86_64", - "sha256": "1249f860d4155d9c3ba8f30c19e7a88c5047923cea17e0d08e633f12408f01f0", + "sha256": "075faa4f3e8eb45e59144858202351a28706f54a6ec17eedd88c9fb9412372cc", "build_file": "@@//toolchain:compiler/nix.BUILD", - "strip_prefix": "gcc-arm-none-eabi-9-2019-q4-major", - "url": "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-mac.tar.bz2?revision=c2c4fe0e-c0b6-4162-97e6-7707e12f2b6e&la=en&hash=EC9D4B5F5B050267B924F876B306D72CDF3BDDC0" + "strip_prefix": "arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi", + "url": "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-darwin-x86_64-arm-none-eabi.tar.xz?rev=a3d8c87bb0af4c40b7d7e0e291f6541b&hash=10927356ACA904E1A0122794E036E8DDE7D8435D" } }, "arm_none_linux_gnueabihf": { @@ -948,7 +949,8 @@ "attributes": { "name": "_main~arm_toolchain~arm_none_linux_gnueabihf", "toolchain_name": "arm_none_linux_gnueabihf", - "toolchain_prefix": "arm-none-linux-gnueabihf" + "toolchain_prefix": "arm-none-linux-gnueabihf", + "version": "13.2.1" } }, "arm_none_eabi_linux_aarch64": { @@ -957,10 +959,10 @@ "attributes": { "toolchain_prefix": "arm-none-eabi", "name": "_main~arm_toolchain~arm_none_eabi_linux_aarch64", - "sha256": "1f5b9309006737950b2218250e6bb392e2d68d4f1a764fe66be96e2a78888d83", + "sha256": "8fd8b4a0a8d44ab2e195ccfbeef42223dfb3ede29d80f14dcf2183c34b8d199a", "build_file": "@@//toolchain:compiler/nix.BUILD", - "strip_prefix": "gcc-arm-none-eabi-9-2019-q4-major", - "url": "https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-aarch64-linux.tar.bz2?revision=4583ce78-e7e7-459a-ad9f-bff8e94839f1&la=en&hash=550DB9C0184B7C70B6C020A5DCBB9D1E156264B7" + "strip_prefix": "arm-gnu-toolchain-13.2.Rel1-aarch64-arm-none-eabi", + "url": "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-aarch64-arm-none-eabi.tar.xz?rev=17baf091942042768d55c9a304610954&hash=7F32B9E3ADFAFC4F8F74C30EBBBFECEB1AC96B60" } } }, diff --git a/extensions.bzl b/extensions.bzl index 32b4dcd..f55f5cd 100644 --- a/extensions.bzl +++ b/extensions.bzl @@ -4,17 +4,69 @@ load( "arm_none_linux_gnueabihf_deps", ) +def compare_versions(left, right): + """ + Compare two version strings, assuming that they're both of the form + major.minor.patch. + + Returns: + -1 if left < right + 0 if left == right + 1 if left > right + """ + left_parts = [int(i) for i in left.split('.')] + right_parts = [int(i) for i in right.split('.')] + for i in range(3): + if left_parts[0] < right_parts[0]: + return -1 + + if left_parts[0] > right_parts[0]: + return 1 + + return 0 + +def minimum_supported_version(versions): + """Obtains the minimum version from the list of version strings.""" + if not len(versions): + return None + + if 1 == len(versions): + return versions[0] + + minimum = versions[0] + for version in versions[1:]: + if compare_versions(minimum, version) > 0: + minimum = version + + return minimum + +def get_toolchain_versions(module_ctx, tag_class): + """Extract toolchain versions from tag classes obtained by evaluating + the lambda on each module.""" + versions = [] + for mod in module_ctx.modules: + for attr in tag_class(mod): + versions.append(attr.version) + return versions + def _arm_toolchain_impl(ctx): - for mod in ctx.modules: - # FIXME: The module extension fails if this is removed, but it - # prevents the ability to override the toolchain version in the - # consuming MODULE.bazel. We should implement some form of MSV - # selection here. - if mod.name == "arm_gnu_toolchain": - for attr in mod.tags.arm_none_eabi: - arm_none_eabi_deps(version = attr.version) - for attr in mod.tags.arm_none_linux_gnueabihf: - arm_none_linux_gnueabihf_deps(version = attr.version) + selected_baremetal_version = minimum_supported_version( + get_toolchain_versions( + ctx, + lambda mod: mod.tags.arm_none_eabi, + ) + ) + if selected_baremetal_version: + arm_none_eabi_deps(version = selected_baremetal_version) + + selected_linux_version = minimum_supported_version( + get_toolchain_versions( + ctx, + lambda mod: mod.tags.arm_none_linux_gnueabihf, + ) + ) + if selected_linux_version: + arm_none_linux_gnueabihf_deps(version = selected_linux_version) _toolchain = tag_class(attrs = { "version": attr.string(),