Skip to content

Instantly share code, notes, and snippets.

@dongcarl
Last active August 3, 2020 20:53
Show Gist options
  • Save dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9 to your computer and use it in GitHub Desktop.
Save dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9 to your computer and use it in GitHub Desktop.
More robust and explicit clang search path ordering

The Symptom

Currently, our darwin_CXX looks something like this:

clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \
        --sysroot $(OSX_SDK) -stdlib=libc++ -mlinker-version=$(LD64_VERSION) \
        -B$(build_prefix)/bin -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1

When ran in a freshly built Ubuntu Bionic docker container with the SDK copied in, the output looks like this:

root@04d377caaf5a:~/build# clang++-8 -target x86_64-apple-darwin16 -mmacosx-version-min=10.12 --sysroot $PWD/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -stdlib=libc++ -mlinker-version=530 -nostdinc++ -isystem $PWD/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -xc++ -v -E - < /dev/null > /dev/null
clang version 8.0.0-3~ubuntu18.04.2 (tags/RELEASE_800/final)
Target: x86_64-apple-darwin16
Thread model: posix
InstalledDir: /usr/bin
 "/usr/lib/llvm-8/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -faligned-alloc-unavailable -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -ggnu-pubnames -target-linker-version 530 -v -nostdinc++ -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -isystem /root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -isysroot /root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /root/build -ferror-limit 19 -fmessage-length 114 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fobjc-runtime=macosx-10.12.0 -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o - -x c++ -
clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/local/include"
ignoring nonexistent directory "/root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1
 /usr/lib/llvm-8/lib/clang/8.0.0/include
 /root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include
 /root/build/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/System/Library/Frameworks (framework directory)
End of search list.

However, if I do the same in our current Guix environment, this is the output:

bash-5.0$ clang++ -target x86_64-apple-darwin16 -mmacosx-version-min=10.12 --sysroot /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -stdlib=libc++ -mlinker-version=530 -nostdinc++ -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -xc++ -v -E - < /dev/null > /dev/null
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-apple-darwin16
Thread model: posix
InstalledDir: /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/bin
 "/gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/bin/clang-8" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -faligned-alloc-unavailable -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -ggnu-pubnames -target-linker-version 530 -v -nostdinc++ -resource-dir /gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/lib/clang/8.0.0 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -isysroot /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -I/gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /bitcoin -ferror-limit 19 -fmessage-length 104 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fobjc-runtime=macosx-10.12.0 -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -o - -x c++ -
clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/local/include"
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/gnu/store/ahqgl4h89xqj695lgqvsaf6zh2nhy4pj-glibc-2.29/include"
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1
 /gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/lib/clang/8.0.0/include
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/System/Library/Frameworks (framework directory)
End of search list.

The Examination

There are a few differences to note:

  1. There's an additional /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include entry at the top of the list of Guix search paths
  2. The list of Guix search paths does not include a $SYSROOT/usr/include entry between the clang resource dir and $SYSROOT/System/Library/Frameworks

(1) can be explained by looking at the guix environment and seeing that CPATH is set. The fact that clang picks up CPATH even when cross compiling is a little strange, but not totally ridiculous. We can prepend a env -u CPATH to fix this.

(2) is the interesting part of this difference. And requires looking into clang's default include path logic (permalink)

InitHeaderSearch::AddDefaultIncludePaths reproduced
void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
                                              const llvm::Triple &triple,
                                            const HeaderSearchOptions &HSOpts) {
  // NB: This code path is going away. All of the logic is moving into the
  // driver which has the information necessary to do target-specific
  // selections of default include paths. Each target which moves there will be
  // exempted from this logic here until we can delete the entire pile of code.
  switch (triple.getOS()) {
  default:
    break; // Everything else continues to use this routine's logic.


  case llvm::Triple::Linux:
  case llvm::Triple::Hurd:
  case llvm::Triple::Solaris:
    return;


  case llvm::Triple::Win32:
    if (triple.getEnvironment() != llvm::Triple::Cygnus ||
        triple.isOSBinFormatMachO())
      return;
    break;
  }


  if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
      HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
    if (HSOpts.UseLibcxx) {
      AddPath("/usr/include/c++/v1", CXXSystem, false);
    } else {
      AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
    }
  }


  AddDefaultCIncludePaths(triple, HSOpts);


  // Add the default framework include paths on Darwin.
  if (HSOpts.UseStandardSystemIncludes) {
    if (triple.isOSDarwin()) {
      AddPath("/System/Library/Frameworks", System, true);
      AddPath("/Library/Frameworks", System, true);
    }
  }
}

Looking at this logic, we can also see how @theuni's custom built clang wasn't able to pick up $SYSROOT/usr/include/c++/v1, most likely it didn't pass one of these if-guards here:

  if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
      HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
    if (HSOpts.UseLibcxx) {
      AddPath("/usr/include/c++/v1", CXXSystem, false);
    } else {
      AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
    }
  }

The function that will uncover the secrets of (2), is found in InitHeaderSearch::AddDefaultCIncludePaths (permalink)

InitHeaderSearch::AddDefaultCIncludePaths reproduced
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
                                            const HeaderSearchOptions &HSOpts) {
  llvm::Triple::OSType os = triple.getOS();


  if (HSOpts.UseStandardSystemIncludes) {
    switch (os) {
    case llvm::Triple::CloudABI:
    case llvm::Triple::FreeBSD:
    case llvm::Triple::NetBSD:
    case llvm::Triple::OpenBSD:
    case llvm::Triple::NaCl:
    case llvm::Triple::PS4:
    case llvm::Triple::ELFIAMCU:
    case llvm::Triple::Fuchsia:
      break;
    case llvm::Triple::Win32:
      if (triple.getEnvironment() != llvm::Triple::Cygnus)
        break;
      LLVM_FALLTHROUGH;
    default:
      // FIXME: temporary hack: hard-coded paths.
      AddPath("/usr/local/include", System, false);
      break;
    }
  }


  // Builtin includes use #include_next directives and should be positioned
  // just prior C include dirs.
  if (HSOpts.UseBuiltinIncludes) {
    // Ignore the sys root, we *always* look for clang headers relative to
    // supplied path.
    SmallString<128> P = StringRef(HSOpts.ResourceDir);
    llvm::sys::path::append(P, "include");
    AddUnmappedPath(P, ExternCSystem, false);
  }


  // All remaining additions are for system include directories, early exit if
  // we aren't using them.
  if (!HSOpts.UseStandardSystemIncludes)
    return;


  // Add dirs specified via 'configure --with-c-include-dirs'.
  StringRef CIncludeDirs(C_INCLUDE_DIRS);
  if (CIncludeDirs != "") {
    SmallVector<StringRef, 5> dirs;
    CIncludeDirs.split(dirs, ":");
    for (StringRef dir : dirs)
      AddPath(dir, ExternCSystem, false);
    return;
  }


  switch (os) {
  case llvm::Triple::Linux:
  case llvm::Triple::Hurd:
  case llvm::Triple::Solaris:
    llvm_unreachable("Include management is handled in the driver.");


  case llvm::Triple::CloudABI: {
    // <sysroot>/<triple>/include
    SmallString<128> P = StringRef(HSOpts.ResourceDir);
    llvm::sys::path::append(P, "../../..", triple.str(), "include");
    AddPath(P, System, false);
    break;
  }


  case llvm::Triple::Haiku:
    AddPath("/boot/system/non-packaged/develop/headers", System, false);
    AddPath("/boot/system/develop/headers/os", System, false);
    AddPath("/boot/system/develop/headers/os/app", System, false);
    AddPath("/boot/system/develop/headers/os/arch", System, false);
    AddPath("/boot/system/develop/headers/os/device", System, false);
    AddPath("/boot/system/develop/headers/os/drivers", System, false);
    AddPath("/boot/system/develop/headers/os/game", System, false);
    AddPath("/boot/system/develop/headers/os/interface", System, false);
    AddPath("/boot/system/develop/headers/os/kernel", System, false);
    AddPath("/boot/system/develop/headers/os/locale", System, false);
    AddPath("/boot/system/develop/headers/os/mail", System, false);
    AddPath("/boot/system/develop/headers/os/media", System, false);
    AddPath("/boot/system/develop/headers/os/midi", System, false);
    AddPath("/boot/system/develop/headers/os/midi2", System, false);
    AddPath("/boot/system/develop/headers/os/net", System, false);
    AddPath("/boot/system/develop/headers/os/opengl", System, false);
    AddPath("/boot/system/develop/headers/os/storage", System, false);
    AddPath("/boot/system/develop/headers/os/support", System, false);
    AddPath("/boot/system/develop/headers/os/translation", System, false);
    AddPath("/boot/system/develop/headers/os/add-ons/graphics", System, false);
    AddPath("/boot/system/develop/headers/os/add-ons/input_server", System, false);
    AddPath("/boot/system/develop/headers/os/add-ons/mail_daemon", System, false);
    AddPath("/boot/system/develop/headers/os/add-ons/registrar", System, false);
    AddPath("/boot/system/develop/headers/os/add-ons/screen_saver", System, false);
    AddPath("/boot/system/develop/headers/os/add-ons/tracker", System, false);
    AddPath("/boot/system/develop/headers/os/be_apps/Deskbar", System, false);
    AddPath("/boot/system/develop/headers/os/be_apps/NetPositive", System, false);
    AddPath("/boot/system/develop/headers/os/be_apps/Tracker", System, false);
    AddPath("/boot/system/develop/headers/3rdparty", System, false);
    AddPath("/boot/system/develop/headers/bsd", System, false);
    AddPath("/boot/system/develop/headers/glibc", System, false);
    AddPath("/boot/system/develop/headers/posix", System, false);
    AddPath("/boot/system/develop/headers",  System, false);
    break;
  case llvm::Triple::RTEMS:
    break;
  case llvm::Triple::Win32:
    switch (triple.getEnvironment()) {
    default: llvm_unreachable("Include management is handled in the driver.");
    case llvm::Triple::Cygnus:
      AddPath("/usr/include/w32api", System, false);
      break;
    case llvm::Triple::GNU:
      break;
    }
    break;
  default:
    break;
  }


  switch (os) {
  case llvm::Triple::CloudABI:
  case llvm::Triple::RTEMS:
  case llvm::Triple::NaCl:
  case llvm::Triple::ELFIAMCU:
  case llvm::Triple::Fuchsia:
    break;
  case llvm::Triple::PS4: {
    // <isysroot> gets prepended later in AddPath().
    std::string BaseSDKPath = "";
    if (!HasSysroot) {
      const char *envValue = getenv("SCE_ORBIS_SDK_DIR");
      if (envValue)
        BaseSDKPath = envValue;
      else {
        // HSOpts.ResourceDir variable contains the location of Clang's
        // resource files.
        // Assuming that Clang is configured for PS4 without
        // --with-clang-resource-dir option, the location of Clang's resource
        // files is <SDK_DIR>/host_tools/lib/clang
        SmallString<128> P = StringRef(HSOpts.ResourceDir);
        llvm::sys::path::append(P, "../../..");
        BaseSDKPath = P.str();
      }
    }
    AddPath(BaseSDKPath + "/target/include", System, false);
    if (triple.isPS4CPU())
      AddPath(BaseSDKPath + "/target/include_common", System, false);
    LLVM_FALLTHROUGH;
  }
  default:
    AddPath("/usr/include", ExternCSystem, false);
    break;
  }
}

Now we see that the missing $SYSROOT/usr/include is added at the end of the function. But what could cause this code path to not activate in Guix? The culprit is this code in the middle of the function:

  // Add dirs specified via 'configure --with-c-include-dirs'.
  StringRef CIncludeDirs(C_INCLUDE_DIRS);
  if (CIncludeDirs != "") {
    SmallVector<StringRef, 5> dirs;
    CIncludeDirs.split(dirs, ":");
    for (StringRef dir : dirs)
      AddPath(dir, ExternCSystem, false);
    return;
  }

The Diagnosis

Because Guix's build of clang uses the fully-supported, non-"Guix specific" functionality of specifying C_INCLUDE_DIRS at configure time, the rest of the include path logic in InitHeaderSearch::AddDefaultCIncludePaths is skipped, including the codepath to add $SYSROOT/usr/include. This leads to failed builds as all of the macOS SDK's C headers are inside $SYSROOT/usr/include.

The Treatment

So we need to find some way to be explicit and ensure the correct default include path ordering we expect, just like @theuni did for libc++ headers in this commit.

To achieve (2), we need to first understand what the "correct" default include path ordering is. Note that not only is getting the right set of paths important, the ordering is important as well if we want to avoid problems with #include_next and gang.

Here's a distillation of what's added by AddDefaultIncludePaths:

Path Include Group IsFramework If $SYSROOT, in Xcode SDK?
$SYSROOT/usr/include/c++/v1 CXXSystem FALSE TRUE
$SYSROOT/usr/local/include System FALSE FALSE
$RESOURCEDIR/include ExternCSystem FALSE N/A
$SYSROOT/usr/include ExternCSystem FALSE TRUE
$SYSROOT/System/Library/Frameworks System TRUE TRUE
$SYSROOT/Library/Frameworks System TRUE FALSE

More info on Include Groups

Another important thing to note is that all these paths need to occur after all -Is and C{,PLUS}_INCLUDE_PATHs

Okay, so let's try the obvious, adding -isystem $SYSROOT/usr/include to our invocation:

bash-5.0$ clang++ -target x86_64-apple-darwin16 -mmacosx-version-min=10.12 --sysroot /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -stdlib=libc++ -mlinker-version=530 -nostdinc++ -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include -xc++ -v -E - < /dev/null > /dev/null
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-apple-darwin16
Thread model: posix
InstalledDir: /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/bin
 "/gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/bin/clang-8" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -faligned-alloc-unavailable -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -ggnu-pubnames -target-linker-version 530 -v -nostdinc++ -resource-dir /gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/lib/clang/8.0.0 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include -isysroot /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -I/gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /bitcoin -ferror-limit 19 -fmessage-length 159 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fobjc-runtime=macosx-10.12.0 -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -o - -x c++ -
clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/local/include"
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/gnu/store/ahqgl4h89xqj695lgqvsaf6zh2nhy4pj-glibc-2.29/include"
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include
 /gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/lib/clang/8.0.0/include
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/System/Library/Frameworks (framework directory)
End of search list.

Unfortunately this places $SYSROOT/usr/include on top of the $RESOURCEDIR/include. So that doesn't work. What's more, if we try this with a CPLUS_INCLUDE_PATH like so:

We end up with an ordering that is definitely not what we want (this is currently broken on master as well):

bash-5.0$ env CPLUS_INCLUDE_PATH="$PWD" clang++ -target x86_64-apple-darwin16 -mmacosx-version-min=10.12 --sysroot /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -stdlib=libc++ -mlinker-version=530 -nostdinc++ -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include -xc++ -v -E - < /dev/null > /dev/null
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-apple-darwin16
Thread model: posix
InstalledDir: /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/bin
 "/gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/bin/clang-8" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -E -disable-free -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -faligned-alloc-unavailable -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -ggnu-pubnames -target-linker-version 530 -v -nostdinc++ -resource-dir /gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/lib/clang/8.0.0 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1 -isystem /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include -isysroot /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers -I/gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include -cxx-isystem /bitcoin -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /bitcoin -ferror-limit 19 -fmessage-length 159 -stack-protector 1 -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fobjc-runtime=macosx-10.12.0 -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -o - -x c++ -
clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/local/include"
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/gnu/store/ahqgl4h89xqj695lgqvsaf6zh2nhy4pj-glibc-2.29/include"
ignoring nonexistent directory "/bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /gnu/store/w8y7rbmjbdjx1bd3jgw5idvwv7s1jdby-profile/include
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include/c++/v1
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/usr/include
 /bitcoin
 /gnu/store/pp3s4h323dadc3l7yxj5zcc5lsi363fs-clang-8.0.0/lib/clang/8.0.0/include
 /bitcoin/depends/SDKs/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers/System/Library/Frameworks (framework directory)
End of search list.

The only way to solve this debacle is to list out all our expected default paths using -Xclang flag in combination with -cxx-isystem, -internal-externc-isystem. This way we make sure that:

  • Our default paths always occur after env var paths/user specified paths
  • Our default paths always end up in the correct ordering amoungst themselves
  • Our default paths are picked up by cc1 as the correct include group

Like so:

clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \
        --sysroot $(OSX_SDK) \
        -Xclang -cxx-isystem$(OSX_SDK)/usr/include/c++/v1 \
        -Xclang -internal-externc-isystem$(clang -print-resource-dir)/include \
        -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include \
        -stdlib=libc++ -mlinker-version=$(LD64_VERSION) \
        -B$(build_prefix)/bin -nostdinc++
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment