从第3方拿到一包测试code ,预计可以直接编译使用,但是在编译过程中遇到一些问题,记录解决方法。
1.拿到原始code ,make 可以成功编译。
2.换成我的toolchain 后,提示link error.
$ make
LD cdec
/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/../lib/gcc/arm-none-linux-gnueabihf/9.2.1/../../../../arm-none-linux-gnueabihf/bin/ld: error: cdec uses VFP register arguments, utils.o does not
/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/../lib/gcc/arm-none-linux-gnueabihf/9.2.1/../../../../arm-none-linux-gnueabihf/bin/ld: failed to merge target specific data of file utils.o
/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/../lib/gcc/arm-none-linux-gnueabihf/9.2.1/../../../../arm-none-linux-gnueabihf/bin/ld: error: cdec uses VFP register arguments, compress.o does not
/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/../lib/gcc/arm-none-linux-gnueabihf/9.2.1/../../../../arm-none-linux-gnueabihf/bin/ld: failed to merge target specific data of file compress.o
collect2: error: ld returned 1 exit status
makefile:46: recipe for target 'cdec' failed
make: *** [cdec] Error 1
查了一些资料,也没有解决我的问题,因此就在想是否没有clean 导致问题?
3.因此,尝试make clean, 但是 又遇到了找不到rm 命令。
$ make clean
clean
make: rm: Command not found
makefile:62: recipe for target 'clean' failed
make: *** [clean] Error 127
console 下,可以成功使用rm 命令。
因此在想是否没有包含到rm 的PATH 呢?
$ whereis rm
rm: /usr/bin/rm /bin/rm /usr/share/man/man1/rm.1.gz
猜测是PATH 中没有加上述path.
查看makefile 并且打印出PATH 变量
export PATH=/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/:$PATH
......
@echo "PATH is $(PATH) "
......
最终打印出来的是:
PATH is /opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/:ATH
从上述打印信息看,确实没有rm 的path.
因此在makefile 中加入rm 的path
export PATH=/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/:$PATH
export PATH=/usr/bin:$PATH
加入path 后,可以成功使用rm 命令了,make clean 也成功了。
4.make clean 后,执行make , 没想到gcc 命令 又不见了。。。
$ make
PATH is /usr/bin:ATH
CC cplay.c
make: arm-none-linux-gnueabihf-gcc: Command not found
makefile:57: recipe for target 'cplay.o' failed
make: *** [cplay.o] Error 127
明明刚刚还能找到gcc 命令呢?怎么现在就not found?
难道PATH 又出什么问题?
新打印出的PATH 变量确实变了,没有gcc 所在的path 了。
PATH is /usr/bin:ATH
那目前看来只能是第2个 export PATH 把第1个export PATH 覆盖了
export PATH=/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/:$PATH
export PATH=/usr/bin:$PATH记得sh 脚本的时候,可以多次这样使用的,并且会把各个path 都加到PATH 环境变量呢/
疑问暂是保留。
最终给makefile 为:
export PATH=/opt/compiler_tool/arm/gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf/bin/:/usr/bin:$PATH
终于既可以make 也 可以make clean 了。
make clean 成功后,也不会报“cdec uses VFP register arguments, utils.o does not” 的问题了。
结论:在换了toolchain 后,没有clean *.o (armv7l-tizen-linux-gnueabi 编译生成), 只是手动删除了cdec 就执行make ,因此会导致生成cdec link 时候使用的toolchain (gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf) 和 编译*.o 使用的toolchain 不一样,从而导致上述问题。
另外又做了一个测试,
*.o 编译使用的toolchain 是gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf
但是cdec link 的时候使用armv7l-tizen-linux-gnueabi, 同样也会报下面的这个error。
$ make
LD cdec
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: error: cdec.o uses VFP register arguments, cdec does not
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: failed to merge target specific data of file cdec.o
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: error: utils.o uses VFP register arguments, cdec does not
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: failed to merge target specific data of file utils.o
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: error: compress.o uses VFP register arguments, cdec does not
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: failed to merge target specific data of file compress.o
collect2: error: ld returned 1 exit status
makefile:46: recipe for target 'cdec' failed
make: *** [cdec] Error 1
5.上述Error 出现的原理是什么?
gcc-linaro-9.2.1-20220411-x86_64_arm-none-linux-gnueabihf 这个toolchain 包含VFP(Virtual Floating Point Register)
但是armv7l-tizen-linux-gnueabi 不包含VFP(Virtual Floating Point Register)
因此,导致上述问题。
link 的时候,加上-mfloat-abi=softfp,link 时候使用soft float point,看看是否能让link 能成功?
LDFLAGS += -L. -mfloat-abi=softfp
又报了另一个error
$ make LD cdec /opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/bin/../lib/gcc/armv7l-tizen-linux-gnueabi/4.9.2/../../../../armv7l-tizen-linux-gnueabi/bin/ld: cannot find /lib/ld-linux.so.3: No such file or directory collect2: error: ld returned 1 exit status makefile:48: recipe for target 'cdec' failed make: *** [cdec] Error 1
/opt/compiler_tool/arm/armv7l-tizen-linux-gnueabi/lib$ ls gcc libarmv7l-tizen-linux-gnueabi-sim.a
因此这种方法不成功。
6.reference
gcc - ARM compilation error, VFP registers used by executable, not object file - Stack Overflow