您的位置  > 互联网

交叉编译器的参数控制和使用方法——gcc

回到电脑上试试。我用的交叉编译器是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中就可以使用了,真正的交叉。