2011-01-05 9 views
56

Ho appena scoperto che il flag -lm è necessario da gcc per compilare un programma che fa riferimento a una funzione dalla libreria matematica. Mi chiedo il motivo per cui un flag esplicito di collegamento non è necessario durante la compilazione di programmi contenenti altre librerie come la libreria di orari. Se scrivo un programma in cui viene chiamata la funzione time(), si compila senza problemi anche senza opzioni di collegamento. Ma un programma con la libreria matematica coinvolta non funzionerà senza il flag -lm.gcc: perché il flag -lm è necessario per collegare la libreria matematica?

Qualcuno può spiegare la ragione di questo comportamento? Grazie per il tuo tempo.

+4

Strani motivi storici, ma soprattutto perché è come è: http://stackoverflow.com/questions/1033898/why-do-you-ha-to-link-the-math-library-in-c – birryree

risposta

32

Perché time() e alcune altre funzioni sono builtin definite nella libreria C (libc) stesso e GCC sempre link a libc a meno si utilizza l'opzione di compilazione -ffreestanding. Tuttavia, le funzioni matematiche sono attive in libm che non è collegato in modo implicito da gcc.

+4

On LLVM gcc Non devo aggiungere -lm. Perchè è questo? –

55

A causa di pratiche storiche ridicole che nessuno è disposto a risolvere. Il consolidamento di tutte le funzioni richieste da C e POSIX in un singolo file di libreria non solo eviterebbe di rispondere a questa domanda ripetutamente, ma anche di risparmiare una quantità significativa di tempo e memoria durante il collegamento dinamico, poiché ogni file .so richiede il filesystem operazioni per individuare e lo trovano, e alcune pagine per le sue variabili statiche, le delocalizzazioni, ecc

Un'implementazione in cui tutte le funzioni sono in una biblioteca e la -lm, -lpthread, -lrt, ecc opzioni sono tutti no-ops (o link per svuotare i file .a) è perfettamente conforme POSIX e sicuramente preferibile.

Nota: sto parlando di POSIX perché C stesso non specifica nulla su come viene richiamato il compilatore. Quindi puoi trattare lo gcc -std=c99 -lm come il modo specifico per l'implementazione che il compilatore deve invocare per un comportamento conforme.

+8

+1 per indicare che POSIX non richiede che esistano librerie libm, libc e librt separate. Ad esempio, su Mac OS tutto si trova in un singolo libSystem (che include anche libdbm, libdl, libgcc_s, libinfo, libm, libpoll, libproc e librpcsvc). –

+3

-1 per speculare sull'impatto della ricerca sulle librerie sulle prestazioni senza eseguire il backup con un collegamento o numeri. "Profilo. Non speculare" –

+7

Questa non è speculazione. Non ho documenti pubblicati, ma ho fatto tutte le misurazioni da solo e la differenza è enorme. Basta usare 'strace' con una delle opzioni di temporizzazione per vedere quanto tempo di avvio viene speso per il collegamento dinamico, o confrontare l'esecuzione di'./Configure' su un sistema in cui tutte le utility standard sono collegate staticamente rispetto a una in cui sono dinamiche linked. Anche gli sviluppatori di app desktop tradizionali e gli integratori di sistemi sono consapevoli dei costi del collegamento dinamico; questo è il motivo per cui esistono cose come il prelink. Sono sicuro che puoi trovare dei punti di riferimento in alcuni di quei documenti. –