At this point you have an executable.
No. A questo punto, si dispone di file oggetto, che non sono, di per sé, eseguibili.
But if you actually run that executable what happens?
Qualcosa di simile a questo:
h2co3-macbook:~ h2co3$ clang -Wall -o quirk.o quirk.c -c
h2co3-macbook:~ h2co3$ chmod +x quirk.o
h2co3-macbook:~ h2co3$ ./quirk.o
-bash: ./quirk.o: Malformed Mach-o file
ho detto voi che non era un eseguibile.
Is the problem that you may have included *.h files, and those only contain function prototypes?
Abbastanza vicino, in realtà. Un'unità di traduzione (file .c) viene (generalmente) trasformata in codice assembly/macchina che rappresenta ciò che fa. Se chiama una funzione, allora ci sarà un riferimento a quella funzione nel file, ma nessuna definizione.
So if you actually call one of the functions from those files, it won't have a definition and your program will crash?
Come ho già detto, non funzionerà nemmeno. Permettetemi di ripetere: un file oggetto è non eseguibile.
what exactly does linking do, under the hood? How does it find the .c file associated with the .h that you included [...]
E non lo fa. Cerca altri file oggetto generati da file .c e infine librerie (che sono essenzialmente solo raccolte di altri file oggetto).
E li trova perché gli dici cosa cercare. Supponendo di avere un progetto che si compone di due file .c che richiedono funzioni di ogni altro, questo non funzionerà:
gcc -c file1.c -o file1.o
gcc -c file2.c -o file2.o
gcc -o my_prog file1.o
fallirà con un errore di linker: il linker non troverà la definizione del funzioni implementate in file2.c
(e file2.o
). Ma questo funzionerà: i file
gcc -c file1.c -o file1.o
gcc -c file2.c -o file2.o
gcc -o my_prog file1.o file2.o
[...] and how does it inject that into your machine code?
Object contengono riferimenti stub (di solito sotto forma di indirizzi punto di ingresso di funzione o esplicite, nomi leggibili) alle funzioni che chiamano. Quindi, il linker esamina ciascuna libreria e il file oggetto, trova i riferimenti (, genera un errore se non è possibile trovare una definizione di funzione), quindi sostituisce i riferimenti stub con le istruzioni del codice macchina "chiama questa funzione". (Sì, questo è in gran parte semplificata, ma senza che ti chiede di una specifica architettura e uno specifico compilatore/linker, è difficile dire più precisamente ...)
Is static when you actually recompile the source of the library for every executable you create?
No. legame statico significa che il codice macchina i file oggetto di una libreria vengono effettivamente copiati/uniti nell'eseguibile finale. Collegamento dinamico significa che una libreria viene caricata in memoria una volta, quindi i riferimenti delle funzioni di stub di cui sopra vengono risolti dal sistema operativo all'avvio del file eseguibile. Nessun codice macchina dalla libreria verrà copiato nel file eseguibile finale. (Quindi qui, il linker nella toolchain fa solo parte del lavoro.)
Quanto segue può aiutarti a raggiungere l'illuminazione: se si collega staticamente un eseguibile, esso sarà autonomo. Funzionerà ovunque (comunque su un'architettura compatibile). Se lo si collega dinamicamente, verrà eseguito solo su una macchina se quella particolare macchina ha tutte le librerie installate a cui fa riferimento il programma.
So you compile one executable library that is shared by all of your processes that use it? How is that possible, exactly? Wouldn't it be outside of the address space of the processes trying to access it?
Il componente linker/loader dinamico del sistema operativo si occupa di tutto ciò.
Also, for dynamic linking, don't you still need to compile the library at some juncture in time?
Come ho già detto: sì, è già compilato. Quindi viene caricato in un punto (in genere quando viene utilizzato per la prima volta) in memoria.
When is it compiled?
Un po 'di tempo prima che potesse essere utilizzato. In genere, una libreria viene compilata, quindi installata in una posizione del sistema in modo che il sistema operativo e il compilatore/linker siano a conoscenza della sua esistenza, quindi è possibile iniziare la compilazione (um, che collega i programmi) che utilizzano quella libreria. Non prima.
possibile duplicato di [Come funziona il collegamento C++ in pratica?] (Http://stackoverflow.com/questions/12122446/how-does-c-linking-work-in-practice) –