Процесс компиляции 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 вместо имени файла.