Что происходит, когда вы вводите «gcc main.c»

Когда вы хотите выполнить код для создания объектного файла, с компьютером необходимо общаться на машинном языке, который представляет собой двоичный код (с основанием 2). К сожалению (и к счастью), люди общаются на языке выше двоичного. Следовательно, почему мы используем язык более высокого уровня, такой как Python, Ruby и, в данном случае, язык программирования C. Но для того, чтобы компьютеры могли выполнять наш код C, мы должны скомпилировать код с помощью команды Unix:
GCC main.c
Прежде чем продолжить процесс компиляции, давайте остановимся на инструменте, с помощью которого мы можем компилировать: GCC.
Аббревиатура GCC означает GNU Compiler Collection. Это интегрированный компилятор проекта GNU для C и некоторых других языков; он способен получать исходную программу на любом из этих языков и генерировать исполняемую двоичную программу на языке машины, на которой она должна выполняться.
Этапы от программы в исходном коде до ее выполнения следующие:
** В конце вы найдете пример **
Шаг 1. Препроцессор
Когда мы запускаем gcc main.c, программа main.c обрабатывается препроцессором. Есть три вещи, которые делает препроцессор:
- Во-первых: удаляет все комментарии из нашей программы main.c
- Во-вторых: он включает код из заголовка и исходного файла
- Третье: заменяет макросы (если они используются в программе) кодом.
Чтобы получить результат компиляции файла ‘.c’ в часть препроцессора, мы используем тег -E
Шаг 2. Компилятор
Затем код, сгенерированный препроцессором, передается компилятору, и компилятор генерирует из него ассемблерный код.
Чтобы получить результат компиляции файла .c в часть компилятора, мы используем тег -C
Шаг 3. Ассемблер
Поскольку наш компьютер все еще не может понять ассемблерный код, ассемблер преобразует ассемблерный код в двоичный код (тот, который наша машина действительно может интерпретировать).
Чтобы получить результат компиляции файла .c в сборочную часть, мы используем тег -S
Шаг 4. Связывание
Теперь компоновщик — это тот, кто связывает весь этот бинарный код из нашей программы с библиотеками и объединяет их в один код, который мы получаем в виде исполняемого файла (a.out).
Но мы, конечно, не хотим чтобы все наши программы назывались одинаково, не так ли? Таким образом, мы можем использовать опцию -o с нашей командой gcc, которая позволяет нам называть наш исполняемый файл как угодно (например, tic_tac_toe).
Чтобы получить окончательный исполняемый файл, как упоминалось ранее, мы используем тег -o
Пример
У меня есть следующая программа, которая печатает «Hello World»:

Давайте посмотрим, каков результат первого шага компиляции: предварительной обработки. Для этого компилируем с тегом -E.

Хотя предыдущий показывает что-то отличное от оригинала, его все же можно прочитать и понять. Следующий шаг уже не имеет значения, поскольку он выглядит совершенно неразборчивым.

Следующий шаг — переход с языка Си на Ассемблер.

Последний шаг — это тот, который позволяет нам связать все вышеперечисленное и оставить нас с исполняемым результатом:

Чтобы углубиться в команды GCC, я приглашаю вас посетить MAN-СТРАНИЦУ команды.