0

我实现了一个 retarget.c 将 printf 输出重定向到串行端口进行调试,它可以被链接并且工作得很好,如果我的链接命令喜欢这样:

arm-none-eabi-gcc --specs=nano.specs --specs=nosys.specs -g -mcpu=cortex-m4 -mthumb -fmessage-length=0 -std=c99 -fno-builtin -Wl,--gc-sections -Wl,-Map=main.map -T"$(LINKERFILE)" -o main.elf main.o retarget.o $(BUILDDIR)/libs.a -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

但是当我归档retarget.o到归档文件$(BUILDDIR)/libs.a中时,链接命令喜欢这个:

arm-none-eabi-gcc --specs=nano.specs --specs=nosys.specs -g -mcpu=cortex-m4 -mthumb -fmessage-length=0 -std=c99 -fno-builtin -Wl,--gc-sections -Wl,-Map=main.map -T"$(LINKERFILE)" -o main.elf main.o $(BUILDDIR)/libs.a -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group

可以链接成功,但是函数printf并没有向串口输出任何东西,看来我自己的版本函数,比如_writeretarget.c中的函数,在最终编译的程序中并没有用到。

4

1 回答 1

0

因为_write已经在 中定义libnosys.a,包括通过--specs=nosys.specs

注意:以下调查是使用从此处下载的 ARM 工具链 9-2019-q4-major 完成的。

这需要对规范文件有基本的了解(关于规范文件)

编译器的内置规范可以用arm-none-eabi-gcc -dumpspecs ( gcc -dumpspecs)查看

--specs=nosys.specs在命令行开头传递a-lnosys在对 的调用中插入ld。(使用 ARM GCC 时,“nosys”、“nano”、“rdimon” 术语是什么?

arm-none-eabi-objdump -t arm-none-eabi/lib/libnosys.a | grep _write找到_write(...)可能覆盖您在其中定义的那个$(BUILDDIR)/libs.a

我也很好奇为什么.a文件.o在调用gcc. 为什么似乎存在于设计中gccld并且仍然让我无法理解。

使用_write静态库中定义的符号libs.a

-Wl,--undefined=_write在最终链接期间调用 gcc 。
(通过这个答案)。From man ld--undefined=symbol强制符号作为未定义符号输入到输出文件中。

另请参阅 Makani 固件存储库,其中实现系统调用的静态库将它们标记为--undefined链接器选项的生成)

于 2021-07-06T03:44:56.227 回答