Сборка с или с++ кода проходит в 2 этапа.
1 - компиляция. На нем каждый cpp-шник преобразуется в объектный файл. Поскольку каждый файл компилируется независимо, мы пока не можем вычислить адрес функций из другого объектника. На их месте оставляем дырки и записываем в специальные таблички символы которые ожидаем
/ имеем.
Потом происходит линковка. Все объектные файлы записываются друг за другом, и теперь можно заполнить адреса всех функций.
Статические библиотеки ведут себя примерно как обычные объектные файлы. С динамическими все несколько сложней.
Компилятор после сборки собирает бинарь, это и есть объектный модуль. После он связывается с нужными библиотеками (статическими или динамическими). После полного этапа сборки в результате получается нужный файл.