Non lo sa. Il processo di build si articola in diverse fasi, due di queste sono:
compilazione
I file c vengono tradotti separatamente in linguaggio macchina e per ognuno di essi genera un file oggetto (.obj, .o). In questa fase il compilatore non ha bisogno delle definizioni, gli basta sapere la dichiarazione. Al posto delle chiamate metterà dei segnaposto (non so se c'è un nome tecnico). Ovviamente il file oggetto non può essere eseguito.
linking
Il linker si occupa di cercare le le definizioni di funzioni e le variabili esterne dichiarate, ma non definite nei file c del progetto. Viene fuso tutto nell'exe e i segnaposto sostituiti con l'indirizzo delle funzioni. Se le funzioni si trovano in librerie dinamiche esterne (es. DLL su Windows, SO su Linux), ci mette una chiamata al sistema operativo.
Prova a scrivere un codice con sole dichiarazioni di funzioni, ma senza chiamarle, dovrebbe compilare lo stesso. Poi prova a mettere la chiamata, ma senza averle definite, ti darà un errore di linking, ma non di compilazione.
Questo succede a grandi linee. Cerca di Google qualcosa come compiling and linking process.
https://www.cprogramming.com/compilingandlinking.htm