如何从单独的库文件中包含syscalls.c?

时间:2014-09-15 15:05:29

标签: c gcc linker arm system-calls

我的代码包括对_write()_sbrk()等函数的间接调用。在项目中,我有一个名为syscalls.c的文件,它定义了这些函数的自定义实现,编译器/链接器找到了这个文件,并在运行make时正确链接到函数。编译行make看起来像这样:

arm-none-eabi-gcc -nostartfiles -mcpu=arm7tdmi -Wl,--gc-sections -Wl,--cref  -L../hardware_drivers/lib -L../framework/lib -T../linker-script.lds -Wl,-Map,./build/bin/Mapfile.map -o build/bin/Elffile.elf ./build/obj/Main.o ./build/obj/SomeCode.o ./build/obj/syscalls.o -Wl,--start-group -lhardware_drivers -lframework -Wl,--end-group

这完美无缺。但是,我想将syscalls.c移动到我所拥有的hardware_drivers项目中,因此它们应该包含在libharware_drivers.a文件中,该文件在编译hardware_drivers时创建,并包含在上面的gcc行中。移动文件并重新编译我的所有项目确实包含.a文件中的syscalls.c(使用arm-none-eabi-ar显示)。但是,当编译我的顶级项目时,我收到此错误:

../../arm-none-eabi/lib/libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

我正在使用代码源代码中的arm-none-eabi-gcc v4.8,我正在为AT91SAM7A1芯片编译它,如果它有任何相关性的话。

当链接器位于单独的库文件中时,是否需要将链接器指向系统调用?

1 个答案:

答案 0 :(得分:3)

你用,

  1. -nostartfiles
  2. 您在 libhardware_drivers.a中创建了一个_fstat的文件
  3. 您使用_fstat_r调用的代码../../ arm-none-eabi / lib / libc.a(lib_a-fstatr.o)
  4. 以下是错误消息

      

    ../../ arm-none-eabi / lib / libc.a(lib_a-fstatr.o):在函数'_fstat_r'中:   fstatr.c :(。text._fstat_r + 0x1c):对'_fstat'的未定义引用

    您可以尝试使用地图文件或_fstat_r-nodefaultlibs查找使用-nostdlibs的代码。问题是库是按照从头到尾的顺序解决的。您的链接器列表末尾有一个隐式-lc。如果您打算使用'C'库,那么您必须在链接后面更改链接器命令以定位 libhardware_drivers.a

    例如,

    arm-none-eabi-gcc -nostartfiles -mcpu=arm7tdmi -Wl,--gc-sections -Wl,--cref\
     -L../hardware_drivers/lib -L../framework/lib -T../linker-script.lds \
     -Wl,-Map,./build/bin/Mapfile.map -o build/bin/Elffile.elf ./build/obj/Main.o\
     ./build/obj/SomeCode.o ./build/obj/syscalls.o \
     -Wl,--start-group -lc -lhardware_drivers -lframework -Wl,--end-group
    

    此处, -lc 位于-lhardware_drivers之前。这将让链接器解析 syscall.o 中对_fstat lib_a-fstatr.o 引用。另一种方法是在另一个目标文件(例如 Main.o )中强制某些合成引用。宏可以强制链接,

    #define FORCE_LINK(x) void* __ ## x ## _force_link =(void*)&x
    FORCE_LINK(fstat);
    

    您很可能在静态库中有循环引用。即, hardware_drivers 是指框架是指 libc libc 是指 hardware_drivers 使事情有效。解决此问题的方法是在命令行上多次列出库或重构代码,这可能是更好的长期。

    重组与单独的 libsyscall.a 一样简单,它在-lc之后列出。