1. 第一次接触rsicv64的交叉编译环境(其他交叉编译环境也基本没接触过,只是知道概念和原理),目前的需求是需要在gitlab上给一套rsicv64-linux-gcc执行CI任务,默认直接在本地服务器执行交叉编译,需要经常清理服务器文件,且成熟的开发环境不适合作为测试环境来运行,因此考虑将CI任务直接在Docker中执行,也需要配置最小化且测试环境最干净的Docker镜像。
  2. 手工在服务器执行,全套流程都是成功的,没有任何问题,但是放到ubuntu 20.04的docker中执行就全失败了,各种依赖库根据报错都逐个安装并解决了,最后所有的任务开始,编译进行到一半退出了,一直提示riscv64-linux-gcc可执行文件no such file or directory

Debug流程:

  1. 首先在CI任务的after_script中逐个ls显示riscv64-linux-gcc的完整目录和文件,发现所有文件都存在,但是不能执行,在本地服务器中手工执行riscv64-linux-gcc -v是没问题的,基本说明这是docker中的编译环境问题导致,但是目前哪个环境导致的问题还非常不明确
$ ls -alht /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
-rwxrwxrwx 1 1000 1000 98K Dec  3  2019 /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
$ /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc --help
/bin/bash: line 128: /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc: No such file or director
  1. docker使用的是最新的ubuntu 20.04,服务器是ubuntu 18.04,尝试把docker版本回退至18.04,问题依旧
  2. 仔细查看riscv64-linux-gcc整个目录和上级所有文件权限,用户,用户组,发现docker默认是root用户登录了,而root的uid/gid是0,但是tar解压出来的文件是属于1000 uid和1000 gid,但是权限已经是777,不确定是否这一块的问题,尝试修复为权限一致:在解压时指定参数–no-same-owner(即tar --no-same-owner -zxvf xxxx.tar.gz),则会将执行该tar命令的用户作为解压后的文件目录的所有者。参考链接:使用root解压后文件夹权限不是root ,手工修改gitlab的Makefile,将所有tar参数加上--no-same-owner参数,解压后文件owner变了,但是问题依旧,修改文件owner并不行,因为可执行文件权限已经是777了,user和group没有影响,而且docker中默认是root用户登录的,权限最高了,也不属于这一块的问题。
$ ls -alht /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
-rwxrwxrwx 1 root root 98K Dec  3  2019 /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
$ /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc --help
/bin/bash: line 128: /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc: No such file or directory

因为docker默认使用root权限运行,导致一些权限异常,那么是否是因为默认root用户执行导致的呢?尝试修改docker中默认用户,新增docker普通用户,用在docker启动时默认普通用户登录,继续给该docker用户增加sudo权限,并设置sudo免密码,最后问题还是依旧,依然不能解决。参考: Using sudo without password prompt as non-root docker user

$ ls -alht /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
-rwxr-xr-x 1 ubuntu ubuntu 98K Dec  3  2019 /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
$ /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc --help
/usr/bin/bash: line 128: /builds/xxx/xxx_buildroot/buildroot-2020.02.11/../toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc: No such file or directory
  1. 所有用户,用户组,文件权限,默认执行任务的用户权限,都排除了,都不能解决,但问题还是属于环境问题,不是用户和权限的文件了。
  2. 用户相关权限被排除了,环境问题怎么解决?是否是docker版本的问题呢?ubuntu 18.04上自带的是docker的早期版本,尝试卸载docker,并安装最新版docker-ce,问题依旧,仍然不能解决。
  3. 通过file命令查看该文件在服务器上的信息
file ./toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc
/home/xxx/workspace/xxx_buildroot/toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.9, stripped

而docker和本地服务器都是x86-64:

ubuntu@e3dcdd33cc14:~$ uname -a
Linux e3dcdd33cc14 5.4.0-73-generic #82~18.04.1-Ubuntu SMP Fri Apr 16 15:10:02 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

搜了一下,arm-linux-gcc也是同样的结果,arm下的解决办法:

arm-linux-gcc 执行的时候提示“没有那个文件”

说明文件应该类似啊,也符合环境依赖库缺少导致文件不能执行,于是直接尝试在docker镜像中安装这几个依赖库文件:

sudo apt-get install libc6-i386 libc6-dev-i386

紧接着直接在docker里面手工验证结果,不再提示no such file or directory,然后直接输出详细信息了:

ubuntu@e3dcdd33cc14:~$ ~/xxx_buildroot/toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc -v
"/home/ubuntu/xxx_buildroot/toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc.gnu" "-v"
Using built-in specs.
COLLECT_GCC=/home/ubuntu/xxx_buildroot/toolchain/nds64le-linux-glibc-v5d/bin/riscv64-linux-gcc.gnu
COLLECT_LTO_WRAPPER=/home/ubuntu/xxx_buildroot/toolchain/nds64le-linux-glibc-v5d/bin/../libexec/gcc/riscv64-linux/7.3.0/lto-wrapper
Target: riscv64-linux
Configured with: /local/sqa/Jenkins/workspace/build-system-3/source-packages/gcc-7.4.0-riscv-ast-v3_2_0-branch-official/configure --target=riscv64-linux --prefix=/local/sqa/Jenkins/workspace/build-system-3/toolchain/nds64le-linux-glibc-v5d --with-pkgversion=2019-11-20_nds64le-linux-glibc-v5d-6c120106e03 --disable-nls --enable-languages=c,c++ --enable-lto --with-gmp=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-mpfr=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-mpc=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-isl=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-cloog=/local/sqa/Jenkins/workspace/build-system-3/host-tools --with-arch=rv64imafdcxv5 --with-tune=nx25 --enable-gp-insn-relax-default=yes --with-abi=lp64d --disable-werror --disable-multilib --enable-shared --enable-tls --with-sysroot=/local/sqa/Jenkins/workspace/build-system-3/toolchain/nds64le-linux-glibc-v5d/riscv64-linux/sysroot CFLAGS='-O2 -g -Wno-implicit-fallthrough -Wno-int-in-bool-context -Wno-cast-function-type -Wno-tautological-compare ' CXXFLAGS='-O2 -g -Wno-implicit-fallthrough -Wno-int-in-bool-context -Wno-cast-function-type -Wno-tautological-compare ' CC=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/gcc CXX=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/g++ LD=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/ld AR=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/gcc-ar RANLIB=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/gcc-ranlib NM=/local/sqa/Jenkins/workspace/build-system-3/host-tools/bin/nm --enable-checking=release LDFLAGS=--static 'CFLAGS_FOR_TARGET=-O2 -g  -mstrict-align -msoft-fp16' 'CXXFLAGS_FOR_TARGET=-O2 -g  -mstrict-align -msoft-fp16' LDFLAGS_FOR_TARGET=
Thread model: posix
gcc version 7.3.0 (2019-11-20_nds64le-linux-glibc-v5d-6c120106e03)
ubuntu@e3dcdd33cc14:~$

说明问题已经成功解决了

和docker的root用户解压,和文件用户组,和文件权限,关系并不大,只是不熟悉rsicv64-linux-gcc的交叉编译环境,是服务器x64_64和交叉编译是32位导致。