I am working on embedded software for a ARM microcontroller (SAM7) and using Yagarto toolchain.
My code currently links libc.a. However I'd like to use a custom implementation of the builtin function memcpy that my code already has.
I have tried using -fno-builtin and/or -fno-builtin-memcpy as specified in the GCC Manual but the linker still complains will the following warning:
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
What is the correct way to use custom implementations of certain gcc built-in functions?
Edit 1: Adding the linking command I am using. In the code below Porject.a is an archive file created with all the project's object files.
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
Newlib is included in commercial GCC distributions by Atollic, CodeSourcery, Code Red, KPIT, Red Hat and others, and receives support from major embedded-processor architecture vendors such as ARM and Renesas.
Newlib is a complete C library implementation written for the embedded systems. It is a separate open source project and is not included in source code form with Zephyr. Instead, the Zephyr SDK includes a precompiled library for each supported architecture ( libc.
The newlib-nano is an open source C library (libc) targeting embedded microcontrollers (MCU). Implementation focus is on code and data size reduction through optimization and removal of non-MCU features.
If it is finding memcpy()
in libc.a, then it is not conflicting with any "built-in", but rather with the newlib implementation. You may need also to specify -nostdlibs option and explicitly link libc.a and libm.a as necessary.
Object (.o) files are linked before library archives (.a) files are searched, so if a symbol is resolved by an object file, it will not be searched for in the archives. If you place your overrides in an static-link library, then you simply list it ahead of the standard library (or any other libraries that use the standard library) on the linker command line.
[Added] The following was originally a "comment" but should probably be in the answer; it is in response to "Edit 1" in the question, and the comment below about link order:
Change -nostartfiles -o project.elf -lc Project.a
to -nostdlib -o project.elf -start-group Project.a -lc -end-group
. The switch -nostdlib
disables default linking of both start-up files (i.e. -nostartfiles
) and standard libraries. The library grouping causes the libraries in the group to be searched iteratively until no further symbols can be resolved, allowing out-of-order and circular dependencies like yours to be resolved. An alternative form for the grouping switches is -( Project.a -lc -)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With