Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!
Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.
Witam serdecznie.
Przyznam szczerze, że przejrzałam forum pod kątem problemu z linkerem, ale nie udało mi się znaleźć satysfakcjonującej odpowiedzi. Usiłuję napisać prosty programik używający wątki w języku C (mam policzyć entropię w bitach). Wszystko szło dobrze, dopóki nie chciałam użyć funkcji log(). Kiedy jest ona w zewnętrznej funkcji kompilator wyrzuca mi błąd "undefined reference to 'log'". Znalazłam w jednym z tematów, że "wystarczy" dołączyć bibliotekę math.h. Była dołączona od samego początku. Dodatkowo ściągnęłam i zainstalowałam repo z bibliotekami do gcc na wszelki wypadek i dalej był problem. Zmiana na funkcję log10(); też niewiele pomogła (mogę sobie pozwolić na taką podmiankę, ponieważ chcę policzyć logarytm przy podstawie 2, więc z praw działania na logarytmach wystarczy, że zastosuję iloraz). W każdym razie zmienną do logarytmu wprowadzam poprzez argument zewnętrznej funkcji. (Zewnętrznej, czyli mam namyśli funkcję, którą stworzyłam sobie sama, a nie funkcję główną main()). Dopatrzyłam się, że właśnie tutaj jest błąd.
Niemniej, jeśli umieszczę funkcję log() (lub log10()) w mainie, podam argument liczbowo (np. log10(10)), to wylicza wartość z błędem, lecz kompiluje bez błędu.
Czy ktoś z Was wie, na czym może polegać problem? Domyślam się, że prawdopodobnie to będzie "bardzo łatwe, bardzo naiwne i wstyd, że nie wiem", niemniej walczę z tym już dobrą godzinę : )
____________
Zapomniałam napisać: kompiluję na Debianie. Natomiast na Ubuntu (zupełnie inny komputer, dodam dla porządku), rzecz wygląda tak samo.
______________
Właściwie to rozwiązane, więc albo można usunąć (przepraszam moderatorze za kłopot (: ), albo podam rozwiązanie, że tak zażartuję, dla potomnych. Mianowicie przy kompilacji nie podałam -lm.
Dziękuję i wybaczcie za zawracanie głowy.
Ostatnio edytowany przez Onegda (2013-03-31 22:40:13)
Offline
no ok, ale gdzie są źródła ?
Offline
http://www.network-theory.co.uk/docs/gccintro/gccintro_17.html
2.7 Linkowanie z bibliotekami zewnętrznymi
Biblioteka jest kolekcją skompilowanych plików obiektowych, które mogą być dołączone do programu. Najbardziej powszechne zastosowanie bibliotek to dostarczenie funkcji systemowych, takich jak pierwiastek kwadratowy ( sqrt ) z biblioteki matematycznej w C.
Biblioteki są zazwyczaj przechowywane w specjalnych plikach archiwów z rozszerzeniem '.a' określanych jako biblioteki statyczne. Są one tworzone z plików obiektowych przy użyciu oddzielnego narzędzia GNU archiwizator ar i używane przez linker do znalezienia/rozwiązania referencji do funkcji w czasie kompilacji. (bardziej podczas linkowania) ...
Standardowe biblioteki systemowe są zazwyczaj umieszczone w katalogach '/usr/lib' i '/lib'. Przykładowo biblioteka matematyczna C jest zazwyczaj przechowywana w pliku '/usr/lib/libm.a' w systemach uniksowych. Odpowiednie deklaracje dla funkcji z tej biblioteki są umieszczone w pliku nagłówkowym '/usr/include/math.h'. Standardowa biblioteka C jest zapisana w '/usr/lib/libc.a' i zawiera funkcje standardu ANSI/ISO C takie jak printf, ta biblioteka jest linkowana domyślnie do każdego programu napisanego w C (podczas linkowania).
Oto przykład programu, który wywołuje zewnętrzną funkcje sqrt z biblioteki matematycznej 'libm.a'Kod:
#include <math.h> #include <stdio.h> int main (void) { double x = sqrt (2.0); printf ("Pierwiastek kwadratowy z 2.0 wynosi %f\n", x); return 0; }Próba stworzenia pliku wykonywalnego z tego kodu powoduje wygenerowanie błędu przez kompilator w czasie linkowania.
Kod:
$ gcc -Wall calc.c -o calc /tmp/ccbR6Ojm.o: In function `main': /tmp/ccbR6Ojm.o(.text+0x19): undefined reference to `sqrt'Problem polega na tym, iż nie można znaleźć referencji do funkcji sqrt bez zewnętrznej biblioteki matematycznej 'libm.a'. Funkcja sqrt nie jest zdefiniowana w programie lub w domyślnej bibliotece 'libc.a' a kompilator nie linkuje pliku 'libm.a' chyba że w sposób jasny tego zażądamy. Plik wspomniany w komunikacie o błędzie ‘/tmp/ccbR60jm.o’ jest tymczasowym plikiem obiektowym stworzonym przez kompilator z calc.c aby kontynuować proces linkowania.
Aby umożliwić kompilatorowi linkowanie funkcji sqrt do naszego programu musimy dostarczyć odpowiednią bibliotekę w tym przypadku 'libm.a'. Jeden oczywisty ale niewygodny sposób aby to zrobić to podać nazwę pliku w linii poleceń:Kod:
$ gcc -Wall calc.c /usr/lib/libm.a -o calcBiblioteka 'libm.a' zawiera definicje wszystkich funkcji matematycznych takich jak sin, cos, exp, log, sqrt. Linker przeszukuje tą biblioteke w poszukiwaniu pliku obiektowego zawierającego funkcje sqrt.
Kiedy plik obiektowy funkcji sqrt zostanie znaleziony nasz program może być linkowany i program wykonywalny może powstać.Kod:
$ ./calc The square root of 2.0 is 1.414214Plik wykonywalny zawiera kod maszynowy dla funkcji main i kod maszynowy dla funkcji sqrt skopiowany z pliku obiektowego w bibliotece 'libm.a'.
Aby uniknąć długich ścieżek z linii poleceń kompilator ma opcję '-l' aby linkować z zewnętrznymi bibliotekami. Przykładowo:Kod:
$ gcc -Wall calc.c -lm -o calcjest równoważne z podaniem pełnej ścieżki do biblioteki.
Ogólnie opcja -lNAZWA spróbuje linkować z plikiem obiektowym z pliku biblioteki 'libNAZWA.a' w standardowym katalogu bibliotek. ...
Gdyby ktoś nic z tego nie zrozumiał to ma to wygladac tak:
1) kompilujemy i tylko kompilujemy wiec opcje dla linkera na tym etapie nie sa potrzebne
gcc -o prog.o -c prog.c
2) linkujemy wiec dodajemy opcje dla linkera:
gcc -lm -o prog prog.o
Jezeli komus bedzie sie chcialo prosz sprawdzic gdyz ja w tej chwili uzywam windowsa nie moge tego zweryfikowac
Lektura dodatkowa:
http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html
Offline