Search path for 'include/c++/v1' on macOS

I noticed that on 12.0.1, in clang/lib/Driver/ToolChains/Darwin.cpp, DarwinClang::AddClangCXXStdlibIncludeArgs, the search path for the C++ headers was improved and now includes:

  1. Alongside the compiler in <install>/include/c++/v1
  2. In a SDK (or a custom sysroot) in <sysroot>/usr/include/c++/v1

However in the relatively modern macOS releases (I checked 10.13 and 11.4), the headers are in

  • /Library/Developer/CommandLineTools/usr/include/c++/v1

To fix this I added a third case to the logic:

    llvm::SmallString<128> CLT = 
      StringRef("/Library/Developer/CommandLineTools/usr/include/c++/v1");
    if (getVFS().exists(CLT)) {
      addSystemInclude(DriverArgs, CC1Args, CLT);
      return;
    } else if (DriverArgs.hasArg(options::OPT_v)) {
      llvm::errs() << "ignoring nonexistent directory \"" << CLT
                   << "\"\n";
    }

For my distribution this solution seems functional.

What do you think? Should I prepare a patch and submit it for review?

Isn’t /Library/Developer/CommandLineTools/ the path when Xcode isn’t installed on the machine?
Regardless, that seems like a valuable addition to me.

That’s a good question, and this was my initial understanding too, but I encountered systems with Xcode installed which also have this folder, so now I tent to believe that Apple always provides this folder.

Anyway, on my machine, without this addition, the 12.0.1 build did not pass.

Unfortunately this is not true :frowning:

I installed a fresh macOS 10.15 and Xcode 11.7, and the /Library/Developer/ folder was added, but it does not contain the CommandLineTools sub-folder.

The actual search path, as reported by gcc -v is:

#include <...> search starts here:
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.3/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.

My builds obviously fail in this setup.

I’m not sure what would be the best strategy for now. The only thing that comes to my mind is to make the Command Line Tools mandatory, and in this case the short /Library/Developer/CommandLineTools/ should be available.

/Library/Developer/CommandLineTools/ only exists if the user has explicitly installed the command line tools with xcode-select --install (or from a pkg downloaded from the developer portal). Homebrew does recommend / require this for some packages so I imagine for many users that’s the most likely reason they would be installed.

Right, my tests also confirm this.

So I think that, at least for my use case (a standalone cross-platform standalone binary distribution), my patch and the requirement to have CLT installed should be enough.

Should I contribute my patch to the repo?

Your patch should only allow to fallback to this directory if it exists right? Your patch does not add a new “requirement” to have the command line tools available, it only makes it works more transparently when available right?

You can always send a patch, it is cheap :slight_smile:

That’s correct.

The original code in 12.0.1 had two choices, I added a third:

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

The actual code is in the xpack-dev-tools/llvm-project fork.

My patch does not add a new requirement for the generic macOS build, but for my specific standalone build, without the Command Line Tools installed, any C++ compile is expected to fail, since there are no C++ headers in my standalone toolchain. But this is another story, I created a separate topic for it.

Yeah, thank you for the encouragement, but since I’m new to the LLVM development workflow, I thought it is more polite to first ask the opinion of more experienced people.