2014-12-15 17 views
9

próbuję skompilować biblioteki w C, które potrzebują „math.h”, tutaj jest pacz pliku .c:C - niezdefiniowane odniesienia do „sqrt” nawet „-lm”

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 
#include "sparse_matrix.h" 
... 

i skompilować z tym poleceniem:

gcc -c ./sparse_matrix.c -o sparse_matrix.o -lm -Wall -pedantic -std=c99 -g -O 

ale nawet z #include wykonanej i flagi -lm po pliku (próbowałem na końcu linii, ale nic się nie zmieniło) nadal pojawia się błąd: undefined reference to « sqrt » collect2: error: ld returned 1 exit status

Nie rozumiem tego po godzinie googlowania. Pracuję z gcc 4.9 pod Ubuntu 14.10 (utopowy jednorożec). Dziękujemy za pomoc z góry!

+0

Opcja '-c' pomija łączenie. Nie dostaniesz tego błędu z tego wiersza poleceń. Dlatego nie jest to linia poleceń, która powoduje błąd. (Nie używaj @ przed regułami w 'makefile' - to prawdopodobnie nie jest twój problem, ale ukrywa polecenia i może wprowadzić Cię w błąd.) A większość tego właśnie powiedziała @paxdiablo. –

+0

możliwy duplikat ["niezdefiniowane odwołanie do \" pow '"nawet z math.h i linkiem biblioteki -lm] (http://stackoverflow.com/questions/16344445/undefined-reference-to-pow-even-with -math-h-and-the-library-link-lm) –

Odpowiedz

10

Nie sądzę, że jest polecenie używasz (no, może to być jeden z nich, ale nie jest to z pewnością jeden powodując błąd).

Opcja -c na gcc mówi, że należy utworzyć tylko pliki obiektów (a konkretnie wysyłane są dane wyjściowe do pliku obiektu sparse_matrix.o, a nie pliku wykonywalnego).

W takim przypadku linker powinien być w całości nazwany , a nie.

W rzeczywistości, z manekina sparse_matrix.c z:

#include <math.h> 
int main(void) { 
    return (int)(sqrt(16.0)); 
} 

swoją komenda działa dobrze, a kiedy zakończyć proces z:

pax> gcc -o sparse_matrix sparse_matrix.o -lm 
pax> ./sparse_matrix 
pax> echo $? 
4 

widać, że również działa dobrze.

Może to oznaczać, że opuszczasz flagę łącznika (taką jak -lm) z rzeczywistego etapu połączenie, co może spowodować ten problem. Nie powinny one mieć wpływu na etap kompilacji (chyba że mają wpływ na oba etapy połączenia, ale -l nie jest jednym z nich).

I, przez "odstąpienie", włączam również możliwość "niewłaściwego rozmieszczenia". Niektóre łączniki są pozycyjne w sposobie obsługi bibliotek, ponieważ będą wyodrębniać obiekty z bibliotek, jeśli spełniają nieokreślony symbol w miejscu, w którym są wymienione.

więc polecenie:

linker sparse_matrix.o -lm ... 

będzie działać, ponieważ plik .o wprowadza niezadowolony odniesienie do sqrt, co jest realizowane przez libm.Jeśli łącznik jest pozycyjny, a następnie:

linker -lm sparse_matrix.o ... 

nie będzie działać, bo w czasie przetwarzania libm było żadnych niezaspokojone symbole tak nic nie zostało wydobyte. Nieokreślone odniesienie do sqrt jest następnie wprowadzane jako po tym punkcie i nie ma żadnych innych obiektów ani bibliotek, które by to zaspokajały.

Niezależnie od tego, czy etap łącznikowy ld, czy gcc ma to ograniczenie, nie wiem, po prostu podnosimy tę możliwość jako coś, na co należy zwrócić uwagę.

+0

Dziękujemy! W rzeczywistości z flagą "-c" linker nie jest w ogóle wywoływany, to był błąd. Ale próbowałem bez flagi -c (gcc sparse_matrix.c -o sparse_matrix.o -Wall -pedantic -std = c99-g -O -lm). Ale mam niezdefiniowane odniesienie do "głównego". Jak już wspomniałem, próbuję tylko zrobić bibliotekę "sparse_matrix", która potrzebuje funkcji "sqrt" z "libmath". –

+1

@Alex, sprawdź, czy faktycznie jest "główny" w tym pliku C. Biorąc pod uwagę, że oddzielasz kompilację od etapów łączy, prawdopodobnie istnieje ona w _annym_ pliku C. Jeśli tylko tworzysz bibliotekę z obiektami (bez 'main'),' -c' jest drogą do zrobienia, ale wprowadzanie biblioteki matematycznej jest czymś, co powinno być zrobione podczas łączenia, kiedy twój klient potrzebuje używać twoich rzeczy: 'gcc client_stuff.c -lsparse_matrix_lib -lm ...'. – paxdiablo

+0

Tak właśnie próbowałem. Dziękuję, nie jestem z łatwością z biblioteką i pomyślałem, że mogę połączyć bibliotekę z inną. Przepraszamy za ten prosty błąd. Próbowałem po prostu z moim głównym programem, który korzysta z tej biblioteki i (teraz, jak rozumiem) działa dobrze (po prostu dodano "-lm" NIE w czasie kompilacji biblioteki, ale na etapie łączenia programu za pomocą mojej biblioteki):) Jeszcze raz dziękuję za tak szybkie odpowiedzi! –

Powiązane problemy