Skip to content

[clang] Match -isysroot behaviour with system compiler on Darwin #80524

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2515,20 +2515,31 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
switch (GetCXXStdlibType(DriverArgs)) {
case ToolChain::CST_Libcxx: {
// On Darwin, libc++ can be installed in one of the following places:
// 1. Alongside the compiler in <install>/include/c++/v1
// 2. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
// 3. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
// 1. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
// 2. Alongside the compiler in <install>/include/c++/v1
// 3. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
//
// The precedence of paths is as listed above, i.e. we take the first path
// that exists. Note that we never include libc++ twice -- we take the first
// path that exists and don't send the other paths to CC1 (otherwise
// include_next could break).
//
// Also note that in most cases, (1) and (2) are exactly the same path.
// Also note that in most cases, (2) and (3) are exactly the same path.
// Those two paths will differ only when the `clang` program being run
// is actually a symlink to the real executable.

// Check for (1)
llvm::SmallString<128> SysrootUsr = Sysroot;
llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
if (getVFS().exists(SysrootUsr)) {
addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
return;
} else if (DriverArgs.hasArg(options::OPT_v)) {
llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
<< "\"\n";
}

// Check for (2)
// Get from '<install>/bin' to '<install>/include/c++/v1'.
// Note that InstallBin can be relative, so we use '..' instead of
// parent_path.
Expand All @@ -2543,7 +2554,7 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
<< "\"\n";
}

// (2) Check for the folder where the executable is located, if different.
// (3) Check for the folder where the executable is located, if different.
if (getDriver().getInstalledDir() != getDriver().Dir) {
InstallBin = llvm::StringRef(getDriver().Dir);
llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
Expand All @@ -2556,17 +2567,6 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
}
}

// Otherwise, check for (3)
llvm::SmallString<128> SysrootUsr = Sysroot;
llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");
if (getVFS().exists(SysrootUsr)) {
addSystemInclude(DriverArgs, CC1Args, SysrootUsr);
return;
} else if (DriverArgs.hasArg(options::OPT_v)) {
llvm::errs() << "ignoring nonexistent directory \"" << SysrootUsr
<< "\"\n";
}

// Otherwise, don't add any path.
break;
}
Expand Down
41 changes: 21 additions & 20 deletions clang/test/Driver/darwin-header-search-libcxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-1 %s
// CHECK-LIBCXX-TOOLCHAIN-1: "-cc1"
// CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
// CHECK-LIBCXX-TOOLCHAIN-1-NOT: "-internal-isystem" "/usr/include/c++/v1"
// CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
//
// RUN: %clang -### %s -fsyntax-only 2>&1 \
// RUN: --target=x86_64-apple-darwin \
Expand All @@ -35,8 +35,8 @@
// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-2 %s
// CHECK-LIBCXX-TOOLCHAIN-2: "-cc1"
// CHECK-LIBCXX-TOOLCHAIN-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
// CHECK-LIBCXX-TOOLCHAIN-2-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
// CHECK-LIBCXX-TOOLCHAIN-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"

// Check with only headers in the sysroot (those should be used).
//
Expand All @@ -49,11 +49,11 @@
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT-1 %s
// CHECK-LIBCXX-SYSROOT-1: "-cc1"
// CHECK-LIBCXX-SYSROOT-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
// CHECK-LIBCXX-SYSROOT-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
// CHECK-LIBCXX-SYSROOT-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"

// Check with both headers in the sysroot and headers alongside the installation
// (the headers in the toolchain should be preferred over the <sysroot> headers).
// (the headers in the <sysroot> headers should be preferred over the toolchain).
// Ensure that both -isysroot and --sysroot work, and that isysroot has precedence
// over --sysroot.
//
Expand Down Expand Up @@ -89,8 +89,8 @@
// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s
//
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-cc1"
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"

// Make sure that using -nostdinc, -nostdinc++ or -nostdlib will drop both the toolchain
// C++ include path and the sysroot one.
Expand Down Expand Up @@ -157,8 +157,8 @@
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
// RUN: --check-prefix=CHECK-LIBCXX-MISSING-BOTH %s
// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[SYSROOT]]/usr/include/c++/v1"
// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"

// Make sure that on Darwin, we use libc++ header search paths by default even when
// -stdlib= isn't passed.
Expand All @@ -175,9 +175,9 @@

// ----------------------------------------------------------------------------
// On Darwin, libc++ can be installed in one of the following places:
// 1. Alongside the compiler in <install>/include/c++/v1
// 2. Alongside the compiler in <clang-executable-folder>/../include/c++/v1
// 3. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
// 1. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1
// 2. Alongside the compiler in <install>/include/c++/v1
// 3. Alongside the compiler in <clang-executable-folder>/../include/c++/v1

// The build folders do not have an `include/c++/v1`; create a new
// local folder hierarchy that meets this requirement.
Expand All @@ -187,7 +187,7 @@
// RUN: cp %clang %t/install/bin/clang
// RUN: mkdir -p %t/install/include/c++/v1

// Headers in (1) and in (2) -> (1) is preferred over (2)
// Headers in (2) and in (3) -> (2) is preferred over (3)
// RUN: rm -rf %t/symlinked1
// RUN: mkdir -p %t/symlinked1/bin
// RUN: ln -sf %t/install/bin/clang %t/symlinked1/bin/clang
Expand All @@ -196,16 +196,16 @@
// RUN: %t/symlinked1/bin/clang -### %s -fsyntax-only 2>&1 \
// RUN: --target=x86_64-apple-darwin \
// RUN: -stdlib=libc++ \
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \
// RUN: | FileCheck -DSYMLINKED=%t/symlinked1 \
// RUN: -DTOOLCHAIN=%t/install \
// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
// RUN: --check-prefix=CHECK-SYMLINKED-INCLUDE-CXX-V1 %s
// CHECK-SYMLINKED-INCLUDE-CXX-V1: "-internal-isystem" "[[SYMLINKED]]/bin/../include/c++/v1"
// CHECK-SYMLINKED-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
// CHECK-SYMLINKED-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
// CHECK-SYMLINKED-INCLUDE-CXX-V1: "-internal-isystem" "[[SYMLINKED]]/bin/../include/c++/v1"

// Headers in (2) and in (3) -> (2) is preferred over (3)
// Headers in (1) and in (3) -> (1) is preferred over (3)
// RUN: rm -rf %t/symlinked2
// RUN: mkdir -p %t/symlinked2/bin
// RUN: ln -sf %t/install/bin/clang %t/symlinked2/bin/clang
Expand All @@ -216,16 +216,17 @@
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
// RUN: | FileCheck -DTOOLCHAIN=%t/install \
// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
// RUN: --check-prefix=CHECK-TOOLCHAIN-INCLUDE-CXX-V1 %s
// CHECK-TOOLCHAIN-INCLUDE-CXX-V1: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
// CHECK-TOOLCHAIN-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
// RUN: --check-prefix=CHECK-SYSROOT-INCLUDE-CXX-V1 %s
// CHECK-SYSROOT-INCLUDE-CXX-V1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
// CHECK-SYSROOT-INCLUDE-CXX-V1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"

// Headers in (2) and nowhere else -> (2) is used
// Headers in (3) and nowhere else -> (3) is used
// RUN: %t/symlinked2/bin/clang -### %s -fsyntax-only 2>&1 \
// RUN: --target=x86_64-apple-darwin \
// RUN: -stdlib=libc++ \
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \
// RUN: | FileCheck -DTOOLCHAIN=%t/install \
// RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \
// RUN: --check-prefix=CHECK-TOOLCHAIN-NO-SYSROOT %s
// CHECK-TOOLCHAIN-NO-SYSROOT-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
// CHECK-TOOLCHAIN-NO-SYSROOT: "-internal-isystem" "[[TOOLCHAIN]]/bin/../include/c++/v1"
3 changes: 2 additions & 1 deletion clang/test/Tooling/clang-check-mac-libcxx-abspath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
//
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: mkdir %t/fake-sysroot
//
// Install the mock libc++ (simulates the libc++ directory structure).
// RUN: cp -r %S/Inputs/mock-libcxx %t/
//
// Pretend clang is installed beside the mock library that we provided.
// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -isysroot %t/fake-sysroot -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
// RUN: cp "%s" "%t/test.cpp"
// clang-check will produce an error code if the mock library is not found.
// RUN: clang-check -p "%t" "%t/test.cpp"
Expand Down
3 changes: 2 additions & 1 deletion clang/test/Tooling/clang-check-mac-libcxx-relpath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
//
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: mkdir -p %t/fake-sysroot
//
// Install the mock libc++ (simulates the libc++ directory structure).
// RUN: cp -r %S/Inputs/mock-libcxx %t/
//
// Pretend clang is installed beside the mock library that we provided.
// RUN: echo '[{"directory":"%t","command":"mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
// RUN: echo '[{"directory":"%t","command":"mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -isysroot %t/fake-sysroot -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
// RUN: cp "%s" "%t/test.cpp"
// clang-check will produce an error code if the mock library is not found.
// RUN: clang-check -p "%t" "%t/test.cpp"
Expand Down