Skip to content

fix(build): build vendored opus so arm64 links on hosts with an Intel Homebrew - #5041

Open
yonatangross wants to merge 1 commit into
block:mainfrom
yonatangross:fix/vendored-opus-arm64
Open

fix(build): build vendored opus so arm64 links on hosts with an Intel Homebrew#5041
yonatangross wants to merge 1 commit into
block:mainfrom
yonatangross:fix/vendored-opus-arm64

Conversation

@yonatangross

Copy link
Copy Markdown

Problem

just desktop-release-build fails at link time on an Apple Silicon Mac that also has an Intel Homebrew installed:

Undefined symbols for architecture arm64:
  "_opus_encoder_create", referenced from:
      opus::Encoder::new::... in libopus-....rlib
  ...
ld: symbol(s) not found for architecture arm64

audiopus_sys's build.rs probes pkg-config first and returns early on a hit, so the vendored opus that the existing CMAKE_POLICY_VERSION_MINIMUM = "3.5" entry exists to compile never gets built. pkg-config's default search path includes /usr/local/lib/pkgconfig — the Intel Homebrew prefix — so an x86_64 libopus.a is statically linked into an arm64 binary.

CI never hits this (no Homebrew opus on the runners), which is why the opus source has to be pinned in-repo rather than left to ambient host state.

Fix

Two env vars in .cargo/config.toml, deliberately both:

var why
LIBOPUS_NO_PKG audiopus_sys's own documented bypass. States the intent — but its build.rs never emits cargo:rerun-if-env-changed=LIBOPUS_NO_PKG, so on a tree that already resolved to the system libopus, cargo reuses the cached build script and this reads as inert. (cargo clean -p audiopus_sys does not reliably evict the build-script output dir either.)
OPUS_NO_PKG_CONFIG pkg-config-rs's per-library opt-out. It is declared via rerun-if-env-changed, so it actually invalidates the cached build script and forces the vendored cmake path to run.

Setting only the first one looks correct and changes nothing, which is why both are here with the reasoning inline.

Verification

Before — build script resolved to the Intel prefix:

cargo:info=Found `Opus` via `pkg_config`.
cargo:rustc-link-search=native=/usr/local/Cellar/opus/1.6.1/lib
cargo:rustc-link-lib=static=opus

After:

cargo:info=Bypassed `pkg-config`.
cargo:info=Building Opus via CMake.
cargo:rustc-link-search=native=.../release/build/audiopus_sys-.../out/lib

just desktop-release-build aarch64-apple-darwin then produces a bundle whose Contents/MacOS/* are 7/7 arm64, and opus is statically linked (no dynamic reference).

Anyone can reproduce the original failure with brew install opus under an Intel Homebrew on an Apple Silicon host.

Scope

One file, config only. No behaviour change on any host that does not have a system libopus — the vendored path is what CI already takes.

`audiopus_sys` probes pkg-config first and returns early on a hit, so the
vendored opus that `CMAKE_POLICY_VERSION_MINIMUM` exists to compile never
gets built when the host has a system libopus. On an Apple Silicon Mac that
also carries an Intel Homebrew at /usr/local, pkg-config's default search
path includes /usr/local/lib/pkgconfig, so an x86_64 libopus is linked into
an arm64 binary and the desktop build dies at link time with
"Undefined symbols for architecture arm64: _opus_encoder_create, ...".

CI never hits this (no Homebrew opus), which is why the opus source has to
be pinned here rather than left to ambient host state.

Sets both bypass vars deliberately: LIBOPUS_NO_PKG is audiopus_sys's own
documented switch, but its build.rs never emits
`cargo:rerun-if-env-changed=LIBOPUS_NO_PKG`, so on a tree that already
resolved to the system libopus cargo reuses the cached build script and the
setting reads as inert. OPUS_NO_PKG_CONFIG is declared by pkg-config-rs via
rerun-if-env-changed, so it actually invalidates the cached script.

Verified the intended path now runs:
  cargo:info=Bypassed `pkg-config`.
  cargo:info=Building Opus via CMake.
  cargo:rustc-link-search=native=.../release/build/audiopus_sys-.../out/lib

Signed-off-by: Yonatan Gross <yonatan2gross@gmail.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@yonatangross
yonatangross requested a review from a team as a code owner August 6, 2026 11:25
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