This is an archive of the discontinued LLVM Phabricator instance.

Add libc++ header path for DarwinClang builds
AbandonedPublic

Authored by hintonda on Sep 4 2015, 1:50 PM.

Details

Summary

Current behavior doesn't add c++ header path if libc++ wasn't installed via macports in /usr. This change will try to locate c++ headers from various locations, including in tree, via macports, sysroot, and default Xcode location -- which is how my configuration finds it.

This probably needs a bit of work, especially wrt other configurations, so feedback would be appreciated..

+Bob Wilson who added the -stdlib=libc++ logic

Diff Detail

Event Timeline

hintonda updated this revision to Diff 34072.Sep 4 2015, 1:50 PM
hintonda retitled this revision from to Add libc++ header path for DarwinClang builds.
hintonda updated this object.
hintonda added a reviewer: rsmith.
hintonda added a subscriber: cfe-commits.
hintonda updated this revision to Diff 34175.Sep 7 2015, 5:36 PM
hintonda removed reviewers: thakis, EricWF, kubamracek.

Removed redundant code from InitHeaderSearch.cpp, it's handled more cleanly in AddClangCXXStdlibIncludeArgs.

Also, newer versions of OSX add libc++ as the default. Perhaps this could be done in cmake, as well as passing the default path to the c++ include directory used by the version of clang used to compile clang. This directory can be found by running xcrun -f clang and munging the path, e.g.,

LIBCXX_INCLUDE_DIR=$(dirname $(dirname $(xcrun -f clang))..)/include/c++/v1

Not sure why arc removed some reviewers when I added the latest diff, but
I've added them back.

Sorry for the noise...

kubamracek edited edge metadata.Sep 8 2015, 4:23 AM

In what scenario exactly are you seeing an issue? If it's a just-built clang that can't find C++ headers, then you should just build the libcxx project alongside.

lib/Driver/ToolChains.cpp
290–295

This is just a default location of Xcode.app and it's wrong to hardcode it, because the user can install Xcode to different locations (or have multiple installations). Even letting CMake find the path will be wrong, because the location of Xcode is a user's choice.

In D12646#241308, @kubabrecka wrote:

In what scenario exactly are you seeing an issue? If it's a just-built clang that can't find C++ headers, then you should just build the libcxx project alongside.

clang++ defaults to -stdlib=libc++ for newer versions of MacOS (see ToolChains.cpp:902), but since there isn't a way to pass corresponding include path via cmake, clang++ doesn't work out of the box, i.e., it only checks /usr/include/c++/v1, not the path relative to the version of clang used to build it.

I first noticed it when I tried to run the version of clang-tidy I'd just built and found I had to pass the path for it to find iostream.

This is just a default location of Xcode.app and it's wrong to hardcode it, because the user can install Xcode to different locations (or have multiple installations). Even letting CMake find the path will be wrong, because the location of Xcode is a user's choice.

Yes, but if you allow the user to pass the include path via cmake, how could that be wrong? This is equivalent to passing GCC_INSTALL_PREFIX so clang can find the gcc headers for libstdc++.

The user can always override it if they want to use a different version, but right now, overriding the location is the only way to make it work. If we're not going to generate a working version using libc++, perhaps we shouldn't override -stdlib=libc++ unless the appropriate headers can't be found.

hintonda updated this object.Sep 8 2015, 8:48 AM
hintonda added a reviewer: bob.wilson.
thakis edited edge metadata.Sep 8 2015, 9:09 AM
In D12646#241308, @kubabrecka wrote:

In what scenario exactly are you seeing an issue? If it's a just-built clang that can't find C++ headers, then you should just build the libcxx project alongside.

clang++ defaults to -stdlib=libc++ for newer versions of MacOS (see ToolChains.cpp:902), but since there isn't a way to pass corresponding include path via cmake, clang++ doesn't work out of the box, i.e., it only checks /usr/include/c++/v1, not the path relative to the version of clang used to build it.

I first noticed it when I tried to run the version of clang-tidy I'd just built and found I had to pass the path for it to find iostream.

I think it works if you a) check out libcxx into llvm/projects/libcxx b) run make install and c) run the binary from your install directory.

I first noticed it when I tried to run the version of clang-tidy I'd just built and found I had to pass the path for it to find iostream.

I think it works if you a) check out libcxx into llvm/projects/libcxx b) run make install and c) run the binary from your install directory.

I don't think b) and c) are necessary. At least for CMake builds, if you checkout libcxx, the output directory will get the C++ headers in the right place.

I think it works if you a) check out libcxx into llvm/projects/libcxx b) run make install and c) run the binary from your install directory.

Yes, that works. But why shouldn't users be able to use the installed version?

Also, if you want to force users to either build libc++ or have the headers installed in /usr/include/c++/v1, then cmake should fail if neither is the case.

bob.wilson edited edge metadata.Sep 8 2015, 9:21 AM

On Darwin platforms, the libc++ headers are expected to be installed alongside clang. If you're not doing that, then you're building it wrong. Adding more fallback options for finding the headers just makes things worse, because instead of a clear failure, you're more likely to get something that works but behaves badly in a subtle way (e.g., due to using really old libc++ headers).

I don't think this is the right thing to do.

On Darwin platforms, the libc++ headers are expected to be installed alongside clang. If you're not doing that, then you're building it wrong. Adding more fallback options for finding the headers just makes things worse, because instead of a clear failure, you're more likely to get something that works but behaves badly in a subtle way (e.g., due to using really old libc++ headers).

I don't think this is the right thing to do.

Okay, I'm comfortable with this solution. I'll work up a diff that makes cmake fail if libc++ isn't included in the build.

hintonda abandoned this revision.Feb 6 2016, 8:25 AM