回到电脑上试试。我用的交叉编译器是gcc 7.5版本,安装在/home/user//cross-gcc/。 我通过剪切和粘贴将其位置更改为 /home/user//cross-gcc/ ,然后在新打开的终端中
export PATH=/home/user/Documents/cross-gcc/bin:$PATH
将交叉编译器路径添加到$PATH开始测试,发现编译正常
aarch64-linux-gun-gcc -c test.c
由于找不到动态 C 链接库,链接期间发生错误。
aarch64-linux-gun-gcc -o test test.o
错误信息是
/home/user/Documents/cross-gcc/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: cannot find /home/user/Downloads/cross-gcc/aarch64-linux-gnu/lib/libc.so.6
天哪,看来-linux-gun-gcc使得链接器ld仍然按照绝对路径在/home/user//cross-gcc/中寻找libc.so.6,而此时一切都在/中home/user //cross-gcc/ 是的! 我想要的是根据相对路径找到链接库! 这样我的交叉编译器就真正可移植了!
根据经验,我认为gcc在哪里指示ld查找libc.so.6等库文件可以通过gcc参数来控制,所以在gcc源代码目录下的./ --help,看了之后,我认为相关的是 --with- 和 --with-build-。 我立刻上网一搜,看到的是一个被这两个参数忽悠的家伙:
/-ml/gcc-help/2007-02/.html
然后我又看了下面页面的Cross--部分对这两个参数的说明:
//.html
然后我也晕了。 看来我们首先要仔细了解一下build、host等,于是我发现了这个有趣的页面:
///-Terms.html
简单描述一下它的意思就是:你制作交叉编译器的机器是build,运行交叉编译器的机器是host,运行交叉编译器编译出的程序的机器是host。 三个都相同称为编译,只有前两个相同称为交叉编译,只有第一个和第三个相同称为编译,以此类推。 上页也提到,在制作交叉编译器的链接库时,如前所述,host是不存在的。 这将在稍后应用。
以我目前的理解,我回到上面的第二个链接,查看了 --with- 和 --with-build- 的描述。 我知道只有 --with- 是有用的,因为它写在它的描述中。 :这...新的 make 。 这意味着这个参数影响主机gcc的行为,这正是我所需要的。 另外,它的描述中有一句话:If the is a of ${}, then it will find to the GCC if the tree is . 也就是说,当指定的 --with- 目录为 --(本文中与 ${} 的子目录相同)目录时,跨平台 gcc 会使用相对路径来查找所需的链接图书馆! 突然,他的眼睛一亮!
现在是时候谈谈我用来创建交叉编译器参考的教程了:
//p/.html
/2018/05/06/-gcc-cross---pi/
//如何构建-gcc-cross-/
第一篇文章引用了后两篇文章。 建议想要采取行动的人阅读全部三篇文章,相互印证。 以这种方式创建的交叉编译器并不是真正可移植的。 所在目录不能更改,否则找不到链接库。 我决定使用 --with- 参数尝试一下。
第一次尝试我用 gcc 这样做:
../configure --prefix=/home/user/Documents/cross-gcc/ --with-sysroot=/home/user/Documents/cross-gcc/aarch64-linux-gnu/ --with-native-system-header-dir=/include/ --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib
使用/home/user//cross-gcc/-linux-gnu/因为是实名,看里面的目录结构和文件就可以了。 使用--with----dir=//是因为没有这个,程序在make的时候会在/home/user//cross-gcc/-linux-gnu/usr//中寻找头文件,而头文件该文件位于/home/user//cross-gcc/-linux-gnu//中,我们需要将默认值/usr//替换为//。
完成所有步骤后,我发现跨gcc被破坏了,链接时出现错误:
/home/user/Documents/cross-gcc/lib/gcc/aarch64-linux-gnu/9.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find /home/user/Documents/cross-gcc/aarch64-linux-gnu/lib/libc.so.6 inside /home/user/Documents/cross-gcc/aarch64-linux-gnu
有朋友需要这个cross-gcc,版本号是9.3。 这个错误信息比我根据教程做的更改路径后制作的7.5版本的cross-gcc给出的错误信息多了一段/home/user//cross-gcc/-linux-gnu。 似乎 cross-gcc 的 9.3 版本将 /home/user//cross-gcc/-linux-gnu/ 视为根目录(/),并在中查找 /home/user//cross-gcc/-linux-gnu它。 /lib/libc.so.6,所以它期望:
/home/user/Documents/cross-gcc/aarch64-linux-gnu/home/user/Documents/cross-gcc/aarch64-linux-gnu/lib/libc.so.6
将 cross-gcc 重命名为 cross-gcc-9 并将其从 /home/user// 移动到 /home/user// 并再次测试。 错误信息如下:
/home/user/Downloads/cross-gcc-9/bin/../lib/gcc/aarch64-linux-gnu/9.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find /home/user/Documents/cross-gcc/aarch64-linux-gnu/lib/libc.so.6 inside /home/user/Downloads/cross-gcc-9/bin/../aarch64-linux-gnu
哇,更改跨gcc路径后,ld会去查找发生相应更改的libc.so.6。 这个改变是正确的。 看来 //.html 页面中的 Cross-- 部分正确的是 --with- 描述是正确的!
这很简单。 首先对/home/user//cross-gcc/-linux-gnu/进行备份,然后在/home/user//cross-gcc/-linux-gnu/下逐层新建文件夹home。 、user、cross-gcc,最后将上述备份移动到新创建的cross-gcc中。 问题解决了,但并不完美。 首先,备份可以是符号链接,以节省磁盘空间。 其次,我更喜欢--with-=/home/user//cross-gcc//。
所以我开始了第二次尝试,首先创建一个空目录:
mkdir –p /home/user/Documents/cross-gcc/sysroot/usr/include
然后 gcc 像这样:
../configure --prefix=/home/user/Documents/cross-gcc/ --with-sysroot=/home/user/Documents/cross-gcc/sysroot/ --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib
最后我发现--with-=/home/user//cross-gcc//根本不起作用。 看来这个需求是有意义的。
那么,创建一个指向 -linux-gnu 的符号链接还不够吗? 于是就有了第三次尝试:
cd cross-gcc/
ln -s aarch64-linux-gnu sysroot
cd sysroot
mkdir -p ./home/user/Documents/cross-gcc
cd ./home/user/Documents/cross-gcc
ln -s ../../../../../aarch64-linux-gnu aarch64-linux-gnu
我们建立了两个符号链接:到-linux-gnu,以及到上层同名的-linux-gnu 符号链接。 请注意,ln -s 在建立符号链接时必须使用相对路径。
还有这个gcc:
../configure --prefix=/home/user/Documents/cross-gcc/ --with-sysroot=/home/user/Documents/cross-gcc/sysroot/ --with-native-system-header-dir=/include/ --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib
成功!
tar -Jcvf cross-gcc.tar.xz cross-gcc
生成的cross-gcc.tar.xz附在文末。
最后完整流程描述如下:
1、下载以下源码包到/home/user//:
/pub/linux//v5.x/linux-5.10.tar.xz
/gnu//-2.34.tar.xz
/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.xz
/gnu/glibc/glibc-2.31.tar.xz
去掉最后的文件名,上面的链接就可以浏览了。
可以使用以下命令查看机器上需要的gcc、gcc和glibc的版本号:
uname -a
ld --version
gcc --version
ldd --version
2.安装必要的工具
sudo apt install make gcc g++ libgmp-dev libmpfr-dev libmpc-dev gawk bison texinfo
3.创建目录并调整环境变量
cd /home/user/Documents/
mkdir cross-gcc
export PATH=/home/user/Documents/cross-gcc/bin:$PATH
4.安装内核头文件
tar -Jxf linux-5.10.tar.xz
cd linux-5.10/
make ARCH=arm64 INSTALL_HDR_PATH=/home/user/Documents/cross-gcc/aarch64-linux-gnu headers_install
cd ..
5.安装(组装机、连接器等)
tar -Jxf binutils-2.34.tar.xz
cd binutils-2.34/
mkdir build
cd build/
../configure --prefix=/home/user/Documents/cross-gcc/ --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --disable-multilib
make -j 4
make install
cd ..
cd ..
6.创建目录结构并建立符号链接
cd cross-gcc/
ln -s aarch64-linux-gnu sysroot
cd sysroot
mkdir -p ./home/user/Documents/cross-gcc
cd ./home/user/Documents/cross-gcc
ln -s ../../../../../aarch64-linux-gnu aarch64-linux-gnu
cd /home/user/Documents/
7. 第一次海湾合作委员会
tar -Jxf gcc-9.3.0.tar.xz
cd gcc-9.3.0/
mkdir build
cd build/
../configure --prefix=/home/user/Documents/cross-gcc/ --with-sysroot=/home/user/Documents/cross-gcc/sysroot/ --with-native-system-header-dir=/include/ --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib
make -j 4 all-gcc
make install-gcc
cd ..
cd ..
8. 第一次使用glibc
tar -Jxf glibc-2.31.tar.xz
cd glibc-2.31/
mkdir build
cd build/
../configure --prefix=/home/user/Documents/cross-gcc/aarch64-linux-gnu/ --build=x86_64-linux-gnu --host=aarch64-linux-gnu --with-headers=/home/user/Documents/cross-gcc/aarch64-linux-gnu/include/ --disable-multilib libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make -j 4 csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /home/user/Documents/cross-gcc/aarch64-linux-gnu/lib/
aarch64-linux-gnu-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /home/user/Documents/cross-gcc/aarch64-linux-gnu/lib/libc.so
touch /home/user/Documents/cross-gcc/aarch64-linux-gnu/include/gnu/stubs.h
cd ..
cd ..
为什么 --host=-linux-gnu 上面提到的有趣的页面已经告诉我们了。
9. 海湾合作委员会第二次
cd gcc-9.3.0/
cd build/
make -j 4 all-target-libgcc
make install-target-libgcc
cd ..
cd ..
10. glibc第二次
cd glibc-2.31/
cd build/
make -j 4
make install
cd ..
cd ..
11.修改gcc源文件
vim /home/user/Documents/gcc-9.3.0/libsanitizer/asan/asan_linux.cc
在第 66 行插入以下三行:
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
12. 海湾合作委员会第三次
cd gcc-9.3.0/
cd build/
make -j 4
make install
cd ..
cd ..
便携式跨平台(cross)编译器:
跨gcc.tar.xz
链接:/s/uAQ 提取码:qb5d
解压到任意路径
tar -Jxvf cross-gcc.tar.xz
然后将交叉编译器路径添加到$PATH中就可以使用了,真正的交叉。