我正在处理一个嵌入式项目,并且正在复制一个示例项目。
不考虑目标文件的链接顺序,我只是将 c
文件以随机顺序放入我的 Makefile
中。
编译和链接生成 1.9Mb
的 executable.elf
。
未生成任何错误,但可执行文件无法运行。
经过长时间的搜索没有找到解决方案,我终于完全复制了项目,包括 c
文件的顺序(其中 120 个),看哪,我得到了一个 executable.elf
2.2Mb
并且没有错误。并且可执行文件有效。
编译选项和/或链接选项没有任何变化。刚刚更改了 c
文件在 makefile 中列出的顺序,因此更改了链接时目标文件的顺序。
我怀疑存在多个具有不同主体/大小的重复函数实现。我的假设是,链接器的链接时间没有以前链接操作的内存,只是选择它遇到的第一个链接操作而不会引发错误。
但是我想保留这个提供的库(所有单个 c
文件,没有 lib *.a
文件)并找到重复的函数实现。所以我知道我应该以什么顺序提供 c 文件,更重要的是,我知道为什么。
两个问题:
- 以上描述是否确实是问题的潜在原因?
- 还有其他可能性吗?
- 如何找到重复的函数实现?
很遗憾,正在编译的代码是专有的,此时无法共享详细信息。
编译器是:
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]
目标是:
cortex-m3
感谢您的帮助。
--- 编辑 ---
有两个文件:
是包含所有源代码的列表(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
是
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 $@
在 Makefile
中,我没有做任何更改。只改变了source.mk中的文件顺序
最佳答案
只有静态库(.a 或 .lib)表现出“首次匹配解析”,因此链接顺序很关键。由于所有 目标文件都是显式链接的,如果有重复的符号,您会收到链接错误。因此,只有将 .a/.lib 文件呈现给链接器的顺序才能产生这种效果。
也许您有两个不同版本的库,并且以不同的顺序链接它们?
GNU 工具链的 binutils 包括 nm用于检查目标文件和存档(库)文件中的符号的工具。
另一种可能性是可执行入口点对您平台上的链接顺序敏感;在这种情况下,它可能只是 crt0(或其他运行时启动代码)的链接顺序。
关于c - 在 c 库中查找重复声明的函数(单个文件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42308135/