Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

AVR Studio 5 problem z linkowaniem biblioteki

Aimeiz 26 Mar 2012 08:12 4556 30
  • #1 26 Mar 2012 08:12
    Aimeiz
    Poziom 15  

    W AVR Studio 5 napisałem i uruchomiłem program na procek atmega 328p.
    To taki dwykanałowy oscyloskopik na wyświetlaczu od Nokia 6100.
    Przeniosłem definicje, makra i procedury obsługi wyświetlacza do oddzielnego projektu PCF8833lib.c. Utworzyłem plik PCF8833lib.h, gdzie umieściłem dyrektywy #define określające stałe, makra, definicje, oraz nagłówki do wszystkich funkcji bibliotecznych.
    Skompilowałem bibliotekę, utworzyły się pliki wynikowe, w tym plik biblioteczny libPCF8833lib.a.

    W programie oscyloskop, dodałem dyrektywę #include "ścisżka\PCF8833lib.h.
    Niestety program oscyloskopu nie chce się skompilować poprawnie.
    Otrzymuję błędy :"undefined reference to 'nazaw funkcji' dla każdej z funkcji bibliotecznych zadeklarowanych w pliku PCF8833lib.h.

    Czyżby linker nie znajdował skompilowanej biblioteki libPCF8833.a ?

    Gdzie umieścić wynikowe pliki biblioteki, aby linker je potrafił znaleźć automatycznie, tak jak znajduje standardowe biblioteki?

    0 29
  • #2 26 Mar 2012 09:50
    tmf
    Moderator Mikrokontrolery Projektowanie

    Linker nigdy automatycznie tego nie znajdzie, bo skąd ma wiedzieć jakie biblioteki potrzebujesz? Musisz mu je wskazać, w tym celu masz stosowne okno konfiguracyjne dla linkera. Swoją drogą to po co tak komplikujesz? Nie prościej po prostu dodać plik PCFcostam.c do projektu i niech się to wszystko razem kompiluje?

    0
  • #3 26 Mar 2012 11:43
    Aimeiz
    Poziom 15  

    Dlaczego komplikuję? Poprostu chcę się tego nauczyć. Jak znajdę gdzieś skompilowaną bibliotekę, która jest dla mnie użyteczna, chcę wiedzieć jak z niej skorzystać.
    Komuś mogę podarować swoją bibliotekę, ale niekoniecznie pokazać jej kod źródłowy.
    Powodów może być wiele.

    Linker w jakiśsposób podłącza standardowe biblioteki i nawet wie które podłączyć.
    podaje się np. #include <plik z nagłówami> i środowisko wie co dalej z tym zrobić.
    Może ktoś wie w jaki sposób wzbogacić standardową o swoją, skompilowaną bibliotekę?
    Poco mam kompilować dziesiątki razy coś czego zmieniać nie będę? I zresztą linker właśnie do tego służy.

    W książkach słabo to jest opisane.

    0
  • #4 26 Mar 2012 12:06
    gaskoin
    Poziom 38  

    #include nie ma tu nic do rzeczy. Ta dyrektywa preprocesora nie ma nic wspólnego z linkerem.

    Jak zajrzysz w opcje projektu, będziesz miał tam taki parametr linkera jak -l. To właśnie za jego pomocą się dołącza biblioteki do projektu.

    Gdzie linker ma szukać bibliotek precyzuje się parametrem -L.

    0
  • #5 26 Mar 2012 13:26
    tmf
    Moderator Mikrokontrolery Projektowanie

    Aimeiz napisał:
    Dlaczego komplikuję? Poprostu chcę się tego nauczyć. Jak znajdę gdzieś skompilowaną bibliotekę, która jest dla mnie użyteczna, chcę wiedzieć jak z niej skorzystać.
    Komuś mogę podarować swoją bibliotekę, ale niekoniecznie pokazać jej kod źródłowy.
    Powodów może być wiele.

    Linker w jakiśsposób podłącza standardowe biblioteki i nawet wie które podłączyć.
    podaje się np. #include <plik z nagłówami> i środowisko wie co dalej z tym zrobić.
    Może ktoś wie w jaki sposób wzbogacić standardową o swoją, skompilowaną bibliotekę?
    Poco mam kompilować dziesiątki razy coś czego zmieniać nie będę? I zresztą linker właśnie do tego służy.

    W książkach słabo to jest opisane.


    Dla mikrokontrolerów tworzenie takich bibliotek jest co najmniej niewygodne. Z tej prostej przyczyny, że dla każdego typu mikrokontrolera musisz mieć odpowiednią, skompilowaną na niego wersję swojej biblioteki. Jeśli z jakiejś przyczyny chcesz tak zrobić to dodatkowo musisz zmodyfikować nie tylko makefile, ale także domyślny skrypt linkera, żeby dołączał wersję biblioteki pod konkretny typ procesora. Kolejna sprawa - nic nie kompilujesz dziesiątki razy. Pliki są rekompilowane wyłącznie jeśli się zmieniły, inaczej kompilator je pomija, a linker używa wcześniej wygenerowanych plików obiektowych (czyli tego co byłoby w twojej bibliotece). Linker wie gdzie jest biblioteka standardowa (libc) bo jest ona wprost wskazana w opcjach kompilacji, tyle, że większość środowisk robi to domyślnie i możesz odnieść wrażenie, że linker ją w jakiś magiczny sposób znajduje, podczas, gdy tak wcale nie jest. Co do książek, to znam przynajmniej jedną w której jest to dosyć dobrze opisane :)

    0
  • #6 26 Mar 2012 13:46
    noonam3
    Poziom 8  

    Jeśli chcesz komuś dać bibliotekę to musisz ją skompilować i dać komuś pliki .lib, .dll oraz h. Takie pliki następnie ktoś musi umieścić w odpowiednich katalogach(dll do np. systemu, lib oraz h do katalogu /lib i /include wskazanego w opcjach AVR studio) i należy również w opcjach linkera podlinkować pliczek .lib z którego korzystamy.

    0
  • #7 26 Mar 2012 13:53
    tmf
    Moderator Mikrokontrolery Projektowanie

    noonam3 napisał:
    Jeśli chcesz komuś dać bibliotekę to musisz ją skompilować i dać komuś pliki .lib, .dll oraz h. Takie pliki następnie ktoś musi umieścić w odpowiednich katalogach(dll do np. systemu, lib oraz h do katalogu /lib i /include wskazanego w opcjach AVR studio) i należy również w opcjach linkera podlinkować pliczek .lib z którego korzystamy.


    Dynamicznie ładowana biblioteka (dll) i AVR? No, no, same cuda.

    0
  • #8 26 Mar 2012 14:20
    gaskoin
    Poziom 38  

    DLL się obsuguje inaczej niż statyczne biblioteki. Linker nie musi o nich wiedzieć, na AVR raczej się tego nie da obsłużyć :)

    0
  • #9 26 Mar 2012 14:21
    noonam3
    Poziom 8  

    No tak, takie cuda to tylko pod PC ;D dll odpada w tym wypadku heh przepraszam za wprowadzanie w błąd.

    0
  • #10 26 Mar 2012 14:21
    Aimeiz
    Poziom 15  

    Drogi kolego tmf.

    To cytat z książki którą polecasz w swojej stopce:
    Str 47.
    "Wynika z tego, że zamiast dołączać
    do projektu kolejne pliki zawierające kod źródłowy, równie dobrze można dołączyć
    skompilowane pliki obiektowe. Dzięki temu nie musimy powtarzać ich kompilacji —
    są one w postaci gotowej do wykorzystania przez linker."
    Dlatego właśnie chcę zgłębić również ten temat, zresztą przyda mi się do innych zastosowań.
    Są też tam podane inne powody, ale nie chcę włączać zbyt obszernych fragmentów tekstu.

    Jeśli dysponujesz wiedzą co konkretnie trzeba zrobić w środowisku AVR Studio 5, aby to zadziałało, to chętnie skorzystam z twojego doświadczenia, natomiast czytanie ogólników typu że coś tam trzeba zmodyfikować ale nie podajesz jak i co, to dosyć mało użyteczna informacja.

    0
  • #12 26 Mar 2012 14:38
    Aimeiz
    Poziom 15  

    Przeczytałem i zastosowałem - dziękuję.
    Ale coś nie jest tak bo nie pomogło.
    AVR Studio 5 problem z linkowaniem biblioteki

    Dostaję taki output:

    Building target: Osciloscope_Nokia_6100_m328.elf
    Invoking: AVR/GNU C/C++ Linker
    "C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" -Wl,-L"../PCF8833lib/Release" -mmcu=atmega328p -Wl,-Map=Osciloscope_Nokia_6100_m328.map -o Osciloscope_Nokia_6100_m328.elf Osciloscope_Nokia_6100_m328.o -Wl,-l libpcf8833lib
    avr-gcc.exe: libpcf8833lib: No such file or directory
    make: *** [Osciloscope_Nokia_6100_m328.elf] Error 1
    Done executing task "RunAvrGCC" -- FAILED.

    plik jest ale go nie odnajduje.

    0
  • #13 26 Mar 2012 14:54
    gaskoin
    Poziom 38  

    wywal w opcji -l z nazwy z początku 'lib' i wywal też '.a' i powinno być ok ('pcf8833lib') bo opcja -l sama dodaje to na początek i koniec

    0
  • #14 26 Mar 2012 15:21
    Aimeiz
    Poziom 15  

    Dzięki - to bardzo konkretna wskazówka. Spróbuję tak zrobić.

    Dodano po 6 [minuty]:

    wstawiłem w górne okienko tylko pcf8833lib, i dostaję błąd - can not find -lpcf8833lib ale to chyba byk w AVR studio i trzeba wstawić separator przed nazwą. Czy powinienem wstawić w cudzysłowie? 'pcf8833lib' czy poprostu spacja przed nazwą?

    w cudzysłowie daje błąd can not find -l'PCF8833lib' duże czy małe litery nic nie zmieniają.

    spacja przed nazwą likwiduje ten bład. Błędów niema, ale i tak się nie kompiluje:

    "C:/Program Files (x86)/Atmel/AVR Studio 5.0/AVR ToolChain/bin/avr-gcc.exe" -Wl,-L"../PCF8833lib/Release" -mmcu=atmega328p -Wl,-Map=Osciloscope_Nokia_6100_m328.map -o Osciloscope_Nokia_6100_m328.elf Osciloscope_Nokia_6100_m328.o -Wl,-l PCF8833lib
    avr-gcc.exe: PCF8833lib: No such file or directory
    make: *** [Osciloscope_Nokia_6100_m328.elf] Error 1

    Załamka :(

    0
  • #15 26 Mar 2012 15:41
    gaskoin
    Poziom 38  

    Spróbuj z innymi slashami. Nie używam gcc z avr, więc sam nie sprawdzę :)

    0
  • #16 26 Mar 2012 15:50
    tmf
    Moderator Mikrokontrolery Projektowanie

    Nie, to nie jest błąd. Ma być -l<nazwa> bez żadnych spacji. A skoro pisze, że nie może znaleźć to znaczy, że nie może - czyli w przeszukiwanych lokalizacjach jej nie ma. Generalnie wywoływanie linkera ze ścieżką względną jest pomysłem kiepskim, bo nigdy nie wiesz z jakiego poziomu zostanie linker wywołany w makefile, szczególnie jeśli jest wywoływany pośrednio przez gcc. W AS5/6 masz w opcjach projektu toolchain i AVR/GNU C linker/Libraries, gdzie można podać i ścieżki i nazwy bibliotek (tak jak gaskoin pisał usuwa się lib i .a z nazwy). Kolejna sprawa - gcc i cały toolchain rozróżniają wielkość liter, PCFcośtam to nie to samo co pcfcośtam. Co do książki - na stronie 49 masz przykład jak dołączyć bibliotekę, a na str. 50 zrzut ekranu z AS4, ale zasadniczo w AS5 to wygląda podobnie.

    0
  • #17 26 Mar 2012 16:59
    Aimeiz
    Poziom 15  

    a tej ścieżki nie wpisuję ręcznie, tylko ją wyklikuję. Jest okienko do zaznaczenia czy ścieżka względna czy bezwzględna. Jak się to okienko zaznaczy to wtedy AVR studio samo odcina resztę ścieżki. zbiór wynikowy po skompilowaniu biblioteki znajduje się tutaj:
    C:\Users\Marcin\Documents\AVRStudio\Osciloscope_Nokia_6100\PCF8833lib\Release

    i ma taką nazwę: libPCF8833lib.a

    Wpisałem teraz tak:
    AVR Studio 5 problem z linkowaniem biblioteki

    Niby zadziałało, ale pojawiał się inny błąd - multiple definition of FONT8x8
    Musiaałem przenieść linijkę:
    #include "FONT8x8.h" gdzie była definicja tej zmiennej, ze ze zbioru PCF8833lib.h do kodu źródłowego biblioteki PCF8833lib.c
    I dopiero wtedy ruszyło.

    Dzięki za pomoc.

    Dodano po 13 [minuty]:

    Już wiem skąd wynił problem.
    Jak się zaznaczy okienko relative path, wtedy AVR studio 5 wstawia "uniksowe" slasze zamiast windowskowskich bakslaszy:
    ../PCF8833lib/Release

    I pojawia się wtedy też ten błąd can not find -IPCF8833lib równie żgdy się zmieni ręcznie slasze na bakslasze.
    ..\PCF8833lib\Release

    Pobadam w wolnym czasie tę opcję relative path. Niech ktoś inny się nie męczy tyle z takim głupstwem.

    Prawdopodobnie w AVR studio 4 to działa tak jak powinno, zresztą nie wiem. Nie chcę się cofać do czwórki bo bym musiał robić downgrade mikrokodu w moim dragonie.

    0
  • #18 26 Mar 2012 17:28
    tmf
    Moderator Mikrokontrolery Projektowanie

    Pamiętaj, żeby nigdy nie definiować zmiennych globalnych w plikach nagłówkowych. Tam można zrobić wyłącznie deklaracje extern.

    0
  • #19 26 Mar 2012 17:52
    Aimeiz
    Poziom 15  

    Przejżę jeszcze te pliki. To przenoszenie z kodu programu do biblioteki, robiłem metodą ctr-x ctr-v i mogły się wdać jakieś definicje / deklaracje niezgodne ze sztuką.

    W pliku nagłówkowym były tylko dyrektywy #define i deklaracje extern funkcji, ale również dyrektywy #include. Jedna z nik włączała plik nagłówkowy, w którym jest deklaracja unsigned char FONT8x8[97][8].
    Przeniosłem ten include do kodu źródłowego biblioteki i jest OK.

    Przydała by się jednak ta względna ścieżka do biblioteki, żeby można było całe rozwiązanie z zzipować i móc skompilopwać w systemie, gdzie bezwzględne ścieżki są inne niż u mnie.

    0
  • #20 26 Mar 2012 19:54
    gaskoin
    Poziom 38  

    Dlatego lepiej dla projektu utworzyć sobie katalog z bibliotekami i tam wszystkie pakować.

    0
  • #21 27 Mar 2012 06:58
    Aimeiz
    Poziom 15  

    Gaskoin.
    To jest bardzo dobra praktyka, bo nigdy niczego nie zabraknie.
    Muszę tylko wyśledzić jak właściwie użyćwzględnych ścieżek w AS 5, żeby projekt można było rozpaklować w dowolne miejsce. Jak się używa ścieżek bezwzględnych to wtedy jest kłopot, nawet na tym samym komputerze ale inne konto użytkownika. instrukcje i helpy do AV5 nie są szczegółowe, no bo począwszy od 5-ki używany jest silnik MS Visual Studio.
    Najlepiej jest zrobnić własnego makefile, wtedy po kłopocie.

    0
  • #22 27 Mar 2012 08:55
    tmf
    Moderator Mikrokontrolery Projektowanie

    Jak znam życie to AS5/6 podobnie jak AS4 będzie miał kłopoty ze ścieżkami względnymi. To jest szczególnie upierdliwe jak się korzysta z jakiegoś systemu wersjonowania. Na szczęście pliki konfiguracji to XML więc łatwo to ręcznie poprawić, co jednak nie zmniejsza upierdliwości takiego rozwiązania.

    0
  • #23 27 Mar 2012 10:23
    gaskoin
    Poziom 38  

    Nie używam AS5/6 ale z tego co mi wiadomo jest zbudowany na VS. Nie wiem jak wersja pod C/C++ ale wersja C# nie ma problemów ze ścieżkami względnymi ani pod gitem ani svnem :)

    0
  • #24 03 Cze 2012 15:19
    d21d3q
    Poziom 11  

    Jak wygląda kwestia plików .cpp? mam hedera i cpp z funkcjami i definicjami do obsługi modułu radiowego, których używam w dwóch różnych projektach. Jak dodam te pliki do projektu, to AStudio kopiuje je do katalogu projektu, więc jak dokonam jakichś zmian, to nie będą one widoczne przez drugi projekt (który ma swoją własną kopię). Pytanie jak podpiąć te pliki pod program, aby były wspólne dla obydwu projektów?
    EDIT:
    Jak na razie podałem w ustawieniach ścieżkę do katalogu ze wspólnymi plikami i załączyłem plik .cpp w przy pomocy #include. W tym przypadku plik ten będzie za każdym razem kompilowany niezależnie od tego czy był zmieniany czy nie?

    0
  • #25 03 Cze 2012 16:04
    tmf
    Moderator Mikrokontrolery Projektowanie

    Robisz jakąś kaszanę. Plików źródłowych nigdy się nie inkluduje. Druga kaszana - jesteś pewien, że piszesz w C++?
    Trzecia kaszana - jeśli plik jest wykorzystywany w dwóch projektach to lepiej z niego zrobić osobny projekt - biblioteki i prekompilowaną wersję wykorzystywać w dwóch pozostałych.
    A AS może korzystać z plików w dowolnej lokalizacji - po prostu dodajesz istniejący plik.

    0
  • #26 03 Cze 2012 16:23
    d21d3q
    Poziom 11  

    Pierwsza kaszana też mi się nie podobała (ale tymczasowo działała :P) Nie czuję problemu z drugiej kaszany.
    Trzecia to meritum. Jeśli mam kilka plików (do różnych modułów), to tworzyć dla nich osobne projekty, czy wystarczy mi jeden zbiorczy?
    Właśnie jak dodawałem istniejący plik, to AS kopiował go do katalogu projektu.

    0
  • #27 03 Cze 2012 18:16
    tmf
    Moderator Mikrokontrolery Projektowanie

    ad 1. To, że działa to jeszcze nie wszystko :) Tłumaczenie dlaczego tak nie należy robić jest dosyć obszerne, po prostu uwierz na słowo, albo zaglądnij do porządnej książki o C.
    ad 2. To jakie masz rozszerzenie ma istotne konsekwencje. gcc po rozszerzeniu rozpoznaje czy ma do czynienia z programem napisanym w C czy C++. A ponieważ to dwa zupełnie różne języki to rozróżnienie jest dosyć istotne. Dodatkowo jeśli w jednym projekcie mieszasz C i C++ to już się robi hardcore, bo np. C++ zupełnie inaczej mangluje nazwy, w efekcie przenoszenie symboli pomiędzy językami nie jest banalne i wymaga np. jawnego użycia extern "C" dla funkcji. A to dopiero początek problemów.
    ad 3. Jeśli te pliki tworzą logiczną całość to bym je umieścił w jednym projekcie (bibliotece), jeśli nie to w różnych. Poza tym w AS możesz też do projektu dodawać projekty zależne.
    ad 4. Nie klikaj add tylko add as link.

    0
  • #28 03 Cze 2012 23:38
    d21d3q
    Poziom 11  

    Doczytałem To i wrzuciłem do nagłówków to:
    #ifdef __cplusplus
    extern "C" {
    #endif
    i zrobiłem jak w ad. 4 (wcześniej nie zauważyłem tej opcji)
    Czy teraz mogę te same pliki dołączać do projektów c i cpp?
    Jaki może być ciąg dalszy problemów?
    Jeśli zanim spytałem o radę wszystko jakoś działało mimo tego wymieszania, to było to moje szczęście, czy też odporność kompilatora na takie "kwiatki"?
    Jeśli miałbym zrobić tak jak w ad. 3, to musiałbym stworzyć dwa osobne projekty dla c i cpp?
    (na cpp uparłem się dlatego, bo dorwałem bibliotekę do obsługi wyświetlacza, która ma zdefiniowany operator << do wypisywania różnych rzeczy na ekran - to jedyny powód)

    0
  • #29 04 Cze 2012 11:57
    gaskoin
    Poziom 38  

    To jest operator przesunięcia bitowego i jego pochodzenie nie ma nic wspólnego z C++.

    Co do innego pytania - jeśli zrobisz #include "costam.c" to to będzie działało, bo w miejsce linijki z include, jest wklejany kod z pliku, który includujesz. Tak się tego nie robi bo prowadzi to do wielu problemów w przyszłości typu redeklaracje redefinicje itd.

    Dołącza się tylko pliki nagłówkowe dostarczające stałe, Makra itp + informacje o prototypach/zmiennych(jako extern). Natomiast same funkcje i zmienne są w pliku źródłowym c, którego to wynik kompilacji powinien być dołączony przez linker. To, co Ty robisz (include c/cpp) to nie jest kaszana, to jest mańana.

    0
  • #30 04 Cze 2012 21:18
    d21d3q
    Poziom 11  

    chodziło mi o analogię do cout'a:
    wyswietlacz << "napis" << numer;
    wygodniej?

    0