gradle / gradle-native

The home of Gradle's support for natively compiled languages
https://blog.gradle.org/introducing-the-new-cpp-plugins
Apache License 2.0
93 stars 8 forks source link

Gradle should explicitly control set of include paths used #564

Open big-guy opened 6 years ago

big-guy commented 6 years ago

We investigated a failure on two different machines for #551. Ultimately, we traced this back to a couple of issues:

To make this less susceptible to "it works on my machine", Gradle should explicitly control the list of includes. This means:

lacasseio commented 6 years ago

I did some more reading on this issue and it appears to be a multi-layer problem that seems to suggest other consideration for improvement.

The main issue is that /usr/include seems to contain an older version of libstdc++ (GCC/GNU), more precisely, version 4.2.1. However, Xcode SDK is based around libc++ (LLVM). It seems to be a widespread issue that some project only detect at runtime where both runtimes are linked inside the same binary. The "real" C++ library should be the one inside selected Xcode SDK and /usr/include should be ignored. In fact, there are a lot of "real" C++ library, and it depends on what you are trying to achieve.

To discover the "real" C++ library, we need to use the concept of system root (--sysroot and -isysroot) which is:

Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers in /usr/include and libraries in /usr/lib, it instead searches dir/usr/include and dir/usr/lib

If we query the toolchain using clang -v -dM -E - < /dev/null we get the following:

#include <...> search starts here:
 /usr/local/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)

However, if we query the toolchain using the Xcode SDK as the system root using clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -v -dM -E - < /dev/null we get the following:

#include <...> search starts here:
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks (framework directory)

Note the discovered include roots are completely different. It's also the key for cross-compiling between macOS and iOS.

I think we should defer for a bit longer using -nostdinc and building our include roots. Instead, we should properly model system root for GCC and Clang.

big-guy commented 6 years ago

@adammurdoch could you fix this up?

big-guy commented 6 years ago

Could you split this into two issues @adammurdoch for nostdinc and sysroot