clang 交叉编译的默认包含目录错误?

clang 交叉编译的默认包含目录错误?

我的构建机器是 xenial x86_64。我正在为 arm-linux-gnueabihf 进行交叉编译。我已经安装了 g++-arm-linux-gnueabihf。

使用 构建时clang++ --target=arm-linux-gnueabihf,我收到错误“ /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/c++/5.4.0/string:38:10: fatal error: 'bits/c++config.h' file not found”。但为什么它读取的是/usr/include/c++/5/string

使用建议的命令“从 g++ 转储包含路径” ,我检查了以下包含路径arm-linux-gnueabihf-g++

$ /usr/bin/arm-linux-gnueabihf-g++ -E -x c++ - -v < /dev/null
Using built-in specs.
COLLECT_GCC=/usr/bin/arm-linux-gnueabihf-g++
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-armhf-cross/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-armhf-cross --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-armhf-cross --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libgcj --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.4) 
COLLECT_GCC_OPTIONS='-E' '-v' '-shared-libgcc' '-march=armv7-a' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-mthumb' '-mtls-dialect=gnu'
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/cc1plus -E -quiet -v -imultiarch arm-linux-gnueabihf -D_GNU_SOURCE - -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mthumb -mtls-dialect=gnu -fstack-protector-strong -Wformat -Wformat-security
ignoring nonexistent directory "/usr/local/include/arm-linux-gnueabihf"
ignoring nonexistent directory "/usr/include/arm-linux-gnueabihf"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/include/c++/5
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/include/c++/5/arm-linux-gnueabihf
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/include/c++/5/backward
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/include
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/include-fixed
 /usr/lib/gcc-cross/arm-linux-gnueabihf/5/../../../../arm-linux-gnueabihf/include
 /usr/include
End of search list.

然后我检查包含路径clang++-3.8 --target=arm-linux-gnueabihf

$ /usr/bin/clang++-3.8 --target=arm-linux-gnueabihf -E -x c++ - -v < /dev/nullclang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: arm--linux-gnueabihf
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0
Found candidate GCC installation: /usr/lib/gcc-cross/arm-linux-gnueabihf/5.4.0
Selected GCC installation: /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0
Candidate multilib: .;@m32
Selected multilib: .;@m32
 "/usr/lib/llvm-3.8/bin/clang" -cc1 -triple armv6kz--linux-gnueabihf -E -disable-free -disable-llvm-verifier -main-file-name - -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu arm1176jzf-s -target-feature +strict-align -target-abi aapcs-linux -mfloat-abi hard -v -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib/llvm-3.8/bin/../lib/clang/3.8.0 -internal-isystem /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/c++/5.4.0 -internal-isystem /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/arm-linux-gnueabihf/c++/5.4.0 -internal-isystem /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/arm--linux-gnueabihf/c++/5.4.0 -internal-isystem /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/c++/5.4.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-3.8/bin/../lib/clang/3.8.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /home/leo/ws/odroid_ws -ferror-limit 19 -fmessage-length 157 -fallow-half-arguments-and-returns -fno-signed-char -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o - -x c++ -
clang -cc1 version 3.8.0 based upon LLVM 3.8.0 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/arm-linux-gnueabihf/c++/5.4.0"
ignoring nonexistent directory "/usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/arm--linux-gnueabihf/c++/5.4.0"
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/c++/5.4.0
 /usr/bin/../lib/gcc-cross/arm-linux-gnueabihf/5.4.0/../../../../include/c++/5.4.0/backward
 /usr/local/include
 /usr/lib/llvm-3.8/bin/../lib/clang/3.8.0/include
 /usr/include
End of search list.

我注意到(在使用 readlink 从路径中删除混乱的 ../.. 之后):

arm-linux-gnueabihf-g++用途/usr/arm-linux-gnueabihf/include/c++/5,并且不使用/usr/include/c++/5。

clang++ --target=arm-linux-gnueabihf用途/usr/include/c++/5,并且不使用/usr/arm-linux-gnueabihf/include/c++/5。

clang 错了吗?我该怎么做才能修复它?

答案1

我仍然不知道 clang 和/或我的系统配置出了什么问题,但我使用这些标志作为解决方法:

-nostdinc++ -cxx-isystem /usr/arm-linux-gnueabihf/include/c++/5 -cxx-isystem /usr/arm-linux-gnueabihf/include/c++/5/arm-linux-gnueabihf

答案2

在这种情况下,您可以使用--sysroot=/usr/arm-linux-gnueabihf/sys-root。从 6.0 版(尚未发布的 ATM)开始,Clang 似乎可以解决 Linux 发行版中 GNU 库和工具(特别是 gcc、glibc 和 libstdc++)的多种布局方式。您可能仍会遇到一些问题,即使用

clang -v ...

strace -e 'trace=!write' clang ...

查看 Clang 正在搜索的目录会有所帮助。我在 Fedora 上找到了一个 hacky 解决方案。我目前正在做:

(我在这里使用 gcc 7 和 clang,并且<sysroot>=/usr/arm-linux-gnueabihf/sys-root

  1. 安装交叉编译先决条件(因发行版而异,但 Fedora 有一个文件系统包,可创建文件<sysroot>夹)。这还包括目标平台的所有二进制文件和开发头文件。不幸的是,许多平台上没有很好的现成解决方案。例如,Fedora 缺少libstdc++aarch64,但我记得 Debian 和 Ubuntu 有这个。

  2. 为平台创建 sysroot

    mkdir -p <sysroot>/lib/gcc
    ln -s <sysroot>/include <sysroot>/usr/include # Another Clang quirk, it seems
    
  3. 复制 GCC 二进制文件和 libstdc++ 头文件。这有点令人沮丧,因为 Clang 查找 GCC 安装的方式是通过搜索常用路径 (例如, /usr/lib/gcc/x86_64-linux-gnu) 并向上移动 X 个目录以查找相关标头。这意味着,除非您可以从 gcc 二进制文件创建到新 sys-root 的硬链接,否则您将需要复制二进制文件和(一些)标头。为了使其正常工作,我必须这样做(对您来说可能有所不同):

    cp -r /usr/lib/gcc/arm-linux-gnueabihf/ <sysroot>/lib/gcc
    # Fedora installs C++ headers here, but we will copy them into sys-root
    # Copy all of your other headers in the same manner
    cp -r /usr/arm-linux-gnueabihf/include/c++ <sysroot>/include
    
  4. 将标志添加--sysroot=到 clang

    clang --target=arm-linux-gnueabihf --sysroot=<sysroot> ...
    

Clang 中处理搜索这些目录的大部分逻辑似乎都在这些文件中(它们可能不存在于旧版本的 Clang 中):

lib/驱动程序/工具链/Gnu.cpp

lib/驱动程序/工具链/Linux.cpp

相关内容