使用编译对象的存档文件似乎打破了编译

时间:2017-06-07 23:10:18

标签: c++ c gcc5

我有一个大型项目,自定义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链接到最终.elf,那么它会按预期工作。

使用存档会导致此问题吗?我也尝试重新排序链接器的参数无济于事。

注意(编辑)

我注意到了run ranlib to add one指令。但是,这不适用,因为:

  1. 对于我正在构建的其他档案,这不是必需的,为什么需要这里?
  2. 这个错误不再发生了(经过一些摆弄。不确定是什么改变了)。主要问题是_init未定义。
  3. 参考

    1. 我正在编译此版本中的其他存档文件,没有任何问题。这里的独特之处在于,这个存档只有一个文件,它是唯一的C-only存档。但是,我不知道这会如何影响事情。

    2. 这基本上就是我编译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
      
    3. gcc

      arm-none-eabi-g++ (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]
      
    4. 简化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) {}
      

1 个答案:

答案 0 :(得分:0)

希望此提示可以帮助您:https://github.com/ap4y/modbus.js/issues/1

  

嗨,你有这个错误,因为静态库(libmodbus.a)已经存在   预编译为其他平台。实际上,把它留进去是我的错   库。为了解决此错误,您应该编译库   为您的平台并在lib目录中替换它。