2012-03-26 9 views
5

Pracuję nad oprogramowaniem embedded dla mikrokontrolera ARM (SAM7) i przy użyciu Yagarto toolchain.Jak zmusić gcc do korzystania z niestandardowych implementacji zaimplementowanych funkcji newlibc?

Mój kod aktualnie łączy się z libc.a. Jednak chciałbym użyć niestandardowej implementacji wbudowanej funkcji, którą mój kod już posiada.

Próbowałem, używając -fno-wbudowane i/lub -fno-wbudowane-memcpy jak określono w GCC Manual ale wciąż narzeka łącznik będzie następujące ostrzeżenie:

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 

Co to jest poprawny sposób używać niestandardowych implementacji niektórych wbudowanych funkcji gcc?

Edytuj 1: Dodanie polecenia łączenia, którego używam. W poniższym kodzie Porject.a jest plikiem archiwum utworzonym ze wszystkich plików obiektów projektu.

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

Należy również podać wiersz polecenia linku, który wygenerował ten błąd. – Clifford

+0

@ Clifford Edytowałem oryginalny wpis, aby dodać informacje, o które prosiłeś: – maguirre

Odpowiedz

3

Jeśli jest znalezienie memcpy() w libc.a, to nie jest sprzeczne z jakimkolwiek "Built-In", ale raczej z realizacją newlib. Konieczne może być również podanie opcji -nostdlibs i, w razie potrzeby, jawne połączenie libc.a i libm.a.

Pliki obiektów (.o) są łączone przed przeszukaniem plików archiwów biblioteki (.a), więc jeśli symbol zostanie rozpoznany przez plik obiektowy, nie będzie on wyszukiwany w archiwach. Jeśli umieścisz przesłonięcia w bibliotece łącza statycznego, po prostu wypisz ją przed biblioteką standardową (lub dowolnymi innymi bibliotekami korzystającymi z biblioteki standardowej) w wierszu komend linkera.

[Nowość]Poniższa był pierwotnie „komentarz”, ale należy prawdopodobnie w odpowiedzi; jest to odpowiedź na "Edytuj 1" w pytaniu, a poniżej komentarz dotyczący kolejności linków:

Zmień -nostartfiles -o project.elf -lc Project.a na -nostdlib -o project.elf -start-group Project.a -lc -end-group. Przełącznik -nostdlib wyłącza domyślne połączenie obu plików startowych (tj. -nostartfiles) i standardowych bibliotek. Grupowanie bibliotek powoduje, że biblioteki w grupie są wyszukiwane iteracyjnie, aż do momentu, gdy nie można już rozpoznać kolejnych symboli, umożliwiając rozwiązanie zależnych od siebie i cyklicznych zależności, takich jak twoje. Alternatywną formą przełączników grupowania jest -(Project.a -lc -).

+0

@Cliford. Mój błąd. Masz rację Czy istnieje sposób, aby wybrać, która implementacja memcpy ma być łączona przez mój kod? Nie mogę zmienić kolejności łączenia między Project.a a biblioteką libc.a, ponieważ mój projekt ma pewne funkcje pośredniczące, które libc.a potrzebuje – maguirre

+2

@Mischief: Alternatywnie, oddzielaj swoje prefiksy newlib od swoich plików projektu 'Project.a -lc stubs .a'. Używanie archiwum do plików projektu jest rzeczą niezwykłą; możesz całkowicie uniknąć problemu, łącząc pliki obiektów bezpośrednio, tak jak jest to normą. Kod w plikach obiektowych będzie zawsze używany zamiast kodu biblioteki niezależnie od kolejki linków; więc kody pośredniczące libc będą rozwiązywane przez dowolny kod obiektowy, który łączysz z pasującymi symbolami, a każdy kod obiektowy zostanie rozwiązany przed innym kodem obiektu przed kodem biblioteki, więc memcpy() będzie poprawnie nadpisany nawet w przypadku wywołań wewnątrz libc. – Clifford

+0

Zgadzam się z Tobą w związku z twoją uwagą o tym, że kod w archiwum jest nietypowy. Jeśli/kiedy będę miał swoją drogę, to się zmieni – maguirre

Powiązane problemy