2009-12-05 8 views
19

Considerate questo codice:Perché creare un file .a da .o per il collegamento statico?

one.c:

#include <stdio.h> 

int one() { 
    printf("one!\n"); 
    return 1; 
} 

two.c:

#include <stdio.h> 

int two() { 
    printf("two!\n"); 
    return 2; 
} 

prog.c

#include <stdio.h> 

int one(); 
int two(); 

int main(int argc, char *argv[]) 
{ 
    one(); 
    two(); 

    return 0; 
} 

voglio collegare questi programmi insieme. Così faccio questo:

gcc -c -o one.o one.c 
gcc -c -o two.o two.c 
gcc -o a.out prog.c one.o two.o 

Questo funziona bene.

O potrei creare una libreria statica:

ar rcs libone.a one.o 
ar rcs libtwo.a two.o 
gcc prog.c libone.a libtwo.a 
gcc -L. prog.c -lone -ltwo 

Quindi la mia domanda è: perché dovrei utilizzare la seconda versione - quella in cui ho creato un file ".a" - piuttosto che collega la mia". o "file? Entrambi sembrano essere collegati staticamente, quindi c'è un vantaggio o una differenza architettonica tra uno e l'altro?

risposta

38

In genere le librerie sono raccolte di file oggetto che possono essere utilizzate in più programmi.

Nel tuo esempio non c'è alcun vantaggio, ma voi avranno fatto:

ar rcs liboneandtwo.a one.o two.o 

Poi collega il programma diventa più semplice:

gcc -L. prog.c -loneandtwo 

E 'davvero una questione di packaging. Avete una serie di file oggetto che formano naturalmente una serie di funzionalità correlate che possono essere riutilizzate in più programmi? Se è così, allora possono essere sensibilmente archiviati in una libreria statica, altrimenti probabilmente non c'è alcun vantaggio.

C'è una differenza importante nella fase di collegamento finale. Tutti i file oggetto che hai collegato saranno inclusi nel programma finale. I file oggetto presenti nelle librerie sono inclusi solo se aiutano a risolvere eventuali simboli non definiti in altri file oggetto. In caso contrario, non saranno collegati all'eseguibile finale.

2

Tecnicamente, il risultato è esattamente lo stesso. Di solito, si creano librerie per le funzioni di utilità, quindi invece di alimentare il linker con dozzine di file oggetto, basta collegare la libreria.

BTW, non ha assolutamente senso creare un file .a che contenga solo un file .o.

+2

Il risultato è in genere molto diverso. Capita di essere lo stesso in questo esempio forzato. – UncleO

1

Il vantaggio principale è quando devi collegare, puoi semplicemente specificare una libreria invece di tutti i file oggetto separati. C'è anche un piccolo vantaggio nella gestione dei file, arrivando ad occuparsi di una libreria invece di una serie di file oggetto. Allo stesso tempo, questo ha anche dato un notevole risparmio di spazio su disco, ma gli attuali prezzi dei dischi rigidi lo rendono meno importante.

2

È possibile inserire una raccolta di file in un file di archivio (.a) per il successivo riutilizzo. La libreria standard è un buon esempio.

A volte ha senso organizzare grandi progetti in biblioteche.

12

La differenza sarebbe nella dimensione dell'eseguibile, anche se forse non per il tuo esempio.

Durante il collegamento a una libreria, vengono incorporati solo i bit utilizzati dal file eseguibile. Quando colleghi un file oggetto, prendi il tutto.

Ad esempio, se il file eseguibile deve includere tutte le funzioni matematiche nella libreria matematica quando ne si utilizza solo uno, sarebbe molto più grande del necessario e contenere molto codice inutilizzato.

È interessante confrontare questo con il modello di collegamento dinamico di Windows. Lì, il sistema operativo deve caricare tutte le DLL (librerie collegate dinamicamente) interamente utilizzate dal tuo eseguibile, il che potrebbe portare a un aumento della RAM. Il vantaggio di tale modello è che il tuo eseguibile è esso stesso più piccolo e le DLL collegate potrebbero già essere in memoria utilizzate da qualche altro eseguibile, quindi non è necessario caricarle di nuovo.

Nel collegamento statico, le funzioni della libreria vengono caricate separatamente per ciascun eseguibile.

0

Ogniqualvolta mi viene posta questa domanda (da parte dei neofiti della mia squadra), "perché (oa volte anche un 'ciò che è') a .a?", Utilizzo la risposta di sotto che usa il .zip come un'analogia.

"Un puntoAy è come un file zip di tutti i puntiOhs che si desidera collegare mentre si costruiscono i risparmi su exe/lib su spazio disco, oltre a non è necessario digitare i nomi di tutti i dotOhs coinvolti."

finora, questo è sembrato farli capire. ;)