我正在开发一个嵌入式项目,我正在复制一个示例项目。
我没有考虑目标文件的链接顺序,只是将c
文件以随机顺序放在我的Makefile
中。
编译和关联会产生executable.elf
1.9Mb
。
没有生成错误,但可执行文件不起作用。
在没有解决方案的长时间搜索之后,我最终完全复制了项目,包括c
文件(其中120个)的顺序,并且我得到了executable.elf
2.2Mb
和没有错误。和可执行文件工作。
在编译选项和/或链接选项中没有任何变化。刚刚更改了生成文件中列出c
文件的顺序,因此更改了链接时目标文件的顺序。
我怀疑有多个具有不同主体/大小的重复功能实现。我的假设是链接器的链接时间,没有先前链接操作的记忆,只选择它遇到的第一个而不引发错误。
但是,我想暂停这个提供的库(所有单个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中文件的顺序
答案 0 :(得分:1)
只有静态库(.a或.lib)表现出“首次匹配解析”,因此链接顺序至关重要。由于所有目标文件都是显式链接的,因此如果存在重复的符号,则会出现链接错误。因此,只有.a / .lib文件呈现给链接器的顺序才会产生这种效果。
也许你有两个不同版本的库,并以不同的顺序链接它们?
GNU工具链的binutils包括nm工具,用于检查对象和存档(库)文件中的符号。
另一种可能性是可执行入口点对您平台上的链接顺序敏感;在这种情况下,它可能只是crt0(或其他运行时启动代码)的链接顺序。