c++ - 对已编译对象使用存档文件似乎会破坏编译

标签 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

如果我按照上面的步骤,有时会出现“Archive has no index”:

.bld/libs/newlib.a: error adding symbols: Archive has no index; run ranlib to add one

有时(我还没有弄清楚如何确定性地使一个或另一个发生)我得到一个 undefined reference ,即使 _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未定义。

引用

  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) {}
    

最佳答案

希望这个提示可以帮到你:https://github.com/ap4y/modbus.js/issues/1

Hi, you have this error because static library (libmodbus.a) have been precompiled for other platform. Actually, it my mistake to leave it in repository. In order to resolve this error you should compile library for your platform and replace it in lib directory.

关于c++ - 对已编译对象使用存档文件似乎会破坏编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44424165/

相关文章:

c - Fortran 派生类型包含可从 C 访问的指针

linux - 在 Linux Mint LMDE 2 中安装 GCC5

c++ - 如何创建一个使用开源 C 项目的 C++ 控制台应用程序

c++ - Visual Studio 中 Opencv 的介绍性示例程序以代码 -1 退出。没有理由

c++ - 系统托盘上下文菜单不会消失

c++ - 正确生成随机指数值c++

c - *(x+4) 和 (x+4) 之间的差异

c - GetObject 在文本光标上失败

c++ - Valgrind 无法识别的指令

c++ - 错误 : 'log2' is not a member of 'std'