Skip to content

[clang][driver] Add \<executable\>/../include/c++/v1 to include path on Darwin #70817

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

Merged
merged 18 commits into from
Nov 20, 2023
Merged

[clang][driver] Add \<executable\>/../include/c++/v1 to include path on Darwin #70817

merged 18 commits into from
Nov 20, 2023

Conversation

ilg-ul
Copy link
Contributor

@ilg-ul ilg-ul commented Oct 31, 2023

On macOS, when clang is invoked via a symlink, since the InstalledDir is where the link is located, the C++ headers are not identified and the default system headers are used.

% ln -s /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/bin/clang++ ~/tmp/clang++
%  ~/tmp/clang++ -v hello.cpp -stdlib=libc++
xPack x86_64 clang version 15.0.7 (https://github.com/xpack-dev-tools/clang-xpack 9b1ff65945b1aaddfe7c0c4d99001ebca5d67b03)
Target: x86_64-apple-darwin21.6.0
Thread model: posix

InstalledDir: /Users/ilg/tmp/. <--- !!!
ignoring nonexistent directory "/Users/ilg/tmp/./../include/c++/v1" <--- !!!

 "/Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/bin/clang-15" -cc1 -triple x86_64-apple-macosx12.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=all -ffp-contract=on -fno-rounding-math -funwind-tables=2 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=lldb -target-linker-version 409.12 -v -fcoverage-compilation-dir=/Users/ilg/tmp -resource-dir /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -stdlib=libc++ -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -fdeprecated-macro -fdebug-compilation-dir=/Users/ilg/tmp -ferror-limit 19 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcolor-diagnostics -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/gr/13tt3vcd7m1gnbhwtkmf5cnw0000gn/T/hello-a87934.o -x c++ hello.cpp
clang -cc1 version 15.0.7 based upon LLVM 15.0.7 default target x86_64-apple-darwin21.6.0
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:

 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 <--- Wrong!

 /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
 "/usr/bin/ld" -demangle -lto_library /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -macosx_version_min 12.0.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -o a.out /var/folders/gr/13tt3vcd7m1gnbhwtkmf5cnw0000gn/T/hello-a87934.o -lc++ -lSystem /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7/lib/darwin/libclang_rt.osx.a

Using the system headers instead of the toolchain headers may have very subtle consequences, sometimes leading to compile errors which are hard to diagnose.

This fix adds a second check using the folder where the executable is located.

On macOS, when clang is invoked via a symlink, since the InstalledDir is
where the link is located, the C++ headers are not identified and the
default system headers are used.

This fix adds a second check using the folder where the executable is
located.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Oct 31, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 31, 2023

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Liviu Ionescu (ilg-ul)

Changes

On macOS, when clang is invoked via a symlink, since the InstalledDir is where the link is located, the C++ headers are not identified and the default system headers are used.

% ln -s /Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/bin/clang++ ~/tmp/clang++
%  ~/tmp/clang++ -v hello.cpp -stdlib=libc++
xPack x86_64 clang version 15.0.7 (https://github.com/xpack-dev-tools/clang-xpack 9b1ff65945b1aaddfe7c0c4d99001ebca5d67b03)
Target: x86_64-apple-darwin21.6.0
Thread model: posix

InstalledDir: /Users/ilg/tmp/. &lt;--- !!!
ignoring nonexistent directory "/Users/ilg/tmp/./../include/c++/v1" &lt;--- !!!

 "/Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/bin/clang-15" -cc1 -triple x86_64-apple-macosx12.0.0 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all --mrelax-relocations -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello.cpp -mrelocation-model pic -pic-level 2 -mframe-pointer=all -ffp-contract=on -fno-rounding-math -funwind-tables=2 -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -target-cpu penryn -tune-cpu generic -mllvm -treat-scalable-fixed-error-as-warning -debugger-tuning=lldb -target-linker-version 409.12 -v -fcoverage-compilation-dir=/Users/ilg/tmp -resource-dir /Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -stdlib=libc++ -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -fdeprecated-macro -fdebug-compilation-dir=/Users/ilg/tmp -ferror-limit 19 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fmax-type-align=16 -fcolor-diagnostics -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/folders/gr/13tt3vcd7m1gnbhwtkmf5cnw0000gn/T/hello-a87934.o -x c++ hello.cpp
clang -cc1 version 15.0.7 based upon LLVM 15.0.7 default target x86_64-apple-darwin21.6.0
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include &lt;...&gt; search starts here:

 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 &lt;--- Wrong!

 /Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
 "/usr/bin/ld" -demangle -lto_library /Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -macosx_version_min 12.0.0 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -o a.out /var/folders/gr/13tt3vcd7m1gnbhwtkmf5cnw0000gn/T/hello-a87934.o -lc++ -lSystem /Users/ilg/Library/xPacks/@<!-- -->xpack-dev-tools/clang/15.0.7-3.1/.content/lib/clang/15.0.7/lib/darwin/libclang_rt.osx.a

Using the system headers instead of the toolchain headers may have very subtle consequences, sometimes leading to compile errors which are hard to diagnose.

This fix adds a second check using the folder where the executable is located.


Full diff: https://github.com/llvm/llvm-project/pull/70817.diff

1 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/Darwin.cpp (+13)
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index f28e08d81bf29b4..de55307385966cf 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -2494,6 +2494,19 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs(
                    << "\"\n";
     }
 
+    // Check for the folder where the executable is located, if different.
+    if (getDriver().getInstalledDir() != getDriver().Dir) {
+      InstallBin = llvm::StringRef(getDriver().Dir.c_str());
+      llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1");
+      if (getVFS().exists(InstallBin)) {
+        addSystemInclude(DriverArgs, CC1Args, InstallBin);
+        return;
+      } else if (DriverArgs.hasArg(options::OPT_v)) {
+        llvm::errs() << "ignoring nonexistent directory \"" << InstallBin
+                     << "\"\n";
+      }
+    }
+
     // Otherwise, check for (2)
     llvm::SmallString<128> SysrootUsr = Sysroot;
     llvm::sys::path::append(SysrootUsr, "usr", "include", "c++", "v1");

@egorzhdan egorzhdan requested review from hyp and ahatanak October 31, 2023 15:26
@ilg-ul
Copy link
Contributor Author

ilg-ul commented Oct 31, 2023

@Endilll, @AaronBallman, @bjope, @mstorsjo, this is a cleanup of a previous PR (#68091) where you contributed.

Could you take a second look?

@MaskRay
Copy link
Member

MaskRay commented Oct 31, 2023

I am unfamiliar with Darwin and @jansvoboda11 @ldionne can give a more authoritative answer, but I can share some feelings.

  • Gnu.cpp uses Generic_GCC::addLibCxxIncludePaths so other versions (e.g. usr/include/c++/v2) are supported.
  • Only one of Dir/InstalledDir should be used. If they are overridden by -ccc-install-dir dir, path(clang)/../include/c++ should be ignored. Gnu.cpp uses Dir to derive the libc++ include directory.
  • With the default-canonical-prefixes, a symlinked clang should use the directory relative to the clang executable, i.e. d/clang -stdlib=libc++ -c a.cc works.

IMHO this patch does not move toward the ideal situation as Dir and InstallDir are duplicates.
Ideally only Dir should be used, but I don't know whether we may run into other complexity.

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Oct 31, 2023

Only one of Dir/InstalledDir should be used

The current behaviour is:

  • if InstalledDir/../include/c++/v1 exists, it is used
  • otherwise the MacOSX.sdk/usr/include/c++/v1 is used.

In most cases, when invoked via a link, there is no include in that folder (see the example above), and the sdk folder is wrongly used.

The proposed behaviour is:

  • if InstalledDir/../include/c++/v1 exists, it is used
  • if Dir/../include/c++/v1 exists, it is used
  • otherwise the MacOSX.sdk/usr/include/c++/v1 is used.

Only one of them is used.

@ldionne
Copy link
Member

ldionne commented Nov 1, 2023

Is there any reason why we don't just use Dir all the time? What's the difference between those two? I think I wrote this code a few years ago and I can guarantee you that I simply didn't know there was a difference between Dir and InstalledDir (since I still don't know the difference).

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 1, 2023

Is there any reason why we don't just use Dir all the time?

That's a good question.

There was a long discussion in #68091, and my understanding is that, for compatibility reasons, the current behaviour must be preserved.

What's the difference between those two?

Dir is the location where the actual executables are installed.
InstalledDir, when the compiler is invoked via a link, is the location where the link comes from.

In my use case, and probably in most use cases, the location where the link comes from is a plain folder, not a hierarchy specific to a toolchain.

However, for testing purposes, including several clang tests, such a hierarchy is created, with other headers, and a link is placed there, with the expectation that the compiler will use that environment and not the one where the toolchain is actually installed.

There are many places in the source code where something is searched for first in the InstalledDir, and, if not found, it is also searched in Dir.

This patch uses exactly the same strategy for identifying the C++ headers on Darwin. Without the patch, when using links the compiler chooses the SDK headers, which is plainly wrong and damaging.

@jroelofs
Copy link
Contributor

jroelofs commented Nov 1, 2023

In my use case, and probably in most use cases, the location where the link comes from is a plain folder, not a hierarchy specific to a toolchain.

I would have expected the opposite. Most non-windows clang toolchains that I know of typically ship clang and clang++ as symlinks to a single binary named clang-${version}, all of which are located in the typical bin-next-to-lib toolchain folder structure. Darwin toolchains are a little weird, since we don't ship libc++ & co. in bin/../{lib,include}, and instead those go in an "SDK" (much like a "sysroot" on other platforms).

As an aside, there is also driver mode selection logic that depends heavily on the specific names of these symlinks, e.g. for C vs C++ mode, clang-cl mode, and/or cross-compiling to a specific target when prefixed with the target triple e.g. arm-none-eabi-clang -> clang.

Don't consider this an objection, but: for your use case, can you stick symlinks in to preserve that toolchain folder structure relative to the ~/tmp/clang++ symlink? i.e. make that ~/tmp/bin/clang++ -> /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/bin/clang-15 and add ~/tmp/lib -> /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib (and same for include).

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 2, 2023

for your use case, can you stick symlinks in to preserve that toolchain folder structure relative to the ~/tmp/clang++ symlink? i.e. make that ~/tmp/bin/clang++ -> /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/bin/clang-15 and add ~/tmp/lib -> /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/15.0.7-3.1/.content/lib (and same for include).

I'm not sure I understand your proposal, but I'm afraid changing the structure of the symlinks is not possible, it is done automatically by a tool.

The example above was just to demonstrate the bug.

In the actual use case, which is inspired by the npm use case, in the project there is a folder xpacks with symlinks to all dependent binaries, with dual indirections, something like this:

ilg@wksi native-cmake-clang13-debug % ls -lAR xpacks
total 0
drwxr-xr-x  61 ilg  staff  1952 Oct 31 14:42 .bin
drwxr-xr-x   3 ilg  staff    96 Oct 31 14:42 @micro-os-plus
drwxr-xr-x   3 ilg  staff    96 Oct 31 14:42 @xpack-dev-tools

xpacks/.bin:
total 0
lrwxr-xr-x  1 ilg  staff  44 Oct 31 14:42 clang -> ../@xpack-dev-tools/clang/.content/bin/clang
lrwxr-xr-x  1 ilg  staff  46 Oct 31 14:42 clang++ -> ../@xpack-dev-tools/clang/.content/bin/clang++
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 clang-check -> ../@xpack-dev-tools/clang/.content/bin/clang-check
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 clang-cl -> ../@xpack-dev-tools/clang/.content/bin/clang-cl
lrwxr-xr-x  1 ilg  staff  48 Oct 31 14:42 clang-cpp -> ../@xpack-dev-tools/clang/.content/bin/clang-cpp
lrwxr-xr-x  1 ilg  staff  48 Oct 31 14:42 clang-doc -> ../@xpack-dev-tools/clang/.content/bin/clang-doc
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 clang-format -> ../@xpack-dev-tools/clang/.content/bin/clang-format
lrwxr-xr-x  1 ilg  staff  60 Oct 31 14:42 clang-offload-bundler -> ../@xpack-dev-tools/clang/.content/bin/clang-offload-bundler
lrwxr-xr-x  1 ilg  staff  60 Oct 31 14:42 clang-offload-wrapper -> ../@xpack-dev-tools/clang/.content/bin/clang-offload-wrapper
lrwxr-xr-x  1 ilg  staff  53 Oct 31 14:42 clang-refactor -> ../@xpack-dev-tools/clang/.content/bin/clang-refactor
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 clang-rename -> ../@xpack-dev-tools/clang/.content/bin/clang-rename
lrwxr-xr-x  1 ilg  staff  54 Oct 31 14:42 clang-scan-deps -> ../@xpack-dev-tools/clang/.content/bin/clang-scan-deps
lrwxr-xr-x  1 ilg  staff  49 Oct 31 14:42 clang-tidy -> ../@xpack-dev-tools/clang/.content/bin/clang-tidy
lrwxr-xr-x  1 ilg  staff  45 Oct 31 14:42 clangd -> ../@xpack-dev-tools/clang/.content/bin/clangd
lrwxr-xr-x  1 ilg  staff  61 Oct 31 14:42 clangd-xpc-test-client -> ../@xpack-dev-tools/clang/.content/bin/clangd-xpc-test-client
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 darwin-debug -> ../@xpack-dev-tools/clang/.content/bin/darwin-debug
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 diagtool -> ../@xpack-dev-tools/clang/.content/bin/diagtool
lrwxr-xr-x  1 ilg  staff  55 Oct 31 14:42 git-clang-format -> ../@xpack-dev-tools/clang/.content/bin/git-clang-format
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 hmaptool -> ../@xpack-dev-tools/clang/.content/bin/hmaptool
lrwxr-xr-x  1 ilg  staff  45 Oct 31 14:42 ld.lld -> ../@xpack-dev-tools/clang/.content/bin/ld.lld
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 ld64.lld -> ../@xpack-dev-tools/clang/.content/bin/ld64.lld
lrwxr-xr-x  1 ilg  staff  57 Oct 31 14:42 ld64.lld.darwinnew -> ../@xpack-dev-tools/clang/.content/bin/ld64.lld.darwinnew
lrwxr-xr-x  1 ilg  staff  42 Oct 31 14:42 lld -> ../@xpack-dev-tools/clang/.content/bin/lld
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 lld-link -> ../@xpack-dev-tools/clang/.content/bin/lld-link
lrwxr-xr-x  1 ilg  staff  43 Oct 31 14:42 lldb -> ../@xpack-dev-tools/clang/.content/bin/lldb
lrwxr-xr-x  1 ilg  staff  53 Oct 31 14:42 lldb-argdumper -> ../@xpack-dev-tools/clang/.content/bin/lldb-argdumper
lrwxr-xr-x  1 ilg  staff  49 Oct 31 14:42 lldb-instr -> ../@xpack-dev-tools/clang/.content/bin/lldb-instr
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 lldb-server -> ../@xpack-dev-tools/clang/.content/bin/lldb-server
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 lldb-vscode -> ../@xpack-dev-tools/clang/.content/bin/lldb-vscode
lrwxr-xr-x  1 ilg  staff  53 Oct 31 14:42 llvm-addr2line -> ../@xpack-dev-tools/clang/.content/bin/llvm-addr2line
lrwxr-xr-x  1 ilg  staff  46 Oct 31 14:42 llvm-ar -> ../@xpack-dev-tools/clang/.content/bin/llvm-ar
lrwxr-xr-x  1 ilg  staff  46 Oct 31 14:42 llvm-as -> ../@xpack-dev-tools/clang/.content/bin/llvm-as
lrwxr-xr-x  1 ilg  staff  57 Oct 31 14:42 llvm-bitcode-strip -> ../@xpack-dev-tools/clang/.content/bin/llvm-bitcode-strip
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 llvm-config -> ../@xpack-dev-tools/clang/.content/bin/llvm-config
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 llvm-cov -> ../@xpack-dev-tools/clang/.content/bin/llvm-cov
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-cxxdump -> ../@xpack-dev-tools/clang/.content/bin/llvm-cxxdump
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-cxxfilt -> ../@xpack-dev-tools/clang/.content/bin/llvm-cxxfilt
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 llvm-cxxmap -> ../@xpack-dev-tools/clang/.content/bin/llvm-cxxmap
lrwxr-xr-x  1 ilg  staff  48 Oct 31 14:42 llvm-diff -> ../@xpack-dev-tools/clang/.content/bin/llvm-diff
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 llvm-dis -> ../@xpack-dev-tools/clang/.content/bin/llvm-dis
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-dlltool -> ../@xpack-dev-tools/clang/.content/bin/llvm-dlltool
lrwxr-xr-x  1 ilg  staff  47 Oct 31 14:42 llvm-lib -> ../@xpack-dev-tools/clang/.content/bin/llvm-lib
lrwxr-xr-x  1 ilg  staff  58 Oct 31 14:42 llvm-libtool-darwin -> ../@xpack-dev-tools/clang/.content/bin/llvm-libtool-darwin
lrwxr-xr-x  1 ilg  staff  46 Oct 31 14:42 llvm-nm -> ../@xpack-dev-tools/clang/.content/bin/llvm-nm
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-objcopy -> ../@xpack-dev-tools/clang/.content/bin/llvm-objcopy
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-objdump -> ../@xpack-dev-tools/clang/.content/bin/llvm-objdump
lrwxr-xr-x  1 ilg  staff  52 Oct 31 14:42 llvm-profdata -> ../@xpack-dev-tools/clang/.content/bin/llvm-profdata
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 llvm-ranlib -> ../@xpack-dev-tools/clang/.content/bin/llvm-ranlib
lrwxr-xr-x  1 ilg  staff  46 Oct 31 14:42 llvm-rc -> ../@xpack-dev-tools/clang/.content/bin/llvm-rc
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-readelf -> ../@xpack-dev-tools/clang/.content/bin/llvm-readelf
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-readobj -> ../@xpack-dev-tools/clang/.content/bin/llvm-readobj
lrwxr-xr-x  1 ilg  staff  48 Oct 31 14:42 llvm-size -> ../@xpack-dev-tools/clang/.content/bin/llvm-size
lrwxr-xr-x  1 ilg  staff  51 Oct 31 14:42 llvm-strings -> ../@xpack-dev-tools/clang/.content/bin/llvm-strings
lrwxr-xr-x  1 ilg  staff  49 Oct 31 14:42 llvm-strip -> ../@xpack-dev-tools/clang/.content/bin/llvm-strip
lrwxr-xr-x  1 ilg  staff  54 Oct 31 14:42 llvm-symbolizer -> ../@xpack-dev-tools/clang/.content/bin/llvm-symbolizer
lrwxr-xr-x  1 ilg  staff  50 Oct 31 14:42 llvm-tblgen -> ../@xpack-dev-tools/clang/.content/bin/llvm-tblgen
lrwxr-xr-x  1 ilg  staff  57 Oct 31 14:42 set-xcode-analyzer -> ../@xpack-dev-tools/clang/.content/bin/set-xcode-analyzer
lrwxr-xr-x  1 ilg  staff  49 Oct 31 14:42 split-file -> ../@xpack-dev-tools/clang/.content/bin/split-file
lrwxr-xr-x  1 ilg  staff  46 Oct 31 14:42 wasm-ld -> ../@xpack-dev-tools/clang/.content/bin/wasm-ld

xpacks/@micro-os-plus:
total 0
lrwxr-xr-x  1 ilg  staff  75 Oct 31 14:42 architecture-synthetic-posix -> /Users/ilg/Library/xPacks/@micro-os-plus/architecture-synthetic-posix/4.0.2

xpacks/@xpack-dev-tools:
total 0
lrwxr-xr-x  1 ilg  staff  59 Oct 31 14:42 clang -> /Users/ilg/Library/xPacks/@xpack-dev-tools/clang/13.0.1-1.1
ilg@wksi native-cmake-clang13-debug % 

This project in particular has binary dependencies only to clang, but other projects can also have dependencies to cmake, ninja, etc, and all binaries are linked in the .bin folder.

With the proposed change, clang correctly idenifies the proper include/c++/v1 folder from the final destination where the toolchain is installed.

@jroelofs
Copy link
Contributor

jroelofs commented Nov 2, 2023

changing the structure of the symlinks is not possible, it is done automatically by a tool.

To be fair: tools can be changed, and in fact you're proposing to change one ;)

But that said, now I see what you're up against.

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 2, 2023

Can you clearly state why you are against this PR? You don't consider the current behaviour of silently using the wrong headers a bug, or the proposed solution is not correct?

@jroelofs
Copy link
Contributor

jroelofs commented Nov 2, 2023

Can you clearly state why you are against this PR? You don't consider the current behaviour of silently using the wrong headers a bug, or the proposed solution is not correct?

Don't consider this an objection

I am not against it; I just wanted to talk through all the options.

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 2, 2023

Then can this bug fix be accepted? Are there any other solutions?

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 8, 2023

Can someone review this patch?

Exactly the same strategy (check if the desired subfolder is below InstalledDir, and, if not, check again below Dir) is used in many places which require to locate various folders, so this patch is consistent with the rest of the code.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

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

I think this is generally reasonable but I'm requesting a few changes.

Copy link

github-actions bot commented Nov 10, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 13, 2023

After several more attempts I identified the reason for the failure: the folder structure in the build location does not include the bin/../include/c++/v1 folder required for this to work:

clang version 18.0.0 (https://github.com/llvm-premerge-tests/llvm-project.git 6bfa3255358eeb2b109525059920e5f2b2abe41b)
Target: x86_64-apple-darwin
Thread model: posix
InstalledDir: /var/lib/buildkite-agent/builds/linux-56-59b8f5d88-tdgkv-1/llvm-project/clang-ci/build/build-clang/tools/clang/test/Driver/Output/darwin-header-search-libcxx.cpp.tmp/xpacks/.bin
ignoring nonexistent directory "/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-tdgkv-1/llvm-project/clang-ci/build/build-clang/tools/clang/test/Driver/Output/darwin-header-search-libcxx.cpp.tmp/xpacks/.bin/../include/c++/v1"
ignoring nonexistent directory "/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-tdgkv-1/llvm-project/clang-ci/build/build-clang/bin/../include/c++/v1"

After creating this include folder, the Linux test finally passed.

I don't know if creating this folder is acceptable for the testing infrastructure, but if we want this test together with the bug fix, we probably have no other choice.

Louis @ldionne, could you review the test code?

@ilg-ul ilg-ul requested a review from ldionne November 13, 2023 16:37
@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 13, 2023

I pushed a new test that copies clang to a local install folder, to avoid creating folders in the build location.

The Linux build passed.

Any other comments?

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 15, 2023

@ldionne, do you agree with the current changes? Since your pending request for changes currently blocks this PR.

@@ -172,3 +172,32 @@
// RUN: --check-prefix=CHECK-LIBCXX-STDLIB-UNSPECIFIED %s
// CHECK-LIBCXX-STDLIB-UNSPECIFIED: "-cc1"
// CHECK-LIBCXX-STDLIB-UNSPECIFIED: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"

// ----------------------------------------------------------------------------
Copy link
Member

Choose a reason for hiding this comment

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

Can you try to integrate your test to the existing ones a bit more closely? They are not really specific to xpm/npm, so it makes sense to support them in a platform agnostic way.

For example, we need to add a test where we set up a symlinked Clang and then run with a toolchain that has headers in it, and confirm that this takes precedence over the ones in the symlink directory. In other words, we now have (1), (2) and (3) places where we look for headers in. Previously, we pretty exhaustively checked the combinations for the two locations we checked -- now we should at least try to check:

  • Headers in (1) and in (2) -> (1) is preferred over (2)
  • Headers in (2) and in (3) -> (2) is preferred over (3) -- you already check that with your current test
  • Headers in (2) and nowhere else -> (2) is used

Also, we should make the comments in the tests platform-agnostic. We also probably want to insert the tests in the right place in the file and I suspect that using (1) (2) and (3) terminology to explain what we're testing would help.

Copy link
Member

Choose a reason for hiding this comment

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

BTW this looks good to me apart from these test improvements.

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

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

LGTM assuming CI passes. Thanks!

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 16, 2023

assuming CI passes

It passed on my Mac, let's hope that the CI will pass too.

But, not related to this PR, on my Mac, I always had several tests failing:

Failed Tests (7):
  Clang :: Driver/baremetal.cpp
  Clang :: Driver/csky-toolchain.c
  Clang :: Driver/freebsd-include-paths.c
  Clang :: Driver/hexagon-toolchain-linux.c
  Clang :: Driver/sysroot.c
  Clang :: Frontend/warning-poison-system-directories.c
  Clang :: Index/pch-from-libclang.c


Testing Time: 844.78s
  Skipped          :    36
  Unsupported      :  3071
  Passed           : 30977
  Expectedly Failed:    24
  Failed           :     7
FAILED: tools/clang/test/CMakeFiles/check-clang /Users/ilg/Work/xpack-dev-tools-build/clang-17.0.5-1/darwin-x64/x86_64-apple-darwin23.1.0/build/llvm-17.0.5/tools/clang/test/CMakeFiles/check-clang 

Is this expected?

@ldionne
Copy link
Member

ldionne commented Nov 16, 2023

That's a question for the Clang regulars -- I generally don't run those tests since I primarily work on libc++, not Clang.

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 17, 2023

The CI passed. Do we need a second review, or the PR can be merged?

@ldionne ldionne merged commit a32a2b2 into llvm:main Nov 20, 2023
@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 20, 2023

Thank you, Louis @ldionne, I highly appreciate your help!

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 20, 2023

The ppc64 build failed with:

RUN: at line 186: mkdir -pv /home/powerllvm/powerllvm_env/aix-ppc64/clang-ppc64-aix/build/tools/clang/test/Driver/Output/darwin-header-search-libcxx.cpp.tmp/install/bin
+ mkdir -pv /home/powerllvm/powerllvm_env/aix-ppc64/clang-ppc64-aix/build/tools/clang/test/Driver/Output/darwin-header-search-libcxx.cpp.tmp/install/bin
mkdir: illegal option -- v
Usage: mkdir [-p] [-e] [-m mode] Directory ... 

How can I fix the test now?

@ilg-ul
Copy link
Contributor Author

ilg-ul commented Nov 20, 2023

I opened #72924 to fix this bug.

MaskRay pushed a commit that referenced this pull request Nov 21, 2023
… on AIX (#72924)

The PR #70817 introduced a
small bug, the tests failed on ppc64-aix with:

```
RUN: at line 186: mkdir -pv /home/powerllvm/powerllvm_env/aix-ppc64/clang-ppc64-aix/build/tools/clang/test/Driver/Output/darwin-header-search-libcxx.cpp.tmp/install/bin
+ mkdir -pv /home/powerllvm/powerllvm_env/aix-ppc64/clang-ppc64-aix/build/tools/clang/test/Driver/Output/darwin-header-search-libcxx.cpp.tmp/install/bin
mkdir: illegal option -- v
Usage: mkdir [-p] [-e] [-m mode] Directory ... 
```

This PR removes the verbose flag from both `mkdir` and `ln -s`.
@MaskRay
Copy link
Member

MaskRay commented Feb 3, 2024

changing the structure of the symlinks is not possible, it is done automatically by a tool.

To be fair: tools can be changed, and in fact you're proposing to change one ;)

But that said, now I see what you're up against.

I am more convinced that we should unify InstalledDir and Dir.
Right now include and library paths are partially derived from Dir/ResourceDir (derived from ClangExecutable) and partially derived from InstalledDir.

I believe that InstalledDir (2010 8897991) was a partial solution when -no-canonical-prefixes (2009) did not work well. InstalledDir should eventually be removed.

Created #80527

MaskRay added a commit that referenced this pull request Mar 4, 2024
My #80527 mentioned that `InstalledDir` was weird in the
-canonical-prefixes mode. #70817 was a workaround to find the libc++
include path for a symlinked clang. After #80527, `InstalledDir` was
identical to `Dir` and was subsequently removed, the code change #70817
can be reverted.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants