Skip to content

Conversation

@SchmErik
Copy link

@SchmErik SchmErik commented Jan 22, 2026

The livekit crate poses a devex challenge for those using this crate on macOS and iOS due to developers having to set these flags. Placing this flag in the .config.toml only works if you're building the crate from the rust-sdks repo but does not get added if a programmer has a rust project that depends on the livekit rust-sdk crate. By adding the flag in the build.rs of the livekit crate, developers that use this crate do not need to worry about setting this flag for macOS and iOS.

Fixes: #795

Summary by CodeRabbit

  • Chores
    • Enhanced build configuration to support macOS and iOS platforms with proper system library linking.

✏️ Tip: You can customize this high-level summary in your review settings.

@CLAassistant
Copy link

CLAassistant commented Jan 22, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link

coderabbitai bot commented Jan 22, 2026

📝 Walkthrough

Walkthrough

A build script is added to explicitly enable Objective-C linking for macOS and iOS targets by setting the -ObjC compiler flag, addressing WebRTC binary compatibility issues with newer macOS versions.

Changes

Cohort / File(s) Summary
Build Script Configuration
livekit/build.rs
New Rust build script that reads the target OS environment variable and conditionally applies -ObjC linker flag for macOS and iOS targets to ensure proper Objective-C category linking for prebuilt WebRTC binaries.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A linking spell for Apple's shore,
Where -ObjC flags were needed more,
The build script hops with careful might,
To make WebRTC load just right!

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The PR partially addresses issue #795 by embedding the -ObjC linker flag in build.rs, which is a necessary step for proper SDK linking on macOS, but does not directly resolve the root cause of the NSInvalidArgumentException crash related to WebRTC binary incompatibility. Clarify whether this linker flag change alone resolves the macOS 26 crash or if additional WebRTC binary compatibility fixes are needed to fully address issue #795.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding the -ObjC flag to build.rs for macOS and iOS targets.
Out of Scope Changes check ✅ Passed The change is scoped appropriately: it adds a build.rs file with only the -ObjC flag logic for macOS and iOS, with no unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between baf9db1 and ba6ff01.

📒 Files selected for processing (1)
  • livekit/build.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • livekit/build.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Build (x86_64-pc-windows-msvc)
  • GitHub Check: Build (aarch64-pc-windows-msvc)
  • GitHub Check: Build (x86_64-unknown-linux-gnu)
  • GitHub Check: Build (aarch64-apple-darwin)
  • GitHub Check: Build (armv7-linux-androideabi)
  • GitHub Check: Build (aarch64-unknown-linux-gnu)
  • GitHub Check: Build (aarch64-linux-android)
  • GitHub Check: Build (x86_64-linux-android)
  • GitHub Check: Build (aarch64-apple-ios)
  • GitHub Check: Build (x86_64-apple-darwin)
  • GitHub Check: Build (aarch64-apple-ios-sim)
  • GitHub Check: Test (x86_64-pc-windows-msvc)
  • GitHub Check: Test (x86_64-apple-darwin)
  • GitHub Check: Test (x86_64-unknown-linux-gnu)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@livekit/build.rs`:
- Around line 1-13: Update the license header in livekit/build.rs to match the
repo's standard Rust header template: replace the current block comment with the
exact multi-line header used across other Rust files including the SPDX
identifier (SPDX-License-Identifier: Apache-2.0), the canonical Apache-2.0
notice text and the correct year/owner formatting (LiveKit, Inc.). Ensure the
header text and SPDX line exactly match other Rust source files so Hawkeye
recognizes it.
- Around line 15-20: The build script currently emits cargo:rustc-link-arg
inside main (in build.rs) which does not propagate to dependent crates; update
the packaging by adding links = "livekit" to Cargo.toml and change the build
script (the main function in build.rs) to print a custom metadata key instead
(e.g., println!("cargo:objc_link_arg=-ObjC")) so downstream crates can pick it
up via the DEP_* env var, then document that dependents must read
DEP_LIVEKIT_OBJC_LINK_ARG in their build.rs and re-emit it as
cargo:rustc-link-arg (or re-add the arg themselves); optionally note the
alternative of using cargo:rustc-link-arg-bin or cargo:rustc-link-arg-cdylib if
only final binaries/cdylibs need the flag.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b63e11 and baf9db1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • .cargo/config.toml
  • livekit/build.rs
💤 Files with no reviewable changes (1)
  • .cargo/config.toml
🧰 Additional context used
🪛 GitHub Actions: License Check
livekit/build.rs

[error] 1-1: Hawkeye check failed: Found header missing in files: ["/home/runner/work/rust-sdks/rust-sdks/livekit/build.rs"]

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: Build (x86_64-apple-darwin)
  • GitHub Check: Build (aarch64-apple-ios-sim)
  • GitHub Check: Build (x86_64-linux-android)
  • GitHub Check: Build (aarch64-linux-android)
  • GitHub Check: Build (aarch64-apple-darwin)
  • GitHub Check: Build (aarch64-unknown-linux-gnu)
  • GitHub Check: Build (armv7-linux-androideabi)
  • GitHub Check: Build (aarch64-pc-windows-msvc)
  • GitHub Check: Build (x86_64-unknown-linux-gnu)
  • GitHub Check: Build (aarch64-apple-ios)
  • GitHub Check: Build (x86_64-pc-windows-msvc)
  • GitHub Check: Test (x86_64-apple-darwin)
  • GitHub Check: Test (x86_64-pc-windows-msvc)
  • GitHub Check: Test (x86_64-unknown-linux-gnu)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1 to +13
// Copyright 2026 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix license header format to satisfy Hawkeye check.
CI reports the header is missing for this file; the current header likely doesn’t match the repo’s required template. Please align it with the standard header used in other Rust files (often includes an SPDX line and exact wording/year format).

📝 Possible minimal adjustment (if SPDX is expected)
+// SPDX-License-Identifier: Apache-2.0
 // Copyright 2026 LiveKit, Inc.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Copyright 2026 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
🧰 Tools
🪛 GitHub Actions: License Check

[error] 1-1: Hawkeye check failed: Found header missing in files: ["/home/runner/work/rust-sdks/rust-sdks/livekit/build.rs"]

🤖 Prompt for AI Agents
In `@livekit/build.rs` around lines 1 - 13, Update the license header in
livekit/build.rs to match the repo's standard Rust header template: replace the
current block comment with the exact multi-line header used across other Rust
files including the SPDX identifier (SPDX-License-Identifier: Apache-2.0), the
canonical Apache-2.0 notice text and the correct year/owner formatting (LiveKit,
Inc.). Ensure the header text and SPDX line exactly match other Rust source
files so Hawkeye recognizes it.

Comment on lines +15 to +20
fn main() {
match std::env::var("CARGO_CFG_TARGET_OS").as_deref() {
Ok("macos") | Ok("ios") => println!("cargo:rustc-link-arg=-ObjC"),
Ok(_) => return,
Err(e) => panic!("{e}"),
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Cargo cargo:rustc-link-arg propagate dependency build script downstream crates

💡 Result:

Short answer: No — cargo:rustc-link-arg affects only the crate whose build script emitted it; it is not propagated to downstream (dependent) crates. See the Cargo build-script docs for rustc-link-arg (applies when building that package's supported targets) and the metadata section (only key=value metadata is passed to immediate dependents — not rustc-link-arg instructions). [1][2]

Sources:

  • cargo build-script reference — rustc-link-arg description. [1]
  • cargo build-script reference — build-script metadata passed to dependents (only key=value, immediate dependents). [2]

🌐 Web query:

Cargo library crate pass linker flags to dependents -ObjC

💡 Result:

Short answer: You can't force-add a generic linker flag like -ObjC from a library crate so it automatically applies to downstream dependents. Cargo's build-script linker-arg outputs are only applied to the crate being built (and to certain target kinds), not propagated to arbitrary dependents. (rustwiki.org)

Options/workarounds:

  • Document the requirement and ask downstream crates (or the final binary) to add the flag in their build script: println!("cargo:rustc-link-arg=-ObjC");. This is the simplest reliable approach. (docs.rs)
  • If you control the final crate type (e.g., produce a cdylib or the final binary), emit the appropriate rustc-link-arg variant from your build script (cargo:rustc-link-arg-cdylib or rustc-link-arg when building the final binary). Those apply to those target kinds. (docs.rs)
  • Use a small helper crate that exposes a build-time configuration (via its links field + a convention for propagating values) and have dependents call that helper from their build.rs to re-emit the link flags. Some projects use this pattern to surface native/link options to dependents. (Cargo does let you emit cfg/env values from a dependency which dependents can read and re-emit.) (docs.rs)

If you want, tell me whether the consumer is a binary, cdylib, or rlib and I’ll give the exact build.rs lines to emit.

Citations:


🌐 Web query:

Cargo build script instructions propagation rust-link-arg library dependencies

💡 Result:

Short answer: Cargo does not automatically propagate cargo:rustc-link-arg (or other rustc-* instructions) from a library crate to its dependents. To have downstream crates receive linker args, expose them as build-script metadata (via package.links and/or custom metadata keys) and have dependents’ build scripts read DEP__* environment variables and re-emit the appropriate cargo:rustc-link-arg (or rustc-link-lib / rustc-link-search) for their own build.

Steps (minimal example):

  1. In the library crate (Cargo.toml):
  • set a links name so Cargo will pass metadata:
    [package]
    links = "mylib"
  • in build.rs emit metadata keys:
    println!("cargo:MY_LINKER_ARG=-Wl,--foo");
    // and emit any rustc-link-lib / rustc-link-search for the library itself if needed:
    println!("cargo:rustc-link-lib=static=mylib");
  1. In a dependent crate’s build.rs:
  • read the env var created by Cargo: DEP_<UPPERCASE_LINKS>_MY_LINKER_ARG
    let v = std::env::var("DEP_MYLIB_MY_LINKER_ARG").ok();
  • if present, re-emit it as a rustc link arg for that crate:
    println!("cargo:rustc-link-arg={}", v.unwrap());
    This ensures the final binary/library being built gets the linker flag. (Metadata is only passed to immediate dependents, not transitive dependents.)

References: Cargo build-script docs (explains cargo:rustc-link-arg and metadata / DEP_* variables and links key). [1][2].

Sources:
[1] Cargo build scripts reference — rustc-link-arg / rustc-cdylib-link-arg.
[2] Cargo build scripts reference — package.links and DEP__* metadata.


cargo:rustc-link-arg does not propagate to dependent crates—the current implementation will not reach downstream users.

cargo:rustc-link-arg applies only to the crate whose build script emits it; Cargo does not forward it to dependents. To ensure -ObjC reaches downstream crates, use the links field + metadata pattern:

  1. Add links = "livekit" to Cargo.toml
  2. Emit custom metadata from build.rs instead of cargo:rustc-link-arg:
    println!("cargo:objc_link_arg=-ObjC");
    
  3. Document that downstream crates must read DEP_LIVEKIT_OBJC_LINK_ARG in their build script and re-emit it as cargo:rustc-link-arg, or add it themselves if they directly link the native code.

Alternatively, if all dependents are final binaries/cdylibs, use cargo:rustc-link-arg-bin or cargo:rustc-link-arg-cdylib respectively (though these still apply only to that specific build, not transitively).

🤖 Prompt for AI Agents
In `@livekit/build.rs` around lines 15 - 20, The build script currently emits
cargo:rustc-link-arg inside main (in build.rs) which does not propagate to
dependent crates; update the packaging by adding links = "livekit" to Cargo.toml
and change the build script (the main function in build.rs) to print a custom
metadata key instead (e.g., println!("cargo:objc_link_arg=-ObjC")) so downstream
crates can pick it up via the DEP_* env var, then document that dependents must
read DEP_LIVEKIT_OBJC_LINK_ARG in their build.rs and re-emit it as
cargo:rustc-link-arg (or re-add the arg themselves); optionally note the
alternative of using cargo:rustc-link-arg-bin or cargo:rustc-link-arg-cdylib if
only final binaries/cdylibs need the flag.

@ladvoc
Copy link
Contributor

ladvoc commented Jan 28, 2026

Hi @SchmErik, thank you for your contribution! Please integrate with main as it will fix CI builds.

The `livekit` crate poses a devex challenge for those using this crate on macOS
and iOS due to developers having to set these flags. Placing this flag in the
.config.toml only works if you're building the crate from the `rust-sdks` repo
but does not get added if a programmer has a rust project that depends on the
livekit rust-sdk crate. A better alternative would be to place the flags within
the build.rs of the `livekit` crate. By doing so, developers that depend on the
livekit crate do not need to worry about setting this flag for macOS and iOS.

Fix this by moving this flag from the `config.toml` to the `build.rs`.
@SchmErik SchmErik force-pushed the fix-mac-linker-flag branch from baf9db1 to ba6ff01 Compare January 28, 2026 22:56
@SchmErik SchmErik changed the title macOS and iOS: move -ObjC flag to build.rs macOS and iOS: add -ObjC flag to build.rs Jan 28, 2026
@SchmErik
Copy link
Author

@ladvoc I've updated this branch. I realized that the linker flag doesn't proapagate down to dependent crates so I added the flag as a part of the build script only. I'm assuming that a large majority of users typically only depend on the livekit crate

@ladvoc ladvoc requested a review from cloudwebrtc January 28, 2026 23:10
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.

NSInvalidArgumentException crash on macOS 26 (Tahoe) - +[NSString stringForAbslStringView:] unrecognized selector

3 participants