Nei linguaggi che richiedono il linking (casi classici: C e C++) il processo di build avviene sostanzialmente in due fasi separate: compilazione e linking.
La compilazione consiste nel convertire i singoli file sorgenti in moduli oggetto, ovvero in codice macchina in cui però al posto degli "oggetti" (funzioni, variabili, ...) definite altrove sono lasciati dei "placeholder".
Mi spiego meglio: se in C in un file scrivi il prototipo di una funzione (ovvero come si chiama e che parametri accetta) ma non la definisci, tu puoi chiamarla all'interno del file, ma ovviamente il compilatore non potrà generare il codice di chiamata a funzione "completo": si limiterà a scrivere il codice di passaggio dei parametri e l'istruzione di chiamata a funzione, ma l'indirizzo della funzione è ancora lasciato in sospeso.
Il linking, invece, consiste nel "tirare le fila" dei vari moduli oggetto per riunirli in un unico eseguibile. I moduli oggetto vengono uniti e i riferimenti finora lasciati in sospeso vengono risolti (dato che il linker ha il quadro completo della situazione). Al termine di questo processo viene generato l'eseguibile finale.

(tutto questo è spiegato in maniera anche più chiara ad esempio in questo articolo di Raymond Chen)