diff --git a/MODULE.bazel b/MODULE.bazel index 44d9e6954dcb..b112f43de446 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -258,18 +258,13 @@ single_version_override( ) bazel_dep( - name = "toolchains_llvm", - version = "1.8.0", - dev_dependency = True, -) - -llvm = use_repo_rule("@toolchains_llvm//toolchain:rules.bzl", "llvm") - -llvm( name = "llvm", + version = "0.8.16", dev_dependency = True, - llvm_versions = {"": "22.1.7"}, ) +# N.B. We must NOT register llvm's toolchain here. We want to use the +# auto-detecting toolchain, above ("local_config_cc"). We only use llvm +# for linting (clang-format) and testing (llvm-objdump). bazel_dep( name = "ruff_prebuilt", diff --git a/tools/install/libdrake/BUILD.bazel b/tools/install/libdrake/BUILD.bazel index 80fddbe377cb..564346d10e8b 100644 --- a/tools/install/libdrake/BUILD.bazel +++ b/tools/install/libdrake/BUILD.bazel @@ -494,8 +494,11 @@ drake_py_unittest( timeout = "moderate", data = [ ":libdrake.so", - "@llvm//:bin/llvm-objdump", + "@llvm//tools:llvm-objdump", ], + env = { + "LLVM_OBJDUMP_RLOCATIONPATH": "$(rlocationpath @llvm//tools:llvm-objdump)", + }, deps = [ "@rules_python//python/runfiles", lief_requirement("lief"), diff --git a/tools/install/libdrake/test/exported_symbols_test.py b/tools/install/libdrake/test/exported_symbols_test.py index c8513c3cfd7b..927bdb7ed8d8 100644 --- a/tools/install/libdrake/test/exported_symbols_test.py +++ b/tools/install/libdrake/test/exported_symbols_test.py @@ -1,4 +1,5 @@ import bisect +import os import struct import subprocess import unittest @@ -249,7 +250,7 @@ def _global_ctors_dtors(symbols): manifest = runfiles.Create() objdump_all = subprocess.check_output( [ - manifest.Rlocation("llvm/bin/llvm-objdump"), + manifest.Rlocation(os.environ["LLVM_OBJDUMP_RLOCATIONPATH"]), LIBDRAKE, "-Mintel", "--no-addresses", diff --git a/tools/lint/BUILD.bazel b/tools/lint/BUILD.bazel index 87d4a04209ef..2d0af1ccc506 100644 --- a/tools/lint/BUILD.bazel +++ b/tools/lint/BUILD.bazel @@ -47,7 +47,7 @@ drake_py_library( srcs = ["clang_format.py"], data = [ "//:.clang-format", - "@llvm//:bin/clang-format", + "@llvm//tools:clang-format", ], deps = [ ":module_py", diff --git a/tools/lint/clang_format.py b/tools/lint/clang_format.py index 67f95a72d952..0df7a8e5c608 100644 --- a/tools/lint/clang_format.py +++ b/tools/lint/clang_format.py @@ -1,18 +1,19 @@ """Drake's wrapper for the clang-format binary.""" import os -from pathlib import Path import sys from python import runfiles def get_clang_format_path(): + # In our runfiles, there should be exactly one path that looks like + # "llvm+{module_extension_...}-{version}-{os}-{arch}/bin/clang-format". + # Find and return it (or raise an error). manifest = runfiles.Create() - path = Path(manifest.Rlocation("llvm/bin/clang-format")) - if not path.is_file(): - raise RuntimeError(f"Could not find required clang-format at {path}") - return path + matches = list(manifest.root().glob("llvm+*/bin/clang-format")) + assert len(matches) == 1, repr(matches) + return matches[0] def _main():