- Компилятор GCC
- GNU Compiler Collection, первые шаги
- Установка GCC в Ubuntu
- Набор компиляторов GCC
- Установка GCC в Ubuntu
- Использование GCC в Ubuntu
- Выводы
- Unix как IDE: Компиляция
- Компиляция и сборка объектного кода
- Препроцессор
- Связывание объектов
- Компиляция, сборка и связывание
- Включение внешних файлов и связывание
- План компиляции
- Расширенный вывод сообщений об ошибках
- Профилирование процесса компиляции
- Оптимизация
- Интерпретаторы
- Inline-код
Компилятор GCC
GСС — это свободно доступный оптимизирующий компилятор для языков C, C++.
Программа gcc, запускаемая из командной строки, представяляет собой надстройку над группой компиляторов. В зависимости от расширений имен файлов, передаваемых в качестве параметров, и дополнительных опций, gcc запускает необходимые препроцессоры, компиляторы, линкеры.
Файлы с расширением .cc или .C рассматриваются, как файлы на языке C++, файлы с расширением .c как программы на языке C, а файлы c расширением .o считаются объектными.
Чтобы откомпилировать исходный код C++, находящийся в файле F.cc, и создать объектный файл F.o, необходимо выполнить команду:
Опция –c означает «только компиляция».
Чтобы скомпоновать один или несколько объектных файлов, полученных из исходного кода — F1.o, F2.o, . — в единый исполняемый файл F, необходимо ввести команду:
Опция -o задает имя исполняемого файла.
Можно совместить два этапа обработки — компиляцию и компоновку — в один общий этап с помощью команды:
— возможные дополнительные опции компиляции и компоновки. Опция –lg++ указывает на необходимость подключить стандартную библиотеку языка С++, — возможные дополнительные библиотеки.
После компоновки будет создан исполняемый файл F, который можно запустить с помощью команды
Опции компиляции
Среди множества опций компиляции и компоновки наиболее часто употребляются следующие:
Источник
GNU Compiler Collection, первые шаги
Эта заметка призвана на простых примерах познакомить начинающего nix-разработчика с инструментами GNU, в частности с компилятором GCC.
С его помощью мы и создадим простейшую программу. По большому счету все, как обычно. Заводим специальную папку, в которой будет размещаться проект.
Создаем в ней файл с именем: hello.c
Открываем файл в любом текстовом редакторе и пишем простейший код:
#include
int main(void)
<
printf(«Hello world!»);
return(0);
>
Сохраняем файл и выполняем команду: gcc hello.c
В созданной нами папке появился новый файл — a.out, это название присваивается по умолчанию, если специально не задано другого.
Это и есть исполняемый файл. Попробуем его запустить, для этого в консоли набираем: ./a.out
И радуемся в связи с первой написанной программой в линуксе!
Идем далее. При запуске исполняемого файла, если мы укажем только его название, система будет искать его в каталогах /usr/bin и /usr/local/bin, и, естественно, не найдет. Первый из них предназначен для размещения стабильных версий программ, как правило, входящих в дистрибутив Linux. Второй – для программ, устанавливаемых самим пользователем (за стабильность которых никто не ручается). По умолчанию, при сборке программы, устанавливаются в каталог /usr/local/bin.
Флаги используемые при компиляции
Флаг -o используем чтобы указать определенное имя получаемому исполняемому файлу: gcc hello.c -o say_hello
Флаг -E используем чтобы посмотреть, что получается после работы препроцессора. Этот флаг останавливает выполнение программы, как раз на этапе обработки препроцессором. В результате получается файл исходного кода с включённым в него содержимым заголовочных файлов.
Выподняем/смотрим: gcc -E hello.c -o hello.cpp
Флаг -с используем для создания объектных файлов (аналог *.obj): gcc -c kalkul.c
Название получаемого файла такое же, но компилятор изменяет расширение .c на .o (но указать можно и вручную).
Флаг -x используем, если создаётся объектный файл из исходника, уже обработанного препроцессором (например такого, какой мы получили выше), мы должны обязательно указать явно, что компилируемый файл является файлом исходного кода, обработанный препроцессором, и имеющий теги препроцессора. В противном случае он будет обрабатываться, как обычный файл C++, без учёта тегов препроцессора, а значит связь с объявленными функциями не будет устанавливаться.
Файл C++, обработанный препроцессором обозначается cpp-output:
gcc -x cpp-output -c hello.cpp
Собирается проект следующим образом: gcc hello.o -o say_hello
Запускаем: ./say_hello
Для чего нужна вся эта возня с промежуточными этапами?
Программы редко состоят из одного файла. Как правило исходных файлов несколько, и они объединены в проект. И в некоторых исключительных случаях программу приходится компоновать из нескольких частей, написанных, возможно, на разных языках. В этом случае приходится запускать компиляторы разных языков, чтобы каждый получил объектный файл из своего исходника, а затем уже эти полученные объектные файлы компоновать в исполняемую программу.
Источник
Установка GCC в Ubuntu
Большинство программ в Linux написаны на C или С++, и если вы хотите собирать их из исходников, то вам обязательно понадобиться компилятор, также он понадобиться, если захотите начать писать свои программы на одном из этих языков.
Существует два основных компилятора в Linux — это GCC и Clang, они похожи по своим возможностям, но так сложилось, что первый считается стандартом для Ubuntu. GCC расшифровывается как GNU Compiler Collection. В этой статье мы рассмотрим, как выполняется установка GCC в Ubuntu, а также рассмотрим базовые приемы работы с этим набором программ в терминале.
Набор компиляторов GCC
Все программы представляют собой набор машинных команд, которые выполняются процессором. Эти команды — последовательность бит. Но писать программы наборами бит очень неудобно, поэтому были придуманы языки программирования высокого уровня. Код на языке программирования хорошо читаем и понятен для человека, а когда из него нужно сделать программу, компилятор ubuntu преобразует все в машинные команды.
В базовую поставку компилятора входят такие программы:
- libc6-dev — заголовочные файлы стандартной библиотеки Си;
- libstdc++6-dev — заголовочные файлы стандартной библиотеки С++;
- gcc — компилятор языка программирования Си;
- g++ — компилятор языка программирования C++;
- make — утилита для организации сборки нескольких файлов;
- dpkg-dev — инструменты сборки пакетов deb.
Все эти пакеты являются зависимостями пакета build-essential, поэтому для установки всего необходимого достаточно установить этот пакет.
Установка GCC в Ubuntu
Если вас устраивает текущая версия GCC, которая есть в официальных репозиториях дистрибутива, то вам достаточно установить пакет build-essential. Для этого выполните команду:
sudo apt -y install build-essential
После завершения установки все необходимое для компиляции программ будет установлено. И вы сможете использовать компилятор. Рассмотрим версии и расположение файлов компилятора:
whereis gcc make
Если необходима более новая версия компилятора, например, на данный момент последняя версия — 11, то можно использовать PPA разработчиков с тестовыми сборками. Для добавления PPA в систему выполните команды:
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test && sudo apt update
Далее установите сам компилятор:
sudo apt -y install gcc-snapshot && sudo apt -y install gcc-11g++-11
Это не заменит ваш текущий компилятор на новый. В системе просто появятся 2 версии компиляторов gcc-11 и g++11, которые вы можете использовать для своих программ. Это лучший вариант на данный момент, но если вы хотите все же сделать gcc-9 компилятором по умолчанию, выполните:
sudo update-alternatives —install /usr/bin/gcc gcc /usr/bin/gcc-9 60 —slave /usr/bin/g++ g++ /usr/bin/g++-9
Готово, теперь вы можете проверить версию gcc-6:
Установка GCC в Ubuntu завершена, и можно переходить к сборке программ. Для удаления компилятора достаточно удалить пакет build-essential при помощи команды:
sudo apt purge -y build-essential && sudo apt-y autoremove
Использование GCC в Ubuntu
Рассмотрим пример компиляции минимальной программы hello.c для освоения работы с gcc. Вот код программы, откройте любой текстовый редактор и сохраните его в файле с названием hello.c:
#include
int main(void) <
printf(«Hello, world!\n»);
return 0;
>
Теперь запустим сборку программы:
Когда сборка программы будет завершена, на выходе появится файл с названием a.out. a.out –это имя исполняемого файла, которое по умолчанию, сгенерировано при помощи gcc. Далее можно запустить данный файл:
Готово, компилятор прекрасно работает в системе, и теперь можно писать свои программы или собирать чужие.
Выводы
В этой статье мы рассмотрели, как установить gcc в Ubuntu 20.04, это один из самых популярных компиляторов для этой операционной системы. И устанавливается он очень просто, если у вас остались вопросы, спрашивайте в комментариях!
На завершение видео с демонстрацией самого процесса:
Источник
Unix как IDE: Компиляция
Под Unix существует множество компиляторов и интерпретаторов, но здесь мы будем обсуждать лишь gcc как средство компиляции C-кода, и коротко коснемся использования perl в качестве примера интерпретатора.
GCC — это набор компиляторов, обладающий очень почтенным возрастом и распространяемый под лицензией GPL. Он известен как инструмент работы с программами на C и C++. Свободная лицензия и повсеместная распространенность на Unix-подобных системах стали залогом его неизменной популярности, хотя есть и более современные альтернативы, использующие инфраструктуру LLVM, такие как Clang.
Основной исполняемый файл gcc лучше представлять не как компилятор в привычном понимании, а слой абстракции над множеством отдельных инструментов программирования, выполняющих парсинг кода, компиляцию, линковку и другие действия. Это значит, что с его помощью можно не просто получить работающий бинарник из кода на C, но детально исследовать все шаги этого сложного процесса, и при необходимости подстроить его под свои нужды.
Здесь я не буду обсуждать использование make-файлов, хотя они наверняка понадобятся для любого проекта сложнее, чем в один файл. Make-файлов я коснусь в следующей статье о средствах автоматизации сборки.
Компиляция и сборка объектного кода
Объектный код компилируется вот такой командой:
Если код верен, будет создан нелинкованный двоичный объектный файл под именем example.o в текущей папке, или выведены сообщения о проблемах. Заглянуть внутрь полученного файла и увидеть его содержимое на языке ассемблера можно так:
Как вариант, можно попросить gcc сразу показать итоговый ассемблерный код при помощи параметра -S:
Вывод ассемблерного кода может быть полезно совместить с выводом самого исходника, чего можно добиться, набрав:
Препроцессор
Препроцессор C (cpp) обычно используется для подключения заголовочных файлов и определения макросов. Это стандартная часть процесса компиляции gcc, но можно просмотреть генерируемый им код, вызвав cpp напрямую:
Исходный код будет выведен в конечном виде, готовым к компиляции, с замененными макросами и подстановкой включаемых внешних файлов.
Связывание объектов
Один или несколько объектных файлов могут быть связаны в соответствующий исполняемый файл:
В этом примере gcc просто вызывает ld, линковщик GNU. Команда создаст исполняемый файл по имени example .
Компиляция, сборка и связывание
Все вышеперечисленное может быть выполнено в один шаг при помощи команды:
Этот способ проще, но компиляция объектов по отдельности дает некоторый выигрыш в производительности: не нужно компилировать не изменявшийся код, но об этом мы поговорим в следующей статье.
Включение внешних файлов и связывание
Файлы C и заголовочные файлы могу быть явно включены в компиляцию при помощи параметра -l:
Аналогично, если код нужно динамически связать с уже скомпилированной системной библиотекой, доступной в одной из системных папок ( /lib или /usr/lib ), например, ncurses, этого можно добиться использованием ключа -l:
Если в процессе компиляции внешних связей много, имеет смысл внести их в переменные окружения:
Кстати, Makefile затем и создан, чтобы избавить нас от беспокойства о таких мелочах.
План компиляции
Чтобы посмотреть подробности внутренней кухни gcc, можно добавить ключ -v, и план компиляции будет выведен в стандартный поток вывода ошибок:
Если нет нужды генерировать объектные или исполняемые файлы, то для аккуратности можно использовать -###:
Очень полезно посмотреть, какие действия gcc предпринимает без нашего ведома, кроме того, так мы можем выявить нежелательные шаги при компиляции.
Расширенный вывод сообщений об ошибках
Существует возможность добавить ключи -Wall и/или -pedantic, чтобы gcc предупреждал нас о случаях, которые не обязательно являются ошибками, но могут ими быть:
Удобно включать такие опции в Makefile или в определении makeprg для Vim, так как они отлично сочетаются с окном quickfix, и помогают писать читабельный, совместимый и безошибочный код.
Профилирование процесса компиляции
Вы можете включить опцию -time, чтобы gcc отображал в тексте вывода время выполения каждого из шагов:
Оптимизация
Gcc имеет ключи оптимизации, указав которые можно попросить его создавать более эффективный объектный код и связанные бинарники за счет увеличения времени компиляции. Я считаю -O2 золотой серединой для выпускаемого кода:
Подобно любой команде Bash, все это можно вызывать прямо из Vim:
Интерпретаторы
Подход к интерпретируемому коду в Unix-системах иной. В своих примерах я буду использовать Perl, но те же принципы применимы для кода, например, на Python или Ruby.
Inline-код
Можно строку Perl-кода прямо на исполнение интерпретатору любым из перечисленных ниже способов Первый, наверное, самый простой и общеупотребительный способ работы с Perl; второй использует синтаксис heredoc, а третий — это классический конвейер Unix.
Конечно, в будничной жизни мы храним код в файле, который можно вызвать прямо вот так:
Можно проверить синтаксис кода без его выполнения с помощью ключа -c:
Порой хочется использовать скрипт подобно любому исполняемому бинарнику, не беспокоясь о том, что он из себя представляет. Для этого в скрипт добавляют первой строкой так называемый «shebang«, указывающий путь к интерпретатору, которому следует передать на исполнение данный файл.
Скрипту после этого можно ставить атрибут исполняемого файла вызовом chmod. Также хорошим тоном считается переименовать файл, убрав расширения, поскольку он теперь считается почти настоящим исполняемым файлом:
Затем файл можно вызывать напрямую, без указания интерпретатора:
Вся эта кухня так здорово работает, что многие стандартные утилиты Linux-систем, такие как adduser, в действительности являются скриптами на Perl или Python.
В следующей публикации я расскажу о методах работы с make для сборки проектов, сравнимых с привычными IDE.
Источник