Skip to content

macOS: find libomp in the environment being built into (backport #58) - #59

Merged
Jim Garrison (garrison) merged 1 commit into
stable/1.7from
mergify/bp/stable/1.7/pr-58
Oct 12, 2026
Merged

Jim Garrison (garrison) merged 1 commit into
stable/1.7from
mergify/bp/stable/1.7/pr-58

Conversation

@mergify

@mergify mergify Bot commented Oct 12, 2026

Copy link
Copy Markdown

On macOS the build locates libomp by probing $CONDA_PREFIX/include/omp.h, falling back to Homebrew. That misses the case where the activated environment is not the one being built into. conda-build and rattler-build activate their own base installation and install into $PREFIX, so a recipe that provides llvm-openmp still fails:

Configuring CPU backend (_core_cpu)
Error: no OpenMP runtime found on this macOS host.
       Looked in $CONDA_PREFIX/include and /opt/homebrew/opt/libomp/include.

on a builder with no Homebrew libomp — while the header sits unexamined in $PREFIX. This is what the conda-forge osx_64 build hits (staged-recipes#35125), where CONDA_PREFIX is /Users/runner/miniforge3 and llvm-openmp 21.1.8 is installed in the host environment.

The change

Consult sys.prefix, then sys.base_prefix, after CONDA_PREFIX and before Homebrew. sys.prefix is the prefix of the interpreter running setup.py, which under both build backends is the environment the extension is built for. It is also the convention _mpi_prefix_from_env_prefix() already uses — which is why MPI detection succeeded in the same build where OpenMP failed.

CONDA_PREFIX stays first, so an ordinary activated environment behaves exactly as before. The new candidates are reachable only where the code previously fell through to Homebrew, so no build that passes today changes behavior.

This serves the intent of the original logic rather than reversing it: build against the libomp that will be loaded at import time, resolved through the interpreter's rpath. Linking the base installation's copy while installing into $PREFIX is one way to end up with two LLVM OpenMP runtimes in one process — the abort described in the README and tracked as #27.

The error message named $CONDA_PREFIX literally, which no longer describes the set of prefixes searched, so it now reports the paths actually tried, deduplicated.

Verification

The changed branch is platform.system() == 'Darwin'-only, so it is unreachable on Linux. I exercised the prefix selection directly across six cases: activated environment with the header present (unchanged); activated prefix without it but the build prefix with it (the failure above, now resolved); neither, so the Homebrew fallback still engages; both, confirming CONDA_PREFIX keeps precedence; CONDA_PREFIX unset; and only sys.base_prefix carrying it.

I do not have a macOS host, so the end-to-end check is the conda-forge osx_64 build. I will report back once it has run against this change.


This pull request was drafted by Claude Opus 5 under my guidance.


This is an automatic backport of pull request #58 done by [Mergify](https://mergify.com).

The Darwin block probes $CONDA_PREFIX/include/omp.h and falls back to Homebrew.
That misses the case where the activated environment is not the one being built
into: conda-build and rattler-build activate their own base installation and
install into $PREFIX, so a recipe that puts llvm-openmp in the host environment
still fails with

    Error: no OpenMP runtime found on this macOS host.
           Looked in $CONDA_PREFIX/include and /opt/homebrew/opt/libomp/include.

on a builder with no Homebrew libomp -- while the header sits unexamined in
$PREFIX. This is what the conda-forge osx_64 build hits.

Consult sys.prefix, then sys.base_prefix, after CONDA_PREFIX and before
Homebrew. sys.prefix is the prefix of the interpreter running setup.py, which
under both build backends is the environment the extension is built for; it is
also the convention _mpi_prefix_from_env_prefix() already uses, which is why MPI
detection succeeded in the same build where OpenMP failed.

CONDA_PREFIX stays first, so an ordinary activated environment behaves exactly
as before. The new candidates can only be reached where the code previously
fell through to Homebrew, so no build that passes today changes behavior.

This serves the intent of the original change rather than reversing it: build
against the libomp that will be LOADED at import time, resolved through the
interpreter's rpath. Linking the base installation's copy while installing into
$PREFIX is how a process ends up with two LLVM OpenMP runtimes, the abort
described in the README and tracked as #27.

The error message listed $CONDA_PREFIX literally, which no longer describes the
set of prefixes searched, so report the paths actually tried, deduplicated.

Assisted-by: Claude Opus 5
(cherry picked from commit b49c22b)
@garrison
Jim Garrison (garrison) merged commit 3159fd7 into stable/1.7 Oct 12, 2026
17 checks passed
@garrison
Jim Garrison (garrison) deleted the mergify/bp/stable/1.7/pr-58 branch October 12, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant