我正在研究ARM微控制器(SAM7)的嵌入式软件并使用Yagarto工具链。
我的代码目前链接libc.a.但是,我想使用我的代码已经具有的内置函数 memcpy 的自定义实现。
我尝试使用GCC Manual中指定的 -fno-builtin和/或-fno-builtin-memcpy ,但链接器仍会抱怨以下警告:
contiki-crazy-horse.a(flashd_efc.o): In function `memcpy':
C:\Users\Melvin\GitRepo\projects\Amatis_Project\SAM7_Contiki\examples\er-rest-example/../../cpu/arm//at91sam7s-x/./flashd_efc.c:669: multiple definition of `memcpy'
c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-memcpy.o):C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\newlib\libc\string/../../../../../newlib-1.19.0/newlib/libc/string/memcpy.c:78: first defined here
collect2: ld returned 1 exit status
make: *** [rest-server-example-nosyms.crazy-horse] Error 1
../../cpu/arm/at91sam7s-x/Makefile.at91sam7s-x:181: recipe for target `rest-server-example-nosyms.crazy-horse' failed
使用某些gcc内置函数的自定义实现的正确方法是什么?
编辑1:添加我正在使用的链接命令。在下面的代码中,Porject.a是一个使用所有项目的目标文件创建的存档文件。
CC = arm-none-eabi-gcc
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
-I$(CONTIKI_CPU)/dbg-io \
-I$(CONTIKI)/platform/$(TARGET) \
${addprefix -I,$(APPDIRS)} \
-DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \
-Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET)
CFLAGS += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN -ffunction-sections
LDFLAGS += -L $(CONTIKI_CPU) --verbose -T $(LINKERSCRIPT) -nostartfiles -Wl,-Map,$(TARGET).map
$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o project.elf -lc Project.a
答案 0 :(得分:3)
如果它在libc.a中找到memcpy()
,那么它与任何“内置”都没有冲突,而是与newlib实现冲突。您可能还需要指定-nostdlibs选项并根据需要显式链接libc.a和libm.a。
在搜索库归档(.a)文件之前链接对象(.o)文件,因此如果符号由目标文件解析,则不会在归档中搜索它。如果将覆盖放在静态链接库中,则只需在链接器命令行上将其列在标准库(或使用标准库的任何其他库)之前。
[已添加] 以下原本是“评论”,但应该在答案中;它是对问题中“编辑1”的回应,以及下面关于链接顺序的评论:
将-nostartfiles -o project.elf -lc Project.a
更改为-nostdlib -o project.elf -start-group Project.a -lc -end-group
。交换机-nostdlib
禁用两个启动文件(即-nostartfiles
)和标准库的默认链接。库分组导致组中的库被迭代搜索,直到无法解析其他符号,从而允许解决与您无关的无序和循环依赖关系。分组开关的另一种形式是-( Project.a -lc -)
。