Repository navigation
BUG: Clang linker fails on macOS 27 Beta ARM64 — ld: library 'd64' not found #2268
Description
Activity
Confirming this on macOS 27.0 (26A428) + Command Line Tools 27.0.0.0 + Apple clang 21.0.0 (clang-2100.3.34.2), PyTensor 3.2.3 / PyMC 6.2.0.
The flag is still on
main(pytensor/link/c/cmodule.py, gated onint(platform.mac_ver()[0].split(".")[0]) >= 15), so no released version is unaffected.Two things that may narrow the fix:
-
On this toolchain the classic-linker selection is not renamed, it is gone:
clang++ -ld64→ld: library 'd64' not foundclang++ -Wl,-ld64→ same error, solditself rejects it tooclang++ -Wl,-ld_classic→ld: warning: -ld_classic is no longer supported and will be ignored
The
mac_ver() >= 15gate therefore has no target left: on macOS ≥ 27 the flag should just be dropped. -
cxx=""works but disables C compilation entirely — much slower, and it rules out samplers that need the compiled logp. A wrapper that strips the flag keeps C compilation:cat > /usr/local/bin/clang-no-ld64 <<'EOF' #!/bin/bash args=() for a in "$@"; do [[ "$a" == "-ld64" ]] || args+=("$a"); done exec /usr/bin/clang++ "${args[@]}" EOF chmod +x /usr/local/bin/clang-no-ld64 export PYTENSOR_FLAGS="cxx=/usr/local/bin/clang-no-ld64" # or cxx = ... in .pytensorrc
Verified: models that failed with the exact CompileError above compile and sample normally.
-
Why it looks like two errors:
.sofiles compiled before the OS upgrade keep loading, so the failure only appears on the next recompile. Any Python patch bump is enough, since the compiledir tag changes (compiledir_macOS-27.0-arm64-arm-64bit-arm-3.12.14-64) and the lazylinker must be rebuilt — hence the follow-up "Version check of the existing lazylinker compiled file. Looking for version 0.32, but found None".
-
Can I request your attention on this one, maybe @ricardoV94? This is a major issue for anyone who has updated to MacOS 27
Can I request your attention on this one, maybe @ricardoV94? This is a major issue for anyone who has updated to MacOS 27
Are you installing via conda?
In my case, no conda involved. I’m installing from PyPI using uv in a virtual environment, with Homebrew Python 3.12.14 (macOS ARM64), PyTensor 3.2.3 and PyMC 6.2.0.
Can you try with conda. The suggested way of working with C backend and respective compilers is to use the conda release/env. If that fails equally we need to take a look
I have applied and validated a host-local workaround on macOS 27.0 / Apple Clang 21. It unblocks current development across six separate PyTensor worktrees while retaining C compilation: a forced PyTensor C-link and a small PyMC NUTS sample both pass.
Workaround applied on this machine
~/.local/bin/pytensor-clang++-macos27(made executable):#!/bin/bash set -euo pipefail if [[ "$(/usr/bin/uname -s)" == "Darwin" ]]; then macos_major="$(/usr/bin/sw_vers -productVersion | /usr/bin/cut -d. -f1)" else macos_major=0 fi if [[ "$macos_major" =~ ^[0-9]+$ ]] && ((macos_major >= 27)); then args=() for arg in "$@"; do [[ "$arg" == "-ld64" ]] || args+=("$arg") done exec /usr/bin/clang++ "${args[@]}" fi exec /usr/bin/clang++ "$@"
~/.pytensorrc:[global] cxx=/absolute/path/to/pytensor-clang++-macos27
The shim removes only
-ld64on macOS >= 27 and passes every other compiler argument through. Because PyTensor reads this user configuration, it applies to all local PyTensor environments without changing repository files or individual virtualenvs. Existing Python kernels need a restart.This is a local mitigation, not a proposed substitute for the upstream fix. To answer the installation question cleanly, I will upgrade another machine to macOS 27 and test the same minimal reproduction in fresh pip and conda environments with this shim disabled, then report back.
Adding a data point: this is triggered by the Command Line Tools / Xcode 27.0 toolchain, not by macOS 27. It reproduces on macOS 26.7 (25G229) once Software Update installs Command Line Tools for Xcode 27.0, which it offers to the previous macOS as a separate update.
- macOS 26.7 (25G229), arm64, no Xcode.app;
xcode-select -p→/Library/Developer/CommandLineTools - Command Line Tools for Xcode 27.0 (
pkgutil --pkg-info=com.apple.pkg.CLTools_Executables→ 27.0.0.0.1788430756), Apple clang 21.0.0,ld-27037.1 - PyTensor 2.38.3 / PyMC 5.28.5 from PyPI in a uv venv (no conda), Python 3.12.13
- The same machine compiled fine on macOS 26.6.x with Command Line Tools 26.6. The first fresh compile after the 27.0 tools landed fails with
ld: library 'd64' not found.
So a fix or workaround gated on
macOS >= 27would miss this case. Both shims earlier in this thread gate that way, so they're no-ops on macOS 26 with the 27 tools. The flag should also not be dropped for every macOS ≥ 15: older toolchains may still rely on-ld64to avoid the Xcode 15ld_primeproblems the gate was written for.Suggested fix: decide from the linker, not the OS version. Probe once per process: link a trivial shared object with
-ld64, and drop the flag only if that fails. For example, incompile_args:def _ld64_supported(cxx): # tiny C file -> cxx -shared -undefined dynamic_lookup -ld64 t.c -o t.so # return False if it fails with "library 'd64' not found"
We're carrying this as a local patch (wrapping
GCC_compiler.compile_args). It has been verified with the PyMC NUTS and nutpie samplers, and it's a no-op on toolchains that still accept-ld64.- macOS 26.7 (25G229), arm64, no Xcode.app;
Describe the issue:
Related issues
-ld64root cause, different linker error message)This is a distinct manifestation of the same issue: PyTensor passes
-ld64as a compiler flag, but on macOS 27 Beta (Sequoia successor, arm64), theClang linker interprets
-ld64as-l d64(i.e. "link against a library namedd64") rather than as the linker-selector flag. This produces a different errormessage than BUG: Compatibility Issue for pytensor on macOS 15.4 #1342/BUG: clang linker fails #1347, suggesting the flag's interpretation changed again in
the newer Xcode/Clang shipped with macOS 27.
Environment
/usr/bin/clang++(clang-2100.3.23.3)Root cause (as understood)
-ld64inpytensor/link/c/cmodule.pyis meant to select the classic macOSlinker (
ld64) over Apple's new linker (ld/lld). On macOS 27 Beta, Clangparses this as
-l d64(link against libraryd64) rather than as a linkerselection flag, because the flag syntax changed in the Xcode toolchain bundled
with this beta OS version.
Workaround (confirmed working)
Setting
pytensor.config.cxx = ""before importing PyMC forces PyTensor touse its Python-mode backend (no C compilation), bypassing the Clang flag entirely.
Performance impact on Apple Silicon (M3 Pro, Python-mode vs C-compiled):
Alternatively, via environment variable before running the script:
Reproducable code example:
Error message:
PyTensor version information:
Name: pytensor
Version: 3.0.7
Apple clang version 21.0.0 (clang-2100.3.23.3)
Target: arm64-apple-darwin27.0.0
Thread model: posix
Context for the issue:
This issue appears to affect all recent macOS versions (15.3+, 15.4, and now 27
Beta), with slightly different error messages depending on exact Xcode/Clang
version. The common root is the
-ld64flag in PyTensor's compile command beingincompatible with Apple's evolving linker toolchain. A more robust fix would be
to detect the macOS linker version at compile time and either omit
-ld64orreplace it with
-Wl,-ld_classicon macOS versions where the latter is supported.