【发布时间】:2017-02-17 22:00:15
【问题描述】:
我正在开发一个嵌入式项目,并且正在复制一个示例项目。
不考虑目标文件的链接顺序,我只是将c文件以随机顺序放在我的Makefile中。
编译和链接会产生 executable.elf 或 1.9Mb。
没有生成错误,但可执行文件不起作用。
在没有解决方案的长时间搜索之后,我终于完全复制了该项目,包括 c 文件的顺序(其中 120 个),看我得到了 2.2Mb 的 executable.elf 并且没有错误。并且可执行文件有效。
编译选项和/或链接选项没有任何变化。只是更改了 c 文件在 makefile 中列出的顺序,因此也更改了链接时目标文件的顺序。
我怀疑有多个具有不同主体/大小的重复函数实现。我的假设是链接器在链接时不记得以前的链接操作,只会选择它遇到的第一个操作而不会引发错误。
但是我想保留这个提供的库(所有单个 c 文件,没有库 *.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 中文件的顺序
【问题讨论】:
-
我知道您说过您不能发布代码本身,但您可以发布与您的
Makefile相同的混淆代码吗?谢谢!事实上,我们甚至不知道您的Makefile的结构是什么,或者您使用什么构建系统来生成它(如果有的话)。这可能会让您更难为您提供明确的答案。 -
你说'我的假设是......链接器......只是选择它遇到的第一个而不引发错误'。那将是非常不寻常的,也是错误的。如果有两个目标文件定义了相同的外部可见函数,则链接应该会失败并出现重复的函数错误。最简单的模拟方法是将一个目标文件添加到列表中两次;当你这样做时,链接应该会失败。你检查过目标文件的大小吗?您是否比较了两个二进制文件的
size输出?编译选项是否相同?编译器版本? -
我刚刚在我的应用程序中添加了一个任意库
c文件并编译/链接了它。所以有两个相同的目标文件具有不同的位置。链接器没有错误。 -
刚刚在原始问题中添加了我的
Makefiles的简单版本。 -
我的假设是基于我读到的here 在类 Unix 系统上,编译器和链接器的传统行为是在命令指定的目标文件中从左到右搜索外部函数行。