Skip to content

llvm: Clang doesn't use SDKROOT when linking #197277

@madsmtm

Description

@madsmtm

brew gist-logs <formula> link OR brew config AND brew doctor output

% brew gist-logs llvm@18
Error: No logs.

% brew gist-logs llvm@19
Error: No logs.

% brew config
HOMEBREW_VERSION: 4.4.4
ORIGIN: https://github.com/Homebrew/brew
HEAD: 824efa8836dc226aa92dbbf7404c1b4a66707cca
Last commit: 7 days ago
Core tap JSON: 10 Nov 22:51 UTC
Core cask tap JSON: 10 Nov 22:51 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 8
Homebrew Ruby: 3.3.5 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.3.5/bin/ruby
CPU: octa-core 64-bit dunno
Clang: 16.0.0 build 1600
Git: 2.39.5 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 8.7.1 => /usr/bin/curl
macOS: 14.6.1-arm64
CLT: 16.1.0.0.1.1729049160
Xcode: N/A
Rosetta 2: false

% brew doctor
Your system is ready to brew.

Note that the system is a clean virtual machine with a newly installed homebrew. The problem has also been reproduced here.

Verification

  • My brew doctor output says Your system is ready to brew. and am still able to reproduce my issue.
  • I ran brew update and am still able to reproduce my issue.
  • I have resolved all warnings from brew doctor and that did not fix my problem.
  • I searched for recent similar issues at https://github.com/Homebrew/homebrew-core/issues?q=is%3Aissue and found no duplicates.

What were you trying to do (and why)?

It is generally expected that setting the SDKROOT environment variable (or the -isysroot flag) when compiling with Clang on macOS selects a different SDK. xcrun, for example, uses this to make it easy to select a different SDK when compiling.

This is somewhat supported by the Clang provided by the llvm package, but the SDK that llvm was built with is always selected when linking instead of the value set by xcrun / in SDKROOT / with -isysroot.

This is likely to affect cross compilation (to iOS/tvOS/watchOS/visionOS). I'm investigating this because of rust-lang/rust#131477 and rust-lang/cc-rs#1278, since it is unclear how downstream users such as rustc should pass a different SDK root.

The following contrived example program fails to link with the macOS 15.1 SDK for this reason:

#import <os/lock.h>

int main(int argc, char *argv[]) {
    if (@available(macos 15.0, *)) {
        // Use some API that's only available on macOS 15.0 or newer
        os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
        os_unfair_lock_lock_with_flags(&lock, OS_UNFAIR_LOCK_FLAG_ADAPTIVE_SPIN);
    }
    return 0;
}

What happened (include all command output)?

Linking fails with:

Undefined symbols for architecture arm64:
 "_os_unfair_lock_lock_with_flags", referenced from:
      _main in foo-21aa0e.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

What did you expect to happen?

The macOS 15.1 SDK is used, also when linking, and compilation and linking succeeds.
OR
An error at compile-time because the macOS 14.0 SDK is consistently used.

Step-by-step reproduction instructions (by running brew commands)

  1. Install llvm package (any version):

    brew install llvm@19

  2. Install Xcode 15.4 and Xcode 16.1 (or equivalent Command Line Tools), so that the macOS 14.0 and macOS 15.1 SDKs are available.

  3. Put the example program above in foo.m.

  4. Try to compile with the macOS 14.0 SDK (this fails as expected, because the function isn't available in the old SDK):

    xcrun -sdk macosx14.0 clang foo.m
    xcrun -sdk macosx14.0 /opt/homebrew/opt/llvm@19/bin/clang foo.m
  5. Compile with Xcode Clang and macOS 15.1 SDK (this works):

    xcrun -sdk macosx15.1 clang foo.m
  6. Compile with Clang provided by llvm package and macOS 15.1 SDK (this fails linking):

    xcrun -sdk macosx15.1 /opt/homebrew/opt/llvm@19/bin/clang foo.m

Use -v to see that Clang always passes the same value to ld's -syslibroot.

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleNo recent activityupstream issueAn upstream issue report is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions