diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 559351590..f6e13910b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -42,13 +42,19 @@ jobs: USE_BZLMOD: ${{ matrix.bzlmod }} run: tests/scripts/run_tests.sh toolchain_test: - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: [macos-latest, ubuntu-latest] + bazel_version: [7.x, latest] + bzlmod: [true, false] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Test env: - USE_BAZEL_VERSION: latest - USE_BZLMOD: true + USE_BAZEL_VERSION: ${{ matrix.bazel_version }} + USE_BZLMOD: ${{ matrix.bzlmod }} run: tests/scripts/run_toolchain_tests.sh external_test: strategy: diff --git a/MODULE.bazel b/MODULE.bazel index 8c2d556a5..229faca2c 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -22,6 +22,7 @@ module( bazel_dep(name = "bazel_skylib", version = "1.5.0") bazel_dep(name = "rules_cc", version = "0.0.17") bazel_dep(name = "platforms", version = "0.0.8") +bazel_dep(name = "helly25_bzl", version = "0.1.2") # TODO: Remove when protobuf is released with a version of rules_python that supports 8.x bazel_dep(name = "rules_python", version = "1.0.0", dev_dependency = True) diff --git a/README.md b/README.md index 89eaa546b..c0e552461 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,25 @@ See [bazel tutorial](https://docs.bazel.build/versions/main/tutorial/cc-toolchain-config.html) for how CC toolchains work in general. +### Requirements + +Version attributes can be requirements of the form `first`, `first:`, +`latest` or `latest:`. + +In case of `latest`, the latest distribution matching the optional `condition` +will be selected. + +In case of `first`, the first distribution matching the optional `condition` +will be selected. + +The condition consists of a comma separated list of semver version comparisons +supporting `<`, `<=`, `>`, `>=`, `==`, `!=`. Examples: + +- `latest` +- `latest:>=20.1.0` +- `latest:>17.0.4,!=19.1.7,<=20.1.0` +- `first:>=15.0.6,<16` + ### Selecting Toolchains If toolchains are registered (see Quickstart section above), you do not need to diff --git a/WORKSPACE b/WORKSPACE index d7c1f5d72..4bbf6d4ed 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -15,3 +15,12 @@ workspace( name = "toolchains_llvm", ) + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "helly25_bzl", + sha256 = "404f8473bcaad2e370752e57d274d2093eb87ca94cb9a597c1a3553b76743206", + strip_prefix = "bzl-0.1.2", + url = "https://github.com/helly25/bzl/releases/download/0.1.2/bzl-0.1.2.tar.gz", +) diff --git a/tests/scripts/run_toolchain_tests.sh b/tests/scripts/run_toolchain_tests.sh index 1bc7cac24..5f1c2074e 100755 --- a/tests/scripts/run_toolchain_tests.sh +++ b/tests/scripts/run_toolchain_tests.sh @@ -41,5 +41,13 @@ targets=( "//toolchain/..." ) +if [[ -z "${common_test_args:-}" ]]; then + common_test_args=() +fi + +if [[ "${USE_BAZEL_VERSION}" == "7.x" ]] || [[ "${USE_BZLMOD}" == "false" ]]; then + targets+=("-//toolchain/internal:llvm_distributions_select_no_error_test") +fi + "${bazel}" ${TEST_MIGRATION:+"--strict"} --bazelrc=/dev/null test \ - "${common_test_args[@]}" "${test_args[@]}" "${targets[@]}" + "${common_test_args[@]}" "${test_args[@]}" -- "${targets[@]}" diff --git a/toolchain/deps.bzl b/toolchain/deps.bzl index 04903a5a8..e045318dc 100644 --- a/toolchain/deps.bzl +++ b/toolchain/deps.bzl @@ -35,4 +35,12 @@ def bazel_toolchain_dependencies(): sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f", ) - # Skip bazel_skylib_workspace because we are not using lib/unittest.bzl + # Skip bazel_skylib_workspace because we are not using lib/unittest.bzl + + if not native.existing_rule("helly25_bzl"): + http_archive( + name = "helly25_bzl", + strip_prefix = "bzl-0.1.2", + url = "https://github.com/helly25/bzl/releases/download/0.1.2/bzl-0.1.2.tar.gz", + sha256 = "404f8473bcaad2e370752e57d274d2093eb87ca94cb9a597c1a3553b76743206", + ) diff --git a/toolchain/internal/BUILD.bazel b/toolchain/internal/BUILD.bazel index 96ee1848b..b44e9c21e 100644 --- a/toolchain/internal/BUILD.bazel +++ b/toolchain/internal/BUILD.bazel @@ -13,7 +13,7 @@ # limitations under the License. load("@bazel_skylib//rules:diff_test.bzl", "diff_test") -load("llvm_distributions.bzl", "write_distributions") +load("llvm_distributions.bzl", "requirements_test_writer", "write_distributions") exports_files(["template.modulemap"]) @@ -50,3 +50,16 @@ sh_test( "//conditions:default": ["@platforms//:incompatible"], }), ) + +requirements_test_writer( + name = "llvm_requirements_test_output", + testonly = True, + result = "llvm_requirements_test.output.txt", + visibility = ["//visibility:private"], +) + +diff_test( + name = "llvm_requirements_test", + file1 = "llvm_requirements_test.golden.txt", + file2 = "llvm_requirements_test.output.txt", +) diff --git a/toolchain/internal/configure.bzl b/toolchain/internal/configure.bzl index 1f02e9ffc..9774e839b 100644 --- a/toolchain/internal/configure.bzl +++ b/toolchain/internal/configure.bzl @@ -36,6 +36,7 @@ load( _supported_targets = "SUPPORTED_TARGETS", _toolchain_tools = "toolchain_tools", ) +load("//toolchain/internal:llvm_distributions.bzl", "is_requirement", "required_llvm_release_name_rctx") load( "//toolchain/internal:sysroot.bzl", _default_sysroot_path = "default_sysroot_path", @@ -79,6 +80,15 @@ def llvm_config_impl(rctx): if not toolchain_root: fail("LLVM toolchain root missing for ({}, {})".format(os, arch)) (_key, llvm_version) = _exec_os_arch_dict_value(rctx, "llvm_versions") + if is_requirement(llvm_version): + llvm_version, distribution, error = required_llvm_release_name_rctx(rctx, llvm_version) + if error: + fail(error) + if llvm_version: + print("\nINFO: Resolved latest LLVM version to {llvm_version}: {distribution}".format( + distribution = distribution, + llvm_version = llvm_version, + )) # buildifier: disable=print if not llvm_version: # LLVM version missing for (os, arch) _empty_repository(rctx) diff --git a/toolchain/internal/llvm_distributions.bzl b/toolchain/internal/llvm_distributions.bzl index 1e89bedbf..566197b3b 100644 --- a/toolchain/internal/llvm_distributions.bzl +++ b/toolchain/internal/llvm_distributions.bzl @@ -13,6 +13,7 @@ # limitations under the License. load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "use_netrc") +load("@helly25_bzl//bzl/versions:versions.bzl", "versions") load( "//toolchain/internal:common.bzl", "attr_dict", @@ -989,6 +990,10 @@ def _find_llvm_basename_list(llvm_version, all_llvm_distributions, host_info): return [] def _find_llvm_basename_or_error(llvm_version, all_llvm_distributions, host_info): + all_llvm_distributions = _filter_llvm_distributions( + llvm_version = llvm_version, + all_llvm_distributions = all_llvm_distributions, + ) basenames = _find_llvm_basename_list(llvm_version, all_llvm_distributions, host_info) if len(basenames) > 1: return None, "ERROR: Multiple configurations found for version {llvm_version} on {os}/{dist_name}/{dist_version} with arch {arch}: [{basenames}].".format( @@ -1015,14 +1020,79 @@ def _find_llvm_basename_or_error(llvm_version, all_llvm_distributions, host_info return basenames[0], None +def _parse_version_or_requirements(version_or_requirements): + if version_or_requirements in ["latest", "first"]: + return None + for prefix in ["latest:", "first:"]: + if version_or_requirements.startswith(prefix): + return versions.parse_requirements(version_or_requirements.removeprefix(prefix)) + fail("ERROR: Invalid version requirements: '{version_or_requirements}'.".format( + version_or_requirements = version_or_requirements, + )) + +def _get_version_from_distribution(distribution): + # We assume here that the `distribution` is a basename of the form `LLVM--...` or + # `clang+llvm--...`. + return distribution.split("-")[1] + +def _get_llvm_versions(*, version_or_requirements, all_llvm_distributions): + llvm_version_dict = {} + for distribution in all_llvm_distributions.keys(): + version = _get_version_from_distribution(distribution) + llvm_version_dict[_parse_version(version)] = version + + return [v for k, v in sorted(llvm_version_dict.items(), reverse = version_or_requirements.startswith("latest"))] + +def _required_llvm_release_name(*, version_or_requirements, all_llvm_distributions, host_info): + llvm_versions = _get_llvm_versions(version_or_requirements = version_or_requirements, all_llvm_distributions = all_llvm_distributions) + requirements = _parse_version_or_requirements(version_or_requirements) + for llvm_version in llvm_versions: + if requirements and not versions.check_all_requirements(llvm_version, requirements): + continue + basenames = _find_llvm_basename_list(llvm_version, all_llvm_distributions, host_info) + if len(basenames) == 1: + return llvm_version, basenames[0], None + return None, None, "ERROR: No matching distribution found." + +def required_llvm_release_name_rctx(rctx, llvm_version): + all_llvm_distributions = _get_all_llvm_distributions(rctx) + return _required_llvm_release_name( + version_or_requirements = llvm_version, + all_llvm_distributions = all_llvm_distributions, + host_info = host_info(rctx), + ) + +def is_requirement(version_or_requirement): + """Return whether `version_or_requirement` is likely a requirement (True) or should be a version.""" + for prefix in ["first:", "latest:"]: + if version_or_requirement.startswith(prefix) or version_or_requirement == prefix[:-1]: + return True + return False + +def _filter_llvm_distributions(*, llvm_version, all_llvm_distributions): + """Return (distribution: sha) entries from `all_llvm_distributions` that match `llvm_version`.""" + result = {} + for k, v in all_llvm_distributions.items(): + if _get_version_from_distribution(k) == llvm_version: + result[k] = v + return result + def _distribution_urls(rctx): - """Return LLVM `urls`, `shha256` and `strip_prefix` for the given context.""" + """Return LLVM `urls`, `sha256` and `strip_prefix` for the given context.""" llvm_version = _get_llvm_version(rctx) all_llvm_distributions = _get_all_llvm_distributions(rctx) _, sha256, strip_prefix, _ = _key_attrs(rctx) if rctx.attr.distribution == "auto": - basename, error = _find_llvm_basename_or_error(llvm_version, all_llvm_distributions, host_info(rctx)) + rctx_host_info = host_info(rctx) + if is_requirement(llvm_version): + llvm_version, basename, error = _required_llvm_release_name( + version_or_requirements = llvm_version, + all_llvm_distributions = all_llvm_distributions, + host_info = rctx_host_info, + ) + else: + basename, error = _find_llvm_basename_or_error(llvm_version, all_llvm_distributions, rctx_host_info) if error: fail(error) if sha256 and sha256 != all_llvm_distributions[basename]: @@ -1263,3 +1333,87 @@ write_distributions = rule( "select": attr.output(mandatory = True), }, ) + +def _requirements_test_writer_impl(ctx): + """Analyze the configured versions and write to a file for test consumption. + The test generated file '.out' contains the following lines: + [,,]: + """ + all_llvm_distributions = { + # In order to prevent new distributions to interfere we cut at 20.1.3. + k: v + for k, v in _llvm_distributions.items() + if _parse_version(_get_version_from_distribution(k)) <= (20, 1, 3) + } + requirement_list = [ + "latest:<=20.1.0", + "latest:<=20.1.0,>17.0.4,!=19.1.7", + "latest:<20.1.0,>17.0.4,!=19.1.7", + "latest:<20.1.0,>17.0.4", + "latest:>=15.0.6,<16", + "first:>=15.0.6,<16", + "latest", + "first", + ] + arch_list = [ + "aarch64", + "armv7a", + "x86_64", + ] + os_list = [ + "darwin", + "linux", + "windows", + ] + ANY_VERSION = "0" # Version does not matter, but must be a valid integer + dist_dict_list = { + "linux": [ + # keep sorted + struct(name = "ubuntu", version = ANY_VERSION), + struct(name = "raspbian", version = ANY_VERSION), + struct(name = "rhel", version = ANY_VERSION), + ], + } + result = [] + for arch in arch_list: + for os in os_list: + dist_list = dist_dict_list.get(os, [struct(name = os, version = "")]) + for dist in dist_list: + for requirement in requirement_list: + host_info = struct( + arch = arch, + os = os, + dist = dist, + ) + llvm_version, basename, error = _required_llvm_release_name( + version_or_requirements = requirement, + all_llvm_distributions = all_llvm_distributions, + host_info = host_info, + ) + if llvm_version and basename: + result.append("[{arch},{os}{dist_name}{dist_version},'{requirement}']: {llvm_version} = {basename}".format( + arch = arch, + os = os, + dist_name = "," + dist.name if os == "linux" else "", + dist_version = "," + dist.version if os == "linux" else "", + requirement = requirement, + llvm_version = llvm_version, + basename = basename, + )) + else: + result.append("[{arch},{os},\"{requirement}\"]: {error}".format( + arch = arch, + os = os, + requirement = requirement, + llvm_version = llvm_version, + basename = basename, + error = error or "ERROR: N/A", + )) + ctx.actions.write(ctx.outputs.result, "\n".join(result) + "\n") + +requirements_test_writer = rule( + implementation = _requirements_test_writer_impl, + attrs = { + "result": attr.output(mandatory = True), + }, +) diff --git a/toolchain/internal/llvm_distributions_test.golden.txt b/toolchain/internal/llvm_distributions_test.golden.txt new file mode 100644 index 000000000..fb2acd378 --- /dev/null +++ b/toolchain/internal/llvm_distributions_test.golden.txt @@ -0,0 +1,164 @@ +del: clang+llvm-6.0.0-amd64-unknown-freebsd-10.tar.xz +del: clang+llvm-6.0.0-i386-unknown-freebsd-10.tar.xz +del: clang+llvm-6.0.0-i686-linux-gnu-Fedora27.tar.xz +del: clang+llvm-6.0.0-mips-linux-gnu.tar.xz +del: clang+llvm-6.0.0-mipsel-linux-gnu.tar.xz +del: clang+llvm-6.0.0-x86_64-linux-gnu-Fedora27.tar.xz +del: clang+llvm-6.0.0-x86_64-linux-gnu-debian8.tar.xz +del: clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz +del: clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-6.0.0-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-6.0.0-x86_64-linux-sles12.2.tar.xz +del: clang+llvm-6.0.1-amd64-unknown-freebsd10.tar.xz +del: clang+llvm-6.0.1-i386-unknown-freebsd10.tar.xz +del: clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz +del: clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-6.0.1-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-6.0.1-x86_64-linux-sles12.3.tar.xz +del: clang+llvm-7.0.0-amd64-unknown-freebsd-10.tar.xz +del: clang+llvm-7.0.0-i386-unknown-freebsd-10.tar.xz +del: clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz +del: clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-7.0.0-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-7.0.0-x86_64-linux-sles12.3.tar.xz +del: clang+llvm-8.0.0-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-8.0.0-i386-unknown-freebsd11.tar.xz +del: clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz +del: clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz +del: clang+llvm-8.0.0-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-8.0.1-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-8.0.1-i386-unknown-freebsd11.tar.xz +del: clang+llvm-8.0.1-powerpc64le-linux-rhel-7.4.tar.xz +del: clang+llvm-8.0.1-powerpc64le-linux-ubuntu-16.04.tar.xz +del: clang+llvm-8.0.1-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-9.0.0-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-9.0.0-i386-unknown-freebsd11.tar.xz +del: clang+llvm-9.0.0-powerpc64le-linux-rhel-7.4.tar.xz +del: clang+llvm-9.0.0-powerpc64le-linux-ubuntu-16.04.tar.xz +del: clang+llvm-9.0.0-x86_64-darwin-apple.tar.xz +del: clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz +del: clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz +del: clang+llvm-9.0.0-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-9.0.0-x86_64-pc-linux-gnu.tar.xz +del: clang+llvm-10.0.0-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-10.0.0-i386-unknown-freebsd11.tar.xz +del: clang+llvm-10.0.0-powerpc64le-linux-rhel-7.4.tar.xz +del: clang+llvm-10.0.0-powerpc64le-linux-ubuntu-16.04.tar.xz +del: clang+llvm-10.0.0-x86_64-linux-sles11.3.tar.xz +del: clang+llvm-10.0.1-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-10.0.1-i386-unknown-freebsd11.tar.xz +del: clang+llvm-10.0.1-powerpc64le-linux-rhel-7.4.tar.xz +del: clang+llvm-10.0.1-powerpc64le-linux-ubuntu-16.04.tar.xz +del: clang+llvm-10.0.1-x86_64-linux-sles12.4.tar.xz +del: clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz +del: clang+llvm-11.0.0-x86_64-linux-sles12.4.tar.xz +del: clang+llvm-11.0.1-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-11.0.1-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-11.0.1-i386-unknown-freebsd11.tar.xz +del: clang+llvm-11.0.1-i386-unknown-freebsd12.tar.xz +del: clang+llvm-11.0.1-powerpc64le-linux-rhel-7.4.tar.xz +del: clang+llvm-11.0.1-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-11.0.1-x86_64-linux-gnu-ubuntu-20.10.tar.xz +del: clang+llvm-11.0.1-x86_64-linux-sles12.4.tar.xz +del: clang+llvm-11.1.0-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-11.1.0-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-11.1.0-i386-unknown-freebsd11.tar.xz +del: clang+llvm-11.1.0-i386-unknown-freebsd12.tar.xz +del: clang+llvm-11.1.0-powerpc64le-linux-rhel-7.4.tar.xz +del: clang+llvm-11.1.0-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-11.1.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-11.1.0-x86_64-linux-gnu-ubuntu-20.10.tar.xz +del: clang+llvm-12.0.0-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-12.0.0-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-12.0.0-i386-unknown-freebsd11.tar.xz +del: clang+llvm-12.0.0-i386-unknown-freebsd12.tar.xz +del: clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz +del: clang+llvm-12.0.0-x86_64-linux-sles12.4.tar.xz +del: clang+llvm-12.0.1-amd64-unknown-freebsd11.tar.xz +del: clang+llvm-12.0.1-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-12.0.1-i386-unknown-freebsd11.tar.xz +del: clang+llvm-12.0.1-i386-unknown-freebsd12.tar.xz +del: clang+llvm-12.0.1-powerpc64le-linux-rhel-7.9.tar.xz +del: clang+llvm-12.0.1-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-13.0.0-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-13.0.0-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-13.0.0-i386-unknown-freebsd12.tar.xz +del: clang+llvm-13.0.0-i386-unknown-freebsd13.tar.xz +del: clang+llvm-13.0.0-powerpc64le-linux-rhel-7.9.tar.xz +del: clang+llvm-13.0.0-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-13.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +del: clang+llvm-13.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz +del: clang+llvm-13.0.1-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-13.0.1-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-13.0.1-i386-unknown-freebsd12.tar.xz +del: clang+llvm-13.0.1-i386-unknown-freebsd13.tar.xz +del: clang+llvm-13.0.1-powerpc64le-linux-rhel-7.9.tar.xz +del: clang+llvm-13.0.1-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-14.0.0-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.0-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.0-i386-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.0-i386-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.0-powerpc64le-linux-rhel-7.9.tar.xz +del: clang+llvm-14.0.0-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-14.0.0-x86_64-linux-sles12.4.tar.xz +del: clang+llvm-14.0.1-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.1-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.1-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-14.0.1-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-14.0.2-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.2-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.3-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.3-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.3-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-14.0.3-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-14.0.4-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.4-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.4-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-14.0.4-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-14.0.5-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.5-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.5-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-14.0.5-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-14.0.6-amd64-unknown-freebsd12.tar.xz +del: clang+llvm-14.0.6-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-14.0.6-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-14.0.6-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-15.0.0-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.0-powerpc64le-linux-ubuntu-18.04.6.tar.xz +del: clang+llvm-15.0.0-sparc64-unknown-linux-gnu.tar.xz +del: clang+llvm-15.0.1-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.1-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-15.0.2-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.2-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-15.0.2-x86_64-unknown-linux-gnu-rhel86.tar.xz +del: clang+llvm-15.0.2-x86_64-unknown-linux-gnu-sles15.tar.xz +del: clang+llvm-15.0.3-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.3-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-15.0.4-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.4-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-15.0.5-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.5-powerpc64le-linux-ubuntu-18.04.5.tar.xz +del: clang+llvm-15.0.6-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.6-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-15.0.7-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-15.0.7-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-16.0.0-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-16.0.0-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-16.0.0-powerpc64le-linux-ubuntu-18.04.tar.xz +del: clang+llvm-16.0.0-sparc64-unknown-linux-gnu.tar.xz +del: clang+llvm-16.0.1-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-16.0.1-powerpc64le-linux-rhel-8.4.tar.xz +del: clang+llvm-16.0.1-powerpc64le-linux-ubuntu-20.04.tar.xz +del: clang+llvm-16.0.2-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-16.0.4-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-16.0.5-amd64-unknown-freebsd13.tar.xz +del: clang+llvm-17.0.1-final_powerpc64-ibm-aix-7.2.tar.xz +del: clang+llvm-17.0.1-sparc64-unknown-linux-gnu.tar.xz +del: clang+llvm-17.0.2-sparc64-unknown-linux-gnu.tar.xz +del: clang+llvm-18.1.0-sparcv9-sun-solaris2.11.tar.xz +del: clang+llvm-18.1.0-sparcv9-unknown-linux-gnu.tar.xz diff --git a/toolchain/internal/llvm_requirements_test.golden.txt b/toolchain/internal/llvm_requirements_test.golden.txt new file mode 100644 index 000000000..97959e9aa --- /dev/null +++ b/toolchain/internal/llvm_requirements_test.golden.txt @@ -0,0 +1,120 @@ +[aarch64,darwin,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-macOS-ARM64.tar.xz +[aarch64,darwin,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-macOS-ARM64.tar.xz +[aarch64,darwin,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = LLVM-19.1.6-macOS-ARM64.tar.xz +[aarch64,darwin,'latest:<20.1.0,>17.0.4']: 19.1.7 = LLVM-19.1.7-macOS-ARM64.tar.xz +[aarch64,darwin,'latest:>=15.0.6,<16']: 15.0.7 = clang+llvm-15.0.7-arm64-apple-darwin22.0.tar.xz +[aarch64,darwin,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-arm64-apple-darwin21.0.tar.xz +[aarch64,darwin,'latest']: 20.1.3 = LLVM-20.1.3-macOS-ARM64.tar.xz +[aarch64,darwin,'first']: 14.0.6 = clang+llvm-14.0.6-arm64-apple-darwin22.3.0.tar.xz +[aarch64,linux,ubuntu,0,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-Linux-ARM64.tar.xz +[aarch64,linux,ubuntu,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-Linux-ARM64.tar.xz +[aarch64,linux,ubuntu,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,ubuntu,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-aarch64-linux-gnu.tar.xz +[aarch64,linux,ubuntu,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,ubuntu,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,ubuntu,0,'latest']: 20.1.3 = LLVM-20.1.3-Linux-ARM64.tar.xz +[aarch64,linux,ubuntu,0,'first']: 6.0.0 = clang+llvm-6.0.0-aarch64-linux-gnu.tar.xz +[aarch64,linux,raspbian,0,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-Linux-ARM64.tar.xz +[aarch64,linux,raspbian,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-Linux-ARM64.tar.xz +[aarch64,linux,raspbian,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,raspbian,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-aarch64-linux-gnu.tar.xz +[aarch64,linux,raspbian,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,raspbian,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,raspbian,0,'latest']: 20.1.3 = LLVM-20.1.3-Linux-ARM64.tar.xz +[aarch64,linux,raspbian,0,'first']: 6.0.0 = clang+llvm-6.0.0-aarch64-linux-gnu.tar.xz +[aarch64,linux,rhel,0,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-Linux-ARM64.tar.xz +[aarch64,linux,rhel,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-Linux-ARM64.tar.xz +[aarch64,linux,rhel,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,rhel,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-aarch64-linux-gnu.tar.xz +[aarch64,linux,rhel,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,rhel,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz +[aarch64,linux,rhel,0,'latest']: 20.1.3 = LLVM-20.1.3-Linux-ARM64.tar.xz +[aarch64,linux,rhel,0,'first']: 6.0.0 = clang+llvm-6.0.0-aarch64-linux-gnu.tar.xz +[aarch64,windows,'latest:<=20.1.0']: 20.1.0 = clang+llvm-20.1.0-aarch64-pc-windows-msvc.tar.xz +[aarch64,windows,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = clang+llvm-20.1.0-aarch64-pc-windows-msvc.tar.xz +[aarch64,windows,"latest:<20.1.0,>17.0.4,!=19.1.7"]: ERROR: No matching distribution found. +[aarch64,windows,"latest:<20.1.0,>17.0.4"]: ERROR: No matching distribution found. +[aarch64,windows,"latest:>=15.0.6,<16"]: ERROR: No matching distribution found. +[aarch64,windows,"first:>=15.0.6,<16"]: ERROR: No matching distribution found. +[aarch64,windows,'latest']: 20.1.3 = clang+llvm-20.1.3-aarch64-pc-windows-msvc.tar.xz +[aarch64,windows,'first']: 20.1.0 = clang+llvm-20.1.0-aarch64-pc-windows-msvc.tar.xz +[armv7a,darwin,"latest:<=20.1.0"]: ERROR: No matching distribution found. +[armv7a,darwin,"latest:<=20.1.0,>17.0.4,!=19.1.7"]: ERROR: No matching distribution found. +[armv7a,darwin,"latest:<20.1.0,>17.0.4,!=19.1.7"]: ERROR: No matching distribution found. +[armv7a,darwin,"latest:<20.1.0,>17.0.4"]: ERROR: No matching distribution found. +[armv7a,darwin,"latest:>=15.0.6,<16"]: ERROR: No matching distribution found. +[armv7a,darwin,"first:>=15.0.6,<16"]: ERROR: No matching distribution found. +[armv7a,darwin,"latest"]: ERROR: No matching distribution found. +[armv7a,darwin,"first"]: ERROR: No matching distribution found. +[armv7a,linux,ubuntu,0,'latest:<=20.1.0']: 20.1.0 = clang+llvm-20.1.0-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,ubuntu,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = clang+llvm-20.1.0-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,ubuntu,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,ubuntu,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,ubuntu,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,ubuntu,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,ubuntu,0,'latest']: 20.1.3 = clang+llvm-20.1.3-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,ubuntu,0,'first']: 6.0.0 = clang+llvm-6.0.0-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,raspbian,0,'latest:<=20.1.0']: 20.1.0 = clang+llvm-20.1.0-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,raspbian,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = clang+llvm-20.1.0-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,raspbian,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,raspbian,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,raspbian,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,raspbian,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,raspbian,0,'latest']: 20.1.3 = clang+llvm-20.1.3-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,raspbian,0,'first']: 6.0.0 = clang+llvm-6.0.0-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,rhel,0,'latest:<=20.1.0']: 20.1.0 = clang+llvm-20.1.0-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,rhel,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = clang+llvm-20.1.0-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,rhel,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,rhel,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,rhel,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,rhel,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-armv7a-linux-gnueabihf.tar.xz +[armv7a,linux,rhel,0,'latest']: 20.1.3 = clang+llvm-20.1.3-armv7a-linux-gnueabihf.tar.gz +[armv7a,linux,rhel,0,'first']: 6.0.0 = clang+llvm-6.0.0-armv7a-linux-gnueabihf.tar.xz +[armv7a,windows,"latest:<=20.1.0"]: ERROR: No matching distribution found. +[armv7a,windows,"latest:<=20.1.0,>17.0.4,!=19.1.7"]: ERROR: No matching distribution found. +[armv7a,windows,"latest:<20.1.0,>17.0.4,!=19.1.7"]: ERROR: No matching distribution found. +[armv7a,windows,"latest:<20.1.0,>17.0.4"]: ERROR: No matching distribution found. +[armv7a,windows,"latest:>=15.0.6,<16"]: ERROR: No matching distribution found. +[armv7a,windows,"first:>=15.0.6,<16"]: ERROR: No matching distribution found. +[armv7a,windows,"latest"]: ERROR: No matching distribution found. +[armv7a,windows,"first"]: ERROR: No matching distribution found. +[x86_64,darwin,'latest:<=20.1.0']: 19.1.7 = LLVM-19.1.7-macOS-X64.tar.xz +[x86_64,darwin,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = LLVM-19.1.6-macOS-X64.tar.xz +[x86_64,darwin,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = LLVM-19.1.6-macOS-X64.tar.xz +[x86_64,darwin,'latest:<20.1.0,>17.0.4']: 19.1.7 = LLVM-19.1.7-macOS-X64.tar.xz +[x86_64,darwin,'latest:>=15.0.6,<16']: 15.0.7 = clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz +[x86_64,darwin,'first:>=15.0.6,<16']: 15.0.7 = clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz +[x86_64,darwin,'latest']: 20.1.3 = LLVM-20.1.3-macOS-X64.tar.xz +[x86_64,darwin,'first']: 6.0.0 = clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz +[x86_64,linux,ubuntu,0,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-Linux-X64.tar.xz +[x86_64,linux,ubuntu,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-Linux-X64.tar.xz +[x86_64,linux,ubuntu,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = LLVM-19.1.6-Linux-X64.tar.xz +[x86_64,linux,ubuntu,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = LLVM-19.1.7-Linux-X64.tar.xz +[x86_64,linux,ubuntu,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz +[x86_64,linux,ubuntu,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz +[x86_64,linux,ubuntu,0,'latest']: 20.1.3 = LLVM-20.1.3-Linux-X64.tar.xz +[x86_64,linux,ubuntu,0,'first']: 6.0.0 = clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +[x86_64,linux,raspbian,0,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-Linux-X64.tar.xz +[x86_64,linux,raspbian,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-Linux-X64.tar.xz +[x86_64,linux,raspbian,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = LLVM-19.1.6-Linux-X64.tar.xz +[x86_64,linux,raspbian,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = LLVM-19.1.7-Linux-X64.tar.xz +[x86_64,linux,"latest:>=15.0.6,<16"]: ERROR: No matching distribution found. +[x86_64,linux,"first:>=15.0.6,<16"]: ERROR: No matching distribution found. +[x86_64,linux,raspbian,0,'latest']: 20.1.3 = LLVM-20.1.3-Linux-X64.tar.xz +[x86_64,linux,raspbian,0,'first']: 19.1.0 = LLVM-19.1.0-Linux-X64.tar.xz +[x86_64,linux,rhel,0,'latest:<=20.1.0']: 20.1.0 = LLVM-20.1.0-Linux-X64.tar.xz +[x86_64,linux,rhel,0,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = LLVM-20.1.0-Linux-X64.tar.xz +[x86_64,linux,rhel,0,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = LLVM-19.1.6-Linux-X64.tar.xz +[x86_64,linux,rhel,0,'latest:<20.1.0,>17.0.4']: 19.1.7 = LLVM-19.1.7-Linux-X64.tar.xz +[x86_64,linux,rhel,0,'latest:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz +[x86_64,linux,rhel,0,'first:>=15.0.6,<16']: 15.0.6 = clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz +[x86_64,linux,rhel,0,'latest']: 20.1.3 = LLVM-20.1.3-Linux-X64.tar.xz +[x86_64,linux,rhel,0,'first']: 6.0.0 = clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz +[x86_64,windows,'latest:<=20.1.0']: 20.1.0 = clang+llvm-20.1.0-x86_64-pc-windows-msvc.tar.xz +[x86_64,windows,'latest:<=20.1.0,>17.0.4,!=19.1.7']: 20.1.0 = clang+llvm-20.1.0-x86_64-pc-windows-msvc.tar.xz +[x86_64,windows,'latest:<20.1.0,>17.0.4,!=19.1.7']: 19.1.6 = clang+llvm-19.1.6-x86_64-pc-windows-msvc.tar.xz +[x86_64,windows,'latest:<20.1.0,>17.0.4']: 19.1.7 = clang+llvm-19.1.7-x86_64-pc-windows-msvc.tar.xz +[x86_64,windows,"latest:>=15.0.6,<16"]: ERROR: No matching distribution found. +[x86_64,windows,"first:>=15.0.6,<16"]: ERROR: No matching distribution found. +[x86_64,windows,'latest']: 20.1.3 = clang+llvm-20.1.3-x86_64-pc-windows-msvc.tar.xz +[x86_64,windows,'first']: 18.1.0 = clang+llvm-18.1.0-x86_64-pc-windows-msvc.tar.xz diff --git a/toolchain/internal/repo.bzl b/toolchain/internal/repo.bzl index c4d9835ec..c68f14a52 100644 --- a/toolchain/internal/repo.bzl +++ b/toolchain/internal/repo.bzl @@ -35,6 +35,13 @@ common_attrs = { "in the list of known llvm_distributions using the provided version. " + "If unset, a default value is set from the `llvm_version` attribute."), ), + "extra_llvm_distributions": attr.string_dict( + mandatory = False, + doc = ("A dictionary that maps distributions to their SHA256 values. " + + "It allows for simple additon of llvm distributiosn using the " + + "'utils/lvm_checksums.sh' tool. This also allows to use the " + + "distributions lists of future toolchain versions."), + ), "exec_os": attr.string( mandatory = False, doc = "Execution platform OS, if different from host OS.", @@ -50,14 +57,10 @@ llvm_repo_attrs.update({ "llvm_version": attr.string( doc = ("One of the supported versions of LLVM, e.g. 12.0.0; used with the " + "`auto` value for the `distribution` attribute, and as a default value " + - "for the `llvm_versions` attribute."), - ), - "extra_llvm_distributions": attr.string_dict( - mandatory = False, - doc = ("A dictionary that maps distributions to their SHA256 values. " + - "It allows for simple additon of llvm distributiosn using the " + - "'utils/lvm_checksums.sh' tool. This also allows to use the " + - "distributions lists of future toolchain versions."), + "for the `llvm_versions` attribute. This value can be set to `first` or " + + "`latest` in order to find the respective first or latest LLVM version " + + "supported on the OS/arch. Further, requirements can be provided, e.g. " + + "`latest:>=17.0.4,!=19.0.7`."), ), "urls": attr.string_list_dict( mandatory = False,