在c库中查找重复声明的函数(单个文件)

时间:2017-02-17 22:00:16

标签: c gcc linker embedded

我正在开发一个嵌入式项目,我正在复制一个示例项目。 我没有考虑目标文件的链接顺序,只是将c文件以随机顺序放在我的Makefile中。

编译和关联会产生executable.elf 1.9Mb。 没有生成错误,但可执行文件不起作用。

在没有解决方案的长时间搜索之后,我最终完全复制了项目,包括c文件(其中120个)的顺序,并且我得到了executable.elf 2.2Mb和没有错误。和可执行文件工作。

在编译选项和/或链接选项中没有任何变化。刚刚更改了生成文件中列出c文件的顺序,因此更改了链接时目标文件的顺序。

我怀疑有多个具有不同主体/大小的重复功能实现。我的假设是链接器的链接时间,没有先前链接操作的记忆,只选择它遇到的第一个而不引发错误。

但是,我想暂停这个提供的库(所有单个c文件,没有lib *.a文件)并找到重复的函数实现。所以我知道我应该以哪种顺序提供c文件,更重要的是,为什么。

两个问题:

  1. 上述说明确实是问题的潜在原因吗?
  2. 还有其他可能吗?
  3. 如何找到重复的函数实现?
  4. 不幸的是,正在编译的代码是专有的,目前无法共享详细信息。

    编译器是:

     arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]
    

    目标是:

     cortex-m3
    

    感谢您的帮助。

    ---编辑---

    有两个文件:

    1. 是包含所有源代码的列表(source.mk):

       C_FILES_SRC  = $(SDK_DIR)/file001.c
       C_FILES_SRC += $(SDK_DIR)/file002.c
       C_FILES_SRC += $(SDK_DIR)/ .....
           |
       C_FILES_SRC += $(APPL_DIR)/file121.c
       C_FILES_SRC += $(APPL_DIR)/file122.c
      
    2. Makefile(简短版):

      include source.mk
      CFLAGS = xxxxx
      # create objects
      %.o: %.c
          $(GCC) $(CFLAGS) -MMD -MP -MF($(@:%.o=%.d) -o $@ -c $<
      
      # link it all together
      executable.elf
          $(GCC) $(MAIN_CFLAGS) $(LINK_SCRIPTS) -Xlinker --gc-sections $(LIBS_DIR) $(EXTRA_LINK_FLAGS) $(SPECS) -o $@ $(OBJS) $(LIBS)
          $(SIZE) --format=berkeley $@
      
    3. Makefile中,我什么都没改变。仅更改了source.mk中文件的顺序

1 个答案:

答案 0 :(得分:1)

只有静态库(.a或.lib)表现出“首次匹配解析”,因此链接顺序至关重要。由于所有目标文件都是显式链接的,因此如果存在重复的符号,则会出现链接错误。因此,只有.a / .lib文件呈现给链接器的顺序才会产生这种效果。

也许你有两个不同版本的库,并以不同的顺序链接它们?

GNU工具链的binutils包括nm工具,用于检查对象和存档(库)文件中的符号。

另一种可能性是可执行入口点对您平台上的链接顺序敏感;在这种情况下,它可能只是crt0(或其他运行时启动代码)的链接顺序。