2012-03-26 36 views
5

我正在研究用于ARM微控制器(SAM7)的嵌入式软件并使用Yagarto工具链。如何强制gcc使用newlibc实现函数的自定义实现?

我的代码当前链接libc.a.不过,我想使用我的代码已有的内置函数memcpy的自定义实现。

我一直在使用-fno-内置和/或-fno-内置-的memcpy作为GCC Manual规定,但仍连接器会抱怨以下警告尝试:

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

还包括生成此错误的链接器命令行。 – Clifford 2012-03-26 18:45:14

+0

@Clifford我编辑了原文,添加了您请求的信息 – maguirre 2012-03-27 15:21:31

回答

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 -)

+0

@Cliford。我的错。你是对的有没有办法选择我想要我的代码链接的memcpy的哪个实现? 我无法切换Project.a和libc.a之间的链接顺序,因为我的项目有一些存根函数,libc.a需要 – maguirre 2012-03-27 15:25:54

+2

@Mischief:或者,将newlib存根与项目文件'Project.a -lc stub分离.a'。为项目文件使用存档是一件不寻常的事情;你可以通过直接链接目标文件来避免这个问题。无论链接顺序如何,对象文件中的代码将始终优先于库代码使用;因此libc存根将由与链接匹配符号的任何目标代码解析,并且任何目标代码将在库代码之前从其他目标代码解析,因此即使对于libc内的调用,memcpy()也将被正确覆盖。 – Clifford 2012-03-27 20:04:52

+0

我同意你对你的评论有关在档案中的代码是不寻常的。如果/当我有我的方式,它将被改变 – maguirre 2012-03-27 20:33:43