Я думаю, что вы знакомы с некоторой информацией, которая менее актуальна для начинающего программиста на Си и которая может сбить вас с толку - часть цели использования языка более высокого уровня, подобного этому, состоит в том, чтобы не задумываться о том, как этот процесс работает. Однако со временем важно понять процесс. Я думаю, что вы, как правило, правильно понимаете это.
Компилятор C просто берет код C и генерирует объектные файлы, содержащие машинный язык. Большая часть объектного файла занята содержимым функций. Например, простой вызов функции в C будет представлен в скомпилированной форме как операторы низкого уровня, чтобы помещать вещи в стек, изменять указатель инструкций и т. Д.
Библиотека C и любые другие используемые вами библиотеки уже доступны в этой скомпилированной форме.
Компоновщик - это то, что объединяет все соответствующие объектные файлы, разрешает все зависимости (например, один объектный файл, вызывающий функцию в стандартной библиотеке), а затем создает исполняемый файл.
Что касается языковых библиотек, написанных на: Думайте о каждой функции как о чёрном ящике. Пока черный ящик имеет стандартный интерфейс (соглашение о вызовах C; то есть он принимает аргументы определенным образом, возвращает значения определенным образом и т. Д.), Как он написан внутри, не имеет значения. Чаще всего функции будут написаны на C или непосредственно в сборке. К тому времени, когда они превращают его в объектный файл (или как скомпилированную библиотеку), уже не имеет значения, как они были изначально созданы, важно то, что они теперь находятся в форме скомпилированного компьютера.
Формат исполняемого файла зависит от операционной системы, но большая часть тела исполняемого файла в Windows очень похожа на объектные файлы. Представьте, что кто-то объединил все объектные файлы, а затем добавил немного клея. Клей загружает связанные вещи, а затем вызывает main (). Например, когда я был ребенком, люди получали удовольствие от «изменения клея», чтобы добавить еще одну функцию перед main (), которая отображала бы заставку с их именем.
Следует отметить, что независимо от того, какой язык вы используете, в конечном итоге вам придется использовать службы операционной системы. Например, для отображения содержимого на экране, для управления процессами и т. Д. Большинство операционных систем имеют API, который также можно вызывать аналогичным образом, но его содержимое не включается в ваш EXE-файл. Например, когда вы запускаете браузер, это исполняемый файл, но в какой-то момент происходит обращение к API Windows для создания окна или загрузки шрифта. Если бы это было частью вашего EXE, ваш EXE был бы огромным. Так что даже в вашем исполняемом файле есть «недостающие ссылки». Обычно они решаются во время загрузки или во время выполнения, в зависимости от операционной системы.