Вы написали программу на C и сохранили исходный код в main.c. Отлично, что теперь? Поскольку C является компилируемым языком, вам необходимо скомпилировать файл main.c, прежде чем вы сможете его запустить. Это когда вы используете gcc, который является компилятором C проекта GNU. Хотя в gcc есть опции для компиляции других языков, таких как C++, этот пост будет посвящен компиляции программ на C.

Чтобы использовать gcc для компиляции вашего файла main.c, вам нужно ввести gcc main.c, как показано выше. Чтобы скомпилировать ваш файл, компилятор (gcc) выполняет несколько шагов, чтобы перейти от main.c к файлу, который вы можете выполнить. По умолчанию этот исполняемый файл называется a.out. Однако вы можете указать имя файла, введя gcc -o исполняемый файл main.c, где исполняемый файл — это имя исполняемого файла.

Как gcc компилирует ваш файл

Прежде чем gcc сможет скомпилировать файл, необходимо подготовить файл для преобразования в формат, понятный компьютеру. Этот шаг выполняется через препроцессор. Он создает промежуточный файл, который будет передан компилятору для продолжения процесса.

Затем компилятор использует этот промежуточный файл для создания ассемблерного кода. Ассемблерный код ближе к языку, который понимает компьютер. Он по-прежнему удобочитаем для человека, но зависит от машины. Это означает, что ассемблерный код не является переносимым, поэтому то, что будет работать на одной машине, не обязательно будет работать на другой.

Затем ассемблер возьмет машинный код и создаст объектный код. Код объекта записывается в двоичном формате (0 и 1). Это тип файла, который может прочитать ваш компьютер.

Наконец, компоновщик свяжет все файлы объектного кода и библиотечные файлы, необходимые вашему компьютеру для запуска вашей программы. Полученный файл — это файл, который вы можете выполнить.

Препроцессор

Как упоминалось выше, препроцессор создает файл, который может использовать ваш компилятор. Чтобы увидеть, что произойдет после того, как препроцессор обработает ваш файл, вы можете использовать параметр -E, как показано ниже. (Я также сохранил информацию, созданную препроцессором, в файле c.) На рисунке ниже также показаны последние 15 строк промежуточного файла, созданного препроцессором.

Как видно из рисунка, последние несколько строк файла — это метод main из файла main.c. Но как насчет того, что над ним? Препроцессор добавит код из заголовочного файла и код из любых макросов, чтобы компилятор имел всю необходимую информацию при компиляции файла. Он также удаляет любые комментарии, которые есть в файле, поскольку компьютер не будет их выполнять.

Компилятор

Далее компилятор берет промежуточный файл и генерирует ассемблерный код. Это делает код более значимым для компьютера, на котором вы его компилируете. Это также означает, что вы должны скомпилировать код на каждом компьютере, на котором вы планируете выполнять файл, поскольку код сборки может быть разным на каждом компьютере. Можно остановить gcc после того, как он скомпилирует файл, используя опцию -S, как показано ниже.

Ассемблерный код будет сохранен в файле с тем же именем, что и у файла c, но с расширением .s. В приведенном выше примере файл c называется main.c, а ассемблерный код находится в main.s.

Ассемблер

Затем ассемблер возьмет ассемблерный код из файла main.s и превратит его в объектный код. Как и в предыдущих частях, gcc имеет параметр (-c), чтобы остановить процесс компиляции после ассемблера. Для этого введите gcc -c main.c. Он сохранит двоичный код в файле o с тем же именем, что и файл. Таким образом, для c-файла main.c объектным кодом будет main.o. На рисунке ниже показано, как выглядит объектный код для нашей программы main.c.

Линкер

Наконец, компоновщик возьмет все файлы объектного кода и библиотечные файлы, необходимые для выполнения программы. Так как это последний шаг, здесь нет возможности завершить компиляцию. Таким образом, результирующий файл на этом шаге — это то, что вы получите, набрав gcc main.c.

По умолчанию результирующий исполняемый файл называется a.out. Можно указать имя файла с помощью опции (-o). Так, например, если вы хотите скомпилировать main.c и использовать файл executable для выполнения файла, вы должны ввести следующее:

gcc -o исполняемый файл main.c.

Резюме

Если вы хотите запустить файл C, вы должны сначала скомпилировать код, чтобы получить исполняемый файл. Для этого вы используете gcc main.c, где main.c — ваш C-файл. Чтобы сделать файл исполняемым, компилятор (gcc) сначала подготавливает файл к компиляции, убедившись, что в файле есть вся информация, необходимая компьютеру для выполнения задачи, и нет информации, которая ему не нужна. Затем он компилирует файл в ассемблерный код, который ближе к языку, который может прочитать компьютер, и переводит его в объектный код, который является языком, который может читать компьютер. Наконец, все объектные файлы и библиотечные файлы, необходимые программе, объединяются в один файл, который может выполняться компьютером.