Процесс компиляции C состоит из четырех основных этапов: предварительная обработка, компиляция, сборка и компоновка.
Некоторые важные аспекты перед началом работы:
- Исходный код означает удобочитаемые инструкции, написанные пользователями.
- Объектный код означает машинный код или двоичный код.
- Компиляция — это процесс преобразования исходного кода в объектный код, который затем можно выполнить.
- GCC означает Коллекция компиляторов GNU, проще говоря, это компилятор многих языков программирования, включая c.
В качестве примера мы создадим программу на C с именем main.c, которая содержит:
#include<stdio.h> int main(void) { return (0); }
1. Предварительная обработка
На самом первом этапе препроцессор исправляет исходный код. Он добавляет все заголовочные файлы и команды препроцессора (#) в исходный код, следит за тем, чтобы все комментарии, включенные в код, игнорировались, и обрабатывает макросы и дополнительные инструкции для компиляции.
Как посмотреть содержимое предварительной обработки:
gcc -E main.c
Мы используем параметр gcc -E, чтобы указать gcc остановиться после этапа предварительной обработки, чтобы вывод был в форме предварительно обработанного исходного кода.
Вот как выглядят некоторые из последних нескольких строк вывода.
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); # 943 "/usr/include/stdio.h" 3 4 # 2 "main.c" 2 int main(void) { return (0); }
2. Компиляция
На втором этапе процесса компиляции исходный код и выходные данные препроцессора превращаются в инструкции ассемблерного кода.
Чтобы посмотреть содержимое этапа компиляции:
gcc -S main.c
вывод:
main.s
Мы используем опцию gcc -S, чтобы остановить процесс компиляции и не собирать. Вывод показывает инструкции по сборке внутри вновь созданного файла, оканчивающегося на .s.
3. Сборка
Третий этап берет набор ассемблерных инструкций, созданных на этапе компиляции, и превращает их в объектный код.
gcc -c main.c
вывод:
main.o
Мы используем gcc -c для создания объектного файла, который будет иметь то же имя, что и исходный код, но будет заканчиваться на .o вместо .c.
4. Связывание
Заключительный этап берет объектный код, инструкции и вызывает все функции, используемые в библиотеках, чтобы связать их вместе, чтобы сформировать один исполняемый файл.
gcc -o main ./main
Мы используем gcc -o, чтобы поместить результат процесса связывания в файл, вы можете назвать этот файл как хотите. Это же имя файла используется для выполнения файла. При выполнении без имени файла используйте ./a.out вместо имени файла.