我有一个大型项目,其中包含构建所有内容的自定义 Makefile。这是针对 ARM Cortex-M0 的。
其中一个步骤是将 Newlib 编译syscalls.c
成syscalls.c.o
. 这被转储到一个存档文件newlib.a
中,该文件又链接到最终output.elf
加载到我设备的闪存上。
$ arm-none-eabi-gcc -o output.elf .bld/*.c.o .bld/*.cpp.o .bld/libs/*.a -nostartfiles -mcpu=cortex-m0 -mthumb -Tlinker.ld -Wl,-Map=output.map --specs=nano.specs
如果我按照上述程序,有时“存档没有索引”:
.bld/libs/newlib.a: error adding symbols: Archive has no index; run ranlib to add one
有时(我还没有弄清楚如何确定性地使其中一种发生)我得到一个未定义的引用,即使_init()
在syscalls.c
.
c:/progra~2/gnutoo~1/50a5a~1.420/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv6-m\libc_nano.a(lib_a-init.o): In function `__libc_init_array':
init.c:(.text.__libc_init_array+0x1c): undefined reference to `_init'
但是,如果我跳过newlib.a
文件并直接链接syscalls.c.o
到 final .elf
,它会按预期工作。
使用存档可能会导致此问题怎么办?我也尝试重新排序链接器的参数无济于事。
注意(编辑)
我确实注意到了run ranlib to add one
指示。但是,这并不适用,因为:
- 这在我正在构建的其他档案中不是必需的,为什么这里需要它?
- 该错误不再发生(经过一番摆弄。不确定发生了什么变化)。主要问题是
_init
未定义。
参考
我正在编译此版本中的其他存档文件,没有任何问题。这里的独特之处在于该存档中只有一个文件,并且它是唯一的仅 C 存档。但是,我不明白这会如何影响事情。
这基本上是我编译
syscalls.c
和归档.o
文件的方式:$ arm-none-eabi-gcc newlib/syscalls.c -o .bld/newlib/syscalls.c.o -c -std=gnu11 -Wstrict-prototypes -nostartfiles -mcpu=cortex-m0 -mthumb -O2 -pipe -ffreestanding -funsigned-bitfields -Wall -Wfatal-errors -ffunction-sections -fdata-sections -MMD -MP -MF .bld/.dep/newlib/syscalls.c.o.d $ arm-none-eabi-ar rcs .bld/libs/newlib.a .bld/newlib/syscalls.c.o
gcc
版本arm-none-eabi-g++ (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]
简化
syscalls.c
caddr_t _sbrk(int nbytes) __attribute__((externally_visible)); void _init(void) __attribute__((externally_visible)); /* c++ destructor dynamic shared object needed if -fuse-cxa-atexit is used*/ void *__dso_handle __attribute__ ((weak)); // defined in linker script extern caddr_t Heap_Bank1_Start; extern caddr_t Heap_Bank1_End; caddr_t _sbrk(int nbytes) { /* ... */ } void _init(void) {}