Общая схема работы компилятора языка Си
Исходя из назначения компилятора (см. Компиляция и интерпретация), схему работы можно совсем упрощённо записать так:
[ исходный код (source code) ]
⇩
( компилятор (compiler) )
⇩
[ иcполняемый код (executable code) ]
Исходный код — это текст программы, написанный на каком-либо языке программирования.
Компилятор здесь понимается в широком смысле — как цепочка инструментов для компиляции (compiler toolchain).
Исполняемый код (или машинный код) — это инструкции (команды) процессора.
Исходный код хранится в виде простого текстового файла (plain text).
Исполняемый код хранится в виде бинарного (двоичного) файла.
Рассмотрим, что происходит в процессе сборки ("build" или "make") программного проекта, написанного на языке Си, в ходе которой работает и компилятор, более детально (тут предполагается картинка со схемой, намёк на неё оформлен ниже в духе псевдографики):
[ исходный код (source code), ... ]
⇩ ⇩ ... ⇩
+------------------------[ компилятор (compiler) ]-----------------------+
| ( препроцессор (preprocessor) компилятора ) |
| ⇩ ⇩ ... ⇩ |
| [ препроцессированный исходный код (preprocessed source code), ... ] |
| ⇩ ⇩ ... ⇩ |
| ( основная часть компилятора ) |
+------------------------------------------------------------------------+
⇩ ⇩ ... ⇩
[ объектный код (object code) проекта, ... ]
⇩ ⇩ ... ⇩
⇩ ⇩ ... ⇩ ⇐
⇩ ⇩ ... ⇩ ⇐ [ объектный код (object code) библиотек, ... ]
⇩ ⇩ ... ⇩ ⇐
⇩ ⇩ ... ⇩
( компоновщик (linker) )
⇩
[ иcполняемый код (executable code) ]
Термин "препроцессор" можно было бы дословно перевести как "предобработчик", здесь он не имеет никакого отношения к понятию центрального процессора. Задача препроцессора — преобразовать текст программы в соответствии с директивами препроцессора (всё, что начинается с симола #
— например: #include .....
)
Объектный код — это машинный код (команды процессора), но где вместо конкретных адресов программных объектов (глобальных переменных, функций) могут использоваться их имена, чтобы на них сослаться. Обычно это объекты, которые находятся в других объектных файлах, полученных из исходного кода других модулей программы. Компоновщик (или его ещё называют "редактор связей") объединяет объектный код разных модулей (в том числе, внешних библиотек) в один самостоятельный файл с исполняемым кодом.