[clang] [Darwin][Driver][clang] Prioritise `-isysroot` over `--sysroot` consistently (PR #115993)

Carlo Cabrera via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 12 21:18:38 PST 2024


https://github.com/carlocab created https://github.com/llvm/llvm-project/pull/115993

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 3de5dbb1110887d5127e815f3ca247a9d839ee85)
    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: https://github.com/Homebrew/homebrew-core/issues/197277

Co-authored-by: Bo Anderson <mail at boanderson.me>


>From d35918e23eaf15f4068e32f8c9b971bd556eb37a Mon Sep 17 00:00:00 2001
From: Carlo Cabrera <github at carlo.cab>
Date: Wed, 13 Nov 2024 13:09:59 +0800
Subject: [PATCH] [Darwin][Driver][clang] Prioritise `-isysroot` over
 `--sysroot` consistently
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 3de5dbb1110887d5127e815f3ca247a9d839ee85)
    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: https://github.com/Homebrew/homebrew-core/issues/197277

Co-authored-by: Bo Anderson <mail at boanderson.me>
---
 clang/lib/Driver/ToolChains/Darwin.cpp | 13 ++++++-------
 clang/test/Driver/sysroot.c            |  4 ++--
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 87380869f6fdab..8bb239d8d3f9df 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -428,15 +428,14 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
   Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
   Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
 
-  // Give --sysroot= preference, over the Apple specific behavior to also use
-  // --isysroot as the syslibroot.
-  StringRef sysroot = C.getSysRoot();
-  if (sysroot != "") {
-    CmdArgs.push_back("-syslibroot");
-    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
-  } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+  // Prioritise -isysroot to ensure that the libraries we link to are taken
+  // from the same SDK that our headers come from.
+  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
     CmdArgs.push_back("-syslibroot");
     CmdArgs.push_back(A->getValue());
+  } else if (StringRef sysroot = C.getSysRoot(); sysroot != "") {
+    CmdArgs.push_back("-syslibroot");
+    CmdArgs.push_back(C.getArgs().MakeArgString(sysroot));
   }
 
   Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace);
diff --git a/clang/test/Driver/sysroot.c b/clang/test/Driver/sysroot.c
index 85da2499090af1..1e85760409a486 100644
--- a/clang/test/Driver/sysroot.c
+++ b/clang/test/Driver/sysroot.c
@@ -11,9 +11,9 @@
 // RUN: FileCheck --check-prefix=CHECK-APPLE-ISYSROOT < %t2 %s
 // CHECK-APPLE-ISYSROOT: "-arch" "i386"{{.*}} "-syslibroot" "{{[^"]*}}/FOO"
 
-// Check that honor --sysroot= over -isysroot, for Apple Darwin.
+// Check that honor -isysroot over --sysroot=, for Apple Darwin.
 // RUN: touch %t3.o
 // RUN: %clang -target i386-apple-darwin10 \
 // RUN:   -isysroot /FOO --sysroot=/BAR -### %t3.o 2> %t3
 // RUN: FileCheck --check-prefix=CHECK-APPLE-SYSROOT < %t3 %s
-// CHECK-APPLE-SYSROOT: "-arch" "i386"{{.*}} "-syslibroot" "{{[^"]*}}/BAR"
+// CHECK-APPLE-SYSROOT: "-arch" "i386"{{.*}} "-syslibroot" "{{[^"]*}}/FOO"



More information about the cfe-commits mailing list