[AVR-GCC] Linker nie znajduje bibliotek

Jun 12, 2007 8 Replies

Próbuję uruchomić projekt oparty o Ethernut.



Wszystko sie kompiluje poprawnie. Mam problem z linkerem.



Robię tak:



avr-g++ -Wl,--defsym=main=0,-Map=main.map,--cref -L /home/daniel/nut/lib -lnutarch -lnutcpp -lnutcrt -lnutcrtf -lnutdev -lnutfs -lnutnet



-lnutos -lnutpro -o prog-test.elf ./prog-test.o



na co gcc odpowiada: /prog-test.o(.text+0x70): In function `_cxx_main_()': : undefined reference to `devUsartAvr0' ./prog-test.o(.text+0x72): In function `_cxx_main_()': : undefined reference to `devUsartAvr0' ./prog-test.o(.text+0x74): In function `_cxx_main_()': : undefined reference to `NutRegisterDevice' ./prog-test.o(.text+0x80): In function `_cxx_main_()': : undefined reference to `fopen' ./prog-test.o(.text+0x86): In function `_cxx_main_()': : undefined reference to `_fileno' ./prog-test.o(.text+0x94): In function `_cxx_main_()': : undefined reference to `_ioctl' ./prog-test.o(.text+0x98): In function `_cxx_main_()': : undefined reference to `NutVersionString'


A wiem że w dołączanych bibliotekach są te funkcje. np. $ avr-objdump -x ~/nut/lib/libnutarch.a | grep devUsartAvr



00000000 g O .data 00000023 devUsartAvr0
00000000 g O .data 00000023 devUsartAvr1


Co robię źle?



Pozdrawiam!


Daniel Jaworski wrote: Mała aktualizacja.

Po usunięciu wszystkich plików wynikowych i ponownym przekompilowaniu projektu mam coś takiego:

$avr-g++ -L/home/daniel/nut/lib/ -L/home/daniel/nut/lib/nutinit.o

-mmcu=atmega128 -Wl,--defsym=main=0,-Map=main.map,--cref -oprog-test.elf ./prog-test.o -lnutarch -lnutcpp -lnutcrt -lnutdev -lnutfs -lnutnet

-lnutos -lnutpro

/home/daniel/nut/lib//libnutos.a(thread.o)(.text+0x190): In function `NutThreadResume': : undefined reference to `NutThreadSwitch' /home/daniel/nut/lib//libnutos.a(thread.o)(.text+0x2bc): In function `NutThreadSetPriority': : undefined reference to `NutThreadSwitch'

Ale jest to dalej dziwne, ponieważ funkcja NutThreadSwitch jest zaimplementowana w libnutarch.a: $ avr-objdump -x ~/nut/lib/libnutarch.a | grep NutThreadSwitch

00000010 g F .text 0000007e NutThreadSwitch

Thus wrote Daniel Jaworski <danielj_no snipped-for-privacy@poczta.fm:

Kolejność bibliotek ma znaczenie.

Paweł

Paweł Więcek wrote: [...]

Dziękuję za informację. O to chodziło. Powinni to napisać wielkimi literami na stronie podręcznika do GCC ;-).

Daniel Jaworski pisze:

Najprościej jest dołączać wszystkie biblioteki dwukrotnie (najpierw wymienić w liście cały zestaw a później jeszcze raz to samo), potem nie ma już problemu kolejności.

Thus wrote Adam Dybkowski snipped-for-privacy@45wp.pl:

Najprościej jest albo przemyśleć kolejność, albo użyć -Wl,-( i -Wl,-). Z tym ostatnim trzeba wszakże uważać, bo jeśli pozostaną jakieś nierozwiązane symbole to będzie kuku. A podwójne dołączenie bibliotek nie gwarantuje sukcesu.

Paweł

Thus wrote Daniel Jaworski <danielj_no snipped-for-privacy@poczta.fm:

No przecież jest napisane:

|| `-lLIBRARY' || `-l LIBRARY' || Search the library named LIBRARY when linking. (The second || alternative with the library as a separate argument is only for || POSIX compliance and is not recommended.) || || It makes a difference where in the command you write this option; || the linker searches and processes libraries and object files in || the order they are specified. Thus, `foo.o -lz bar.o' searches || library `z' after file `foo.o' but before `bar.o'. If `bar.o' || refers to functions in `z', those functions may not be loaded. [...]

Paweł

Paweł Więcek pisze:

O przemyśleniu kolejności w niektórych większych projektach zwykle nie ma mowy, bo bibliotek jest wiele a funkcje się skutecznie "zazębiają". Jeszcze się nie naciąłem na sytuację, gdzie niepoprawnie zadziałałoby (lub nie zadziałało) podwójne wypisanie zestawu na liście dla linkera.

Podaj przykład.

Thus wrote Adam Dybkowski snipped-for-privacy@45wp.pl:

To wtedy należałoby mocno przemyśleć architekturę całego projektu, bo pozostawia wiele do życzenia.

Przykład radykalnie uproszczony:

Główny moduł: int main() { foo(); return 0; }

W bibliotece libA.a: void baz() { puts("Ha!\n"); }

W bibliotece libB.a: void bar() { baz(); }

W bibliotece libC.a: void foo() { bar(); }

I Makefile: LIBS=-lA -lB -lC

main: main.o $(CC) -o $@ $^ $(LIBS)

Nie zbuduje się. Dodanie drugi raz $(LIBS) w wywołaniu linkera nie pomoże. Przeorganizowanie listy bibliotek owszem.

Paweł

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required