每次重编toolchain是很耗时的,因此编译好一次后,将其提取出来,作为外挂toolchain使用。
make menuconfig 配置如下:
--- Use external toolchain
[ ] Use host's toolchain
(arm-openwrt-linux-muslgnueabi) Target name
(arm-openwrt-linux-) Toolchain prefix
(/work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi) Toolchain root
Toolchain libc (musl) --->
(./bin) Toolchain program path
(./include) Toolchain include path
(./lib) Toolchain library path
其中target name是目标的名字,可以通过下面的命令获得:
$ /work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi/bin/arm-openwrt-linux-muslgnueabi-gcc -dumpmachine
arm-openwrt-linux-muslgnueabi
toolchain-prefix是工具的前缀,工具链在bin目录下:
$ ls -l /work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi/bin/
arm-openwrt-linux-ld.bfd -> arm-openwrt-linux-muslgnueabi-ld.bfd
arm-openwrt-linux-muslgnueabi-addr2line
使用这两个都可以。
配置好后编译,但是发现toolchain-prefix使用arm-openwrt-linux-muslgnueabi-时报错,提示符号未定义。
发现是执行toolchain/wrapper,导致openwrt提供了一个wrapper,刚好和工具前缀同名。导出的PATH如下:
PATH=/work/openwrt/openwrt/staging_dir/toolchain-arm-openwrt-linux-muslgnueabi/bin:/work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi/bin:/work/openwrt/openwrt/staging_dir/toolchain-arm-openwrt-linux-muslgnueabi/bin:
刚好使用wrapper里面的工具,wrapper这个工具会-I toolchain里面的include,导致内核使用toolchain里面的头文件。
解决办法是,前缀使用arm-openwrt-linux-,或者修改toolchain/Makefile,不执行wrapper。
$ git diff toolchain/
diff --git a/toolchain/Makefile b/toolchain/Makefile
index 0336b2f72c..30137cfa21 100644
--- a/toolchain/Makefile
+++ b/toolchain/Makefile
@@ -29,7 +29,7 @@
curdir:=toolchain
# subdirectories to descend into
-$(curdir)/builddirs := $(if $(CONFIG_GDB),gdb) $(if $(CONFIG_EXTERNAL_TOOLCHAIN),wrapper,kernel-headers binutils gcc/initial gcc/final $(LIBC) fortify-headers) $(if $(CONFIG_NASM),nasm)
+$(curdir)/builddirs := $(if $(CONFIG_GDB),gdb) $(if $(CONFIG_EXTERNAL_TOOLCHAIN),,kernel-headers binutils gcc/initial gcc/final $(LIBC) fortify-headers) $(if $(CONFIG_NASM),nasm)
ifdef CONFIG_USE_UCLIBC
$(curdir)/builddirs += $(LIBC)/utils
endif
使用arm-openwrt-linux-muslgnueabi-前缀,去掉wrapper,继续编译,发现编译dropbear的时候报错。
出现符号找不到,操作目标文件时出现plugin needed to handle lto object。根据上网的教程,给nm,ar,ranlib添加wrapper解决:
$ cat arm-openwrt-linux-ar
#!/bin/sh
command=$1
shift
arm-openwrt-linux-muslgnueabi-gcc-ar $command --plugin /work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi/libexec/gcc/arm-openwrt-linux-muslgnueabi/7.4.0/liblto_plugin.so $*
$ cat arm-openwrt-linux-nm
#!/bin/sh
arm-openwrt-linux-muslgnueabi-nm --plugin /work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi/libexec/gcc/arm-openwrt-linux-muslgnueabi/7.4.0/liblto_plugin.so $*
$ cat arm-openwrt-linux-ranlib
#!/bin/sh
command=$1
shift
arm-openwrt-linux-muslgnueabi-ranlib $command --plugin /work/toolchain/toolchain-arm_cortex-a7+neon-vfpv4_gcc-7.4.0_musl_eabi/libexec/gcc/arm-openwrt-linux-muslgnueabi/7.4.0/liblto_plugin.so $*
参考:
http://hubicka.blogspot.com/2014/04/linktime-optimization-in-gcc-2-firefox.html