-
-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
llvm: Clang doesn't use SDKROOT
when linking
#197277
Comments
See also discussion in #196094 (comment) |
Works for me:
But I'm guessing the important bit that's left out of your reproduction steps is that you must be testing this on macOS 14 (which I am not). |
I think this is an upstream bug. You can reproduce this with Apple Clang as well:
|
Indeed, this was on a macOS 14.0 VM. The problem can also be encountered if you try to cross-compile (assuming you have Xcode installed): brew install llvm@18 # Different problem on llvm@19 because of #197278
echo """
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
return UIApplicationMain(argc, argv, nil, nil);
}
""" > bar.m
xcrun -sdk iphoneos /opt/homebrew/opt/llvm@18/bin/clang -target arm64-apple-ios -framework UIKit bar.m |
Dunno, I guess it depends on what the desired behaviour of setting both But it could be somewhat fixed by Homebrew by setting |
This makes me think that the issue is not related to #196094, then, because we set homebrew-core/Formula/l/llvm@18.rb Line 132 in 08e2379
|
Not convinced -- setting Does it work for you if you replace
Yea, we could maybe just make |
Indeed, this is not related to #196094, I only linked it for the context.
Agree that it's not a good solution, since it would completely ignore
Agreed that I'm not sure what the right behaviour is either 🤷. |
Right -- in that case, this is definitely an upstream bug. Can you reproduce this with |
I removed all the config files in If you're debugging this, then the behaviour here can be reproduced with Apple Clang with: clang --sysroot $(xcrun -sdk macosx14.5 --show-sdk-path) -isysroot $(xcrun -sdk macosx15.1 --show-sdk-path) foo.m
# Or
xcrun -sdk macosx15.1 clang --sysroot $(xcrun -sdk macosx14.5 --show-sdk-path) foo.m
# Or
SDKROOT=$(xcrun -sdk macosx15.1 --show-sdk-path) clang --sysroot $(xcrun -sdk macosx14.5 --show-sdk-path) foo.m I.e. specify an old SDK for |
I think one workaround here is to pass You might also be able to do mkdir -p ~/.config/clang
touch ~/.config/clang/$(clang --print-target-triple).cfg to make
just work. |
Or, I guess the most obvious workaround: pass |
I am indeed considering whether |
You could try passing
should just work for you, even on macOS 14. Though maybe you don't want to target macOS 15.1, and instead want to target something older but use the |
The behaviour comes from llvm/llvm-project@8438464. Looking at the code that was from a time This is no longer the case so I believe the code is now wrong and should probably be inverted. I think it makes sense to propose this upstream and apply a patch rather than try do weird workarounds here, particularly given the workarounds wouldn't even be consistent between Hard to pinpoint when the header includes logic changed but I suspect it's been a while, so this issue probably affects every LLVM version we ship. |
Can confirm that this issue is present in Do you want to work on a fix upstream? If not, then I can try to, but I get the feeling you're more experienced with that. |
I'll send the patch -- @Bo98 already has two outstanding PRs waiting for a review upstream. |
…stently On Darwin, `clang` currently prioritises `-isysroot` over `--sysroot` when selecting headers, but does the reverse when setting `-syslibroot` for the linker, which determines library selection. This is wrong, because it leads to using headers that are of different versions from the libraries being linked. We can see this from: ❯ bin/clang -v -xc - -o /dev/null \ -isysroot /Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.sdk \ --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.sdk <<<'int main(){}' clang version 20.0.0git (https://github.com/llvm/llvm-project.git 3de5dbb) Target: arm64-apple-darwin24.1.0 [snip] #include "..." search starts here: #include <...> search starts here: /Users/carlocab/github/llvm-project/build-clang-config/lib/clang/20/include /Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.sdk/usr/include /Applications/Xcode-14.3.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.sdk/System/Library/Frameworks (framework directory) End of search list. "/usr/bin/ld" -demangle -lto_library /Users/carlocab/github/llvm-project/build-clang-config/lib/libLTO.dylib -no_deduplicate -dynamic -arch arm64 -platform_version macos 13.3.0 13.3 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.sdk -mllvm -enable-linkonceodr-outlining -o /dev/null /var/folders/nj/9vfk4f0n377605jhxxmngd8h0000gn/T/--b914c6.o -lSystem We can fix this by reversing the order in which the `-syslibroot` flag is determined. Downstream bug report: Homebrew/homebrew-core#197277 Co-authored-by: Bo Anderson <mail@boanderson.me>
brew gist-logs <formula>
link ORbrew config
ANDbrew doctor
outputNote that the system is a clean virtual machine with a newly installed homebrew. The problem has also been reproduced here.
Verification
brew doctor
output saysYour system is ready to brew.
and am still able to reproduce my issue.brew update
and am still able to reproduce my issue.brew doctor
and that did not fix my problem.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 thatllvm
was built with is always selected when linking instead of the value set byxcrun
/ inSDKROOT
/ 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:
What happened (include all command output)?
Linking fails with:
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)Install
llvm
package (any version):brew install llvm@19
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.
Put the example program above in
foo.m
.Try to compile with the macOS 14.0 SDK (this fails as expected, because the function isn't available in the old SDK):
Compile with Xcode Clang and macOS 15.1 SDK (this works):
Compile with Clang provided by
llvm
package and macOS 15.1 SDK (this fails linking):Use
-v
to see that Clang always passes the same value told
's-syslibroot
.The text was updated successfully, but these errors were encountered: