2014-12-15 17 views
9

provo a compilare una libreria in C che hanno bisogno "math.h", qui è l'inizio del file .c:C - undefined reference to "sqrt" anche con '-lm'

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

e compilo con questo comando:

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

ma anche con la #include fatto e la bandiera -lm dopo che il file (ho provato alla fine della linea, ma non è cambiato nulla) ancora ottengo l'errore: undefined reference to « sqrt » collect2: error: ld returned 1 exit status

Non capisco dopo un'ora di cercare su Google il problema. Sto lavorando con gcc 4.9 sotto ubuntu 14.10 (unicorno utopico). Grazie per l'aiuto in anticipo!

+0

L'opzione '-c' sopprime il collegamento. Non riceverai quell'errore da quella riga di comando. Pertanto, quella non è la riga di comando che produce l'errore. (Non usare @ before rules in un 'makefile' - probabilmente non è un tuo problema, ma nasconde i comandi e può essere fuorviante.) E la maggior parte di questo è ciò che dice @paxdiablo. –

+0

possibile duplicato di ["riferimento non definito a \' pow "" anche con math.h e il link della libreria -lm] (http://stackoverflow.com/questions/16344445/undefined-reference-to-pow-even-with -math-h-and-the-library-link-lm) –

risposta

10

Non credo che sia il comando è in esecuzione (beh, può essere uno di loro, ma non è certamente quello che causa l'errore).

L'opzione -c su gcc indica di creare solo i file oggetto (e in particolare si invia l'output a sparse_matrix.o, un file oggetto anziché uno eseguibile).

In tal caso, il linker deve non essere chiamato a tutti.

Infatti, con un manichino sparse_matrix.c di:

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

tuo comando funziona bene e, quando ho completare il processo con:

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

si può vedere che funziona anche bene.

Può essere che si sta lasciando fuori le bandiere linker (come -lm) dalla effettiva collegamento fase, che potrebbe causare questo problema. Non dovrebbero avere alcun effetto sulla fase di compilazione (a meno che non influiscano su entrambe le fasi di collegamento e ma lo -l non sia uno di quelli).

E, per "lasciare", includo anche la possibilità di "errato". Alcuni linker sono posizionali nel modo in cui gestiscono le librerie in quanto estraggono solo oggetti dalle librerie se soddisfano un simbolo non definito nel punto in cui sono elencati.

Così, il comando:

linker sparse_matrix.o -lm ... 

avrebbe funzionato perché il file .o introduce un riferimento insoddisfatto per sqrt, che viene soddisfatta da libm.Se il linker è posizionale, quindi:

linker -lm sparse_matrix.o ... 

non avrebbe funzionato perché, al momento della lavorazione libm, c'erano non simboli insoddisfatti quindi nulla è stato estratto. Il riferimento non definito a sqrt viene quindi introdotto dopo in quel punto e non ci sono altri oggetti o librerie per soddisfarlo.

Se lo stadio di collegamento ld o gcc ha questa limitazione, non lo so, sto solo aumentando la possibilità come qualcosa a cui prestare attenzione.

+0

Grazie! Infatti con il flag '-c' il linker non è chiamato affatto, è stato un errore. Ma ho provato senza il flag -c (gcc sparse_matrix.c -o sparse_matrix.o -Wall -pedantic -std = c99 -g -O -lm). Ma ho un riferimento indefinito a "main". Come ho detto, provo solo a fare una libreria "sparse_matrix" che ha bisogno della funzione "sqrt" da "libmath". –

+1

@Alex, controlla se esiste effettivamente _is_ un 'main' in quel file C. Dato che stai separando la compilazione dalle fasi di collegamento, è probabile che esista nel file _another_ C. Se stai _solo_ creando una libreria con oggetti (non 'main'),' -c' è la strada da percorrere, ma l'introduzione della lib di matematica è qualcosa che dovrebbe essere fatto durante il collegamento, quando un tuo cliente ha bisogno per usare la tua roba: 'gcc client_stuff.c -lsparse_matrix_lib -lm ...'. – paxdiablo

+0

Sì, questo è quello che stavo cercando di fare. Grazie, non sono così disinvolto con la biblioteca e ho pensato di poter collegare una lib in un'altra. Ci scusiamo per questo errore piuttosto semplice. Ho appena provato con il mio programma principale che usa questa libreria e (ora che lo capisco) funziona bene (appena aggiunto '-lm' NON al momento della compilazione della libreria ma allo stadio di collegamento del programma usando la mia lib):) Grazie ancora per risposte così rapide! –