The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=e68d702b3a1fc52145e70d861db89a0f20bfc3a0
commit e68d702b3a1fc52145e70d861db89a0f20bfc3a0 Author: John Baldwin <j...@freebsd.org> AuthorDate: 2025-08-06 20:13:13 +0000 Commit: John Baldwin <j...@freebsd.org> CommitDate: 2025-08-06 20:13:13 +0000 cross-build make.py: Handle lld brew packages on macOS Homebrew uses separate packages for llvm and lld starting with llvm19. To handle this case automatically, pass the binary_name to default_cross_toolchain() and only use the automatic path for a given binary if the binary is found in the path (not just if the directory exists). Add a second clause for ld.lld that looks for a lld package if lld wasn't found in the llvm directory. Note that manually specifying the path cannot use a single --cross-bindir option. Instead, XLD must be manually set in addition to --cross-bindir when requesting a specific version. Reviewed by: arichardson Differential Revision: https://reviews.freebsd.org/D51653 --- tools/build/make.py | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/tools/build/make.py b/tools/build/make.py index ec42cb70dd21..618a2aa7abb0 100755 --- a/tools/build/make.py +++ b/tools/build/make.py @@ -40,6 +40,7 @@ # --cross-bindir=/path/to/cross/compiler buildworld -DWITH_FOO TARGET=foo # TARGET_ARCH=bar` import argparse +import functools import os import shlex import shutil @@ -178,24 +179,41 @@ def check_xtool_make_env_var(varname, binary_name): return global parsed_args if parsed_args.cross_bindir is None: - parsed_args.cross_bindir = default_cross_toolchain() + cross_bindir = default_cross_toolchain(binary_name) + else: + cross_bindir = parsed_args.cross_bindir return check_required_make_env_var(varname, binary_name, - parsed_args.cross_bindir) + cross_bindir) + + +@functools.cache +def brew_prefix(package: str) -> str: + path = subprocess.run(["brew", "--prefix", package], stdout=subprocess.PIPE, + stderr=subprocess.PIPE).stdout.strip() + debug("Inferred", package, "dir as", path) + return path.decode("utf-8") +def binary_path(bindir: str, binary_name: str) -> "Optional[str]": + try: + if bindir and Path(bindir, "bin", binary_name).exists(): + return str(Path(bindir, "bin")) + except OSError: + pass + return None -def default_cross_toolchain(): +def default_cross_toolchain(binary_name: str) -> str: # default to homebrew-installed clang on MacOS if available if sys.platform.startswith("darwin"): if shutil.which("brew"): - llvm_dir = subprocess.run([ - "brew", "--prefix", "llvm"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip() - debug("Inferred LLVM dir as", llvm_dir) - try: - if llvm_dir and Path(llvm_dir.decode("utf-8"), "bin").exists(): - return str(Path(llvm_dir.decode("utf-8"), "bin")) - except OSError: - return None + bindir = binary_path(brew_prefix("llvm"), binary_name) + if bindir: + return bindir + + # brew installs lld as a separate package for LLVM 19 and later + if binary_name == "ld.lld": + bindir = binary_path(brew_prefix("lld"), binary_name) + if bindir: + return bindir return None