Под Unix существует множество компиляторов и интерпретаторов, но здесь мы будем обсуждать лишь gcc как средство компиляции C-кода, и коротко коснемся использования perl в качестве примера интерпретатора.
GCC
GCC — это набор компиляторов, обладающий очень почтенным возрастом и распространяемый под лицензией GPL. Он известен как инструмент работы с программами на C и C++. Свободная лицензия и повсеместная распространенность на Unix-подобных системах стали залогом его неизменной популярности, хотя есть и более современные альтернативы, использующие инфраструктуру LLVM, такие как Clang.
Основной исполняемый файл gcc лучше представлять не как компилятор в привычном понимании, а слой абстракции над множеством отдельных инструментов программирования, выполняющих парсинг кода, компиляцию, линковку и другие действия. Это значит, что с его помощью можно не просто получить работающий бинарник из кода на C, но детально исследовать все шаги этого сложного процесса, и при необходимости подстроить его под свои нужды.
Курс молодого бойца в компилятор GCC (для языков СС++)
Здесь я не буду обсуждать использование make-файлов, хотя они наверняка понадобятся для любого проекта сложнее, чем в один файл. Make-файлов я коснусь в следующей статье о средствах автоматизации сборки.
Компиляция и сборка объектного кода
Объектный код компилируется вот такой командой:
$ gcc -c example.c -o example.o
Если код верен, будет создан нелинкованный двоичный объектный файл под именем example.o в текущей папке, или выведены сообщения о проблемах. Заглянуть внутрь полученного файла и увидеть его содержимое на языке ассемблера можно так:
$ objdump -D example.o
Как вариант, можно попросить gcc сразу показать итоговый ассемблерный код при помощи параметра -S:
$ gcc -c -S example.c -o example.s
Вывод ассемблерного кода может быть полезно совместить с выводом самого исходника, чего можно добиться, набрав:
$ gcc -c -g -Wa,-a,-ad example.c > example.lst
Препроцессор
Препроцессор C (cpp) обычно используется для подключения заголовочных файлов и определения макросов. Это стандартная часть процесса компиляции gcc, но можно просмотреть генерируемый им код, вызвав cpp напрямую:
$ cpp example.c
Исходный код будет выведен в конечном виде, готовым к компиляции, с замененными макросами и подстановкой включаемых внешних файлов.
Связывание объектов
Один или несколько объектных файлов могут быть связаны в соответствующий исполняемый файл:
$ gcc example.o -o example
В этом примере gcc просто вызывает ld, линковщик GNU. Команда создаст исполняемый файл по имени example .
Компиляция, сборка и связывание
Все вышеперечисленное может быть выполнено в один шаг при помощи команды:
$ gcc example.c -o example
Этот способ проще, но компиляция объектов по отдельности дает некоторый выигрыш в производительности: не нужно компилировать не изменявшийся код, но об этом мы поговорим в следующей статье.
Включение внешних файлов и связывание
Файлы C и заголовочные файлы могу быть явно включены в компиляцию при помощи параметра -l:
Язык C за 100 секунд [перевод на русский]
$ gcc -I/usr/include/somelib.h example.c -o example
Аналогично, если код нужно динамически связать с уже скомпилированной системной библиотекой, доступной в одной из системных папок ( /lib или /usr/lib ), например, ncurses, этого можно добиться использованием ключа -l:
$ gcc -lncurses example.c -o example
Если в процессе компиляции внешних связей много, имеет смысл внести их в переменные окружения:
$ export CFLAGS=-I/usr/include/somelib.h $ export CLIBS=-lncurses $ gcc $CFLAGS $CLIBS example.c -o example
Кстати, Makefile затем и создан, чтобы избавить нас от беспокойства о таких мелочах.
План компиляции
Чтобы посмотреть подробности внутренней кухни gcc, можно добавить ключ -v, и план компиляции будет выведен в стандартный поток вывода ошибок:
$ gcc -v -c example.c -o example.o
Если нет нужды генерировать объектные или исполняемые файлы, то для аккуратности можно использовать -###:
$ gcc -### -c example.c -o example.o
Очень полезно посмотреть, какие действия gcc предпринимает без нашего ведома, кроме того, так мы можем выявить нежелательные шаги при компиляции.
Расширенный вывод сообщений об ошибках
Существует возможность добавить ключи -Wall и/или -pedantic, чтобы gcc предупреждал нас о случаях, которые не обязательно являются ошибками, но могут ими быть:
$ gcc -Wall -pedantic -c example.c -o example.o
Удобно включать такие опции в Makefile или в определении makeprg для Vim, так как они отлично сочетаются с окном quickfix, и помогают писать читабельный, совместимый и безошибочный код.
Профилирование процесса компиляции
Вы можете включить опцию -time, чтобы gcc отображал в тексте вывода время выполения каждого из шагов:
$ gcc -time -c example.c -o example.o
Оптимизация
Gcc имеет ключи оптимизации, указав которые можно попросить его создавать более эффективный объектный код и связанные бинарники за счет увеличения времени компиляции. Я считаю -O2 золотой серединой для выпускаемого кода:
gcc -O1 gcc -O2 gcc -O3
Подобно любой команде Bash, все это можно вызывать прямо из Vim:
:!gcc % -o example
Интерпретаторы
Подход к интерпретируемому коду в Unix-системах иной. В своих примерах я буду использовать Perl, но те же принципы применимы для кода, например, на Python или Ruby.
Inline-код
Можно строку Perl-кода прямо на исполнение интерпретатору любым из перечисленных ниже способов Первый, наверное, самый простой и общеупотребительный способ работы с Perl; второй использует синтаксис heredoc, а третий — это классический конвейер Unix.
$ perl -e ‘print «Hello world.n»;’ $ perl
Конечно, в будничной жизни мы храним код в файле, который можно вызвать прямо вот так:
$ perl hello.pl
Можно проверить синтаксис кода без его выполнения с помощью ключа -c:
$ perl -c hello.pl
Порой хочется использовать скрипт подобно любому исполняемому бинарнику, не беспокоясь о том, что он из себя представляет. Для этого в скрипт добавляют первой строкой так называемый «shebang», указывающий путь к интерпретатору, которому следует передать на исполнение данный файл.
#!/usr/bin/env perl print «Hello, world.n»;
Скрипту после этого можно ставить атрибут исполняемого файла вызовом chmod. Также хорошим тоном считается переименовать файл, убрав расширения, поскольку он теперь считается почти настоящим исполняемым файлом:
$ mv hello $ chmod +x hello
Затем файл можно вызывать напрямую, без указания интерпретатора:
$ ./hello
Вся эта кухня так здорово работает, что многие стандартные утилиты Linux-систем, такие как adduser, в действительности являются скриптами на Perl или Python.
В следующей публикации я расскажу о методах работы с make для сборки проектов, сравнимых с привычными IDE.
Продолжение следует.
Источник: habr.com
1.gcc
Коллекция компиляторов GNU изначально называласьКомпилятор языка GNU C(GNU C Compiler), потому что он мог справиться толькоЯзык C, GCC был быстро расширен после его выпуска, включая внешние интерфейсы для C, C ++, Objective-C, Fortran, Java, Ada и Go, а также библиотеки для этих языков (такие как libstdc ++, libgcj и т. Д.). Первоначальное намерение GCC — компилятор, специально написанный для операционной системы GNU.
Система GNU является полностью свободным программным обеспечением. Здесь «свобода» означает, что она уважает свободу пользователей.
Комплект компилятора GUN содержит несколько внешних процессоров для перевода на разные языки. Конечно, мы фокусируемся на внешнем процессоре GCC на языке Си.
GCC также является многоцелевым компилятором, иными словами, он использует сменные внутренние процессоры для генерации соответствующих исполняемых программ для множества различных компьютерных архитектур.
GCC не только поддерживает множество «диалектов» языка Си, но также может различать различные стандарты языка Си, то есть вы можете использовать параметры командной строки для управления тем стандартом Си, которому должен следовать компилятор при переводе исходного кода. Например, при использовании параметров командной строки -std=c99 При запуске GCC компилятор поддерживает стандарт C99.
GUN99 c99
1.1 Установка
- Команда установки
sudo apt install gcc g++ # Напишите программу в Linux: версия gcc> 4.8.5
gcc -v/—version g++ -v/—version
- Миф 1: gcc может компилировать только код c, а g ++ может компилировать только код c ++. Оба варианта возможны, но, пожалуйста, обратите внимание:
- Суффикс: .c, gcc рассматривает его как программу на C, а g ++ как программу на C ++;
- Суффикс — .cpp, оба будут рассматриваться как программы на C ++, правила грамматики C ++ более строгие.
- На этапе компиляции g ++ вызовет gcc. Для кода c ++ эти два эквивалента, но поскольку команда gcc не может автоматически связываться с библиотекой, используемой программой C ++, для завершения ссылки обычно используется g ++. Для объединения просто скомпилируйте / скомпонуйте все С g ++ это создает иллюзию, что программы на cpp могут использовать только g ++.
- Фактически этот макрос указывает только на то, что компилятор будет интерпретировать код в синтаксисе C или C ++.
- Как упоминалось выше, если используется суффикс .c и используется компилятор gcc, макрос не определен, в противном случае он уже определен.
- Строго говоря, это предложение не является неправильным, но оно вводит в заблуждение концепцию, следует сказать: компиляция может использовать gcc / g ++, а ссылка может использовать g++ или gcc -lstdc++ 。
- Команда gcc не может автоматически связываться с библиотеками, используемыми программами C ++, поэтому для завершения ссылки обычно используется g ++. Но на этапе компиляции g ++ автоматически вызовет gcc, оба эквивалента
Рабочий процесс 1.2 gcc
- Предварительная обработка исходной программы на языке C для генерации .i файл.
- Расширение заголовочного файла
- Замена макроса
- define NUM 10
- int a = NUM
- Комментарий удален
- xxx.c -> xxx.i
- gcc -E xxx.c -o xxx.i
- Предварительно обработанный файл .i компилируется на ассемблере и генерируется .s файл.
- xxx.i -> xxx.s (получить файл сборки)
- gcc -S xxx.i -o xxx.s
- Сборка файлов на ассемблере для создания объектных файлов .o файл.
- xxx.s -> xxx.o (двоичный файл)
- gcc -c xxx.s -o xxx.o
- Различные модули .o Файлы связаны для создания исполняемого файла программы.
- xxx.o -> исполняемая программа (двоичная)
- gcc xxx.o -o xxx
1,3 gcc общие параметры параметров
-E | Предварительная обработка указанного исходного файла без компиляции |
-S | Скомпилируйте указанный исходный файл, но не собирайте |
-c | Скомпилировать и собрать указанный исходный файл, но не ссылаться |
-o [file1] [file2] / [file2] -o [file1] | Скомпилируйте файл file2 в исполняемый файл file1 |
-I directory | Укажите каталог поиска для включаемых файлов |
-g | При компиляции, генерации отладочной информации программа может быть отлажена отладчиком |
-D | Когда программа скомпилирована, укажите макрос |
-w | Не генерирует никаких предупреждающих сообщений |
-Wall | Генерация всех предупреждающих сообщений |
-On | Диапазон значений n: 0 ~ 3. 4 уровня параметров оптимизации компилятора, -O0 означает отсутствие оптимизации, -O1 по умолчанию и -O3 имеет самый высокий уровень оптимизации |
-l | Когда программа скомпилирована, укажите используемую библиотеку |
-L | Укажите путь поиска библиотеки при компиляции. |
-fPIC/fpic | Генерация независимого от местоположения кода |
-shared | Создайте общий объектный файл. Обычно используется при создании общих библиотек |
-std | Укажите диалект C, например: -std = c99, диалект gcc по умолчанию — GNU C |
Параметр -D Сценарий использования: используется при отладке программы, открывает вывод журнала через макрос, указанный в -D
#include //#define DEBUG int main() int a = 10; #ifdef DEBUG printf(«Я программная обезьяна, я не могу лазить по деревьям . n»); #endif for(int i=0; i3; ++i) printf(«hello, GCC. n»); > return 0; >
По умолчанию седьмая строка кода не выводится. Если вы хотите вывести это предложение, вы можете использовать -D
Параметр — на оптимизаторе есть 4 уровня
n Диапазон значений: 0-3
O0 -> не оптимизировано, O1 -> уровень по умолчанию, O3 -> самый высокий уровень
Простейший пример:
int a, b, c, d; a = 10; b = a; c = b; d = c; // Оптимизация: b = 10; c = 10; d = 10;
Параметр -std, указать спецификацию компилятора
c самым ранним стандартом: c89
c99 начал поддерживать текущие привычки письма
int a = 10; func(); int b =5; for(int i=0; i5; ++i)
gcc -std=c99/gnu99 test.c -o test
— Пробелы между параметром DDEBUG и значением являются необязательными
gcc test.c -o test -DDEBUG # define DEBUG
Источник: russianblogs.com
Gnu c что это за программа
GNU Compiler Collection (обычно используется сокращение GCC) — набор компиляторов для различных языков программирования, разработанный в рамках проекта GNU. GCC является свободным программным обеспечением, распространяется фондом свободного программного обеспечения (FSF) на условиях GNU GPL и GNU LGPL и является ключевым компонентом GNU toolchain. Он используется как стандартный компилятор для свободных UNIX-подобных операционных систем.
Изначально названный GNU C Compiler поддерживал только язык Си. Позднее GCC был расширен для компиляции исходных кодов на таких языках программирования, как C++, Objective-C, Java, Фортран, Ada, Go, GAS и D.
С версии 4.2.2 GCC перешёл на лицензию GPLv3.
Перед установкой
Проверить, установлен ли gcc можно в cmd командой
Если gcc установлени, Вы увидите версию
Если gcc не установлен, Вы увидите следующее сообщение
Microsoft Windows [Version 10.0.18363.720] (c) 2019 Microsoft Corporation. All rights reserved. C:UsersAndrei>gcc —version ‘gcc’ is not recognized as an internal or external command, operable program or batch file.
Установка
Для работы в Windows нужен MinGW скачать его можно на сайте nuwen.net/mingw.html
Для этой статьи использовался mingw-17.1.exe
Далее действуйте по инструкции
Двойной клик на mingw-17.1.exe
После установки нужно добавить C:MinGWbin в системную переменную среды PATH.
Если Вы не знаете как это сделать, прочитайте мою статью «Системная переменная PATH»
Теперь команда gcc —version должна возвращать версию компилятора.
Microsoft Windows [Version 10.0.18363.720] (c) 2019 Microsoft Corporation. All rights reserved. C:UsersAndrei>gcc —version gcc (GCC) 9.2.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Если этого не происходит — перезапустите консоль. Если не помогло — перезапустите Windows.
После установки
Итак, Вы установили MinGW написали простейшую программу 3.cpp, компилируете с помощью gcc
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:UsersAndreiAppDataLocalTempccuoNssB.o:3.cpp:(.text+0x28): undefined reference to `std::ios_base::Init::~Init()’ c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:UsersAndreiAppDataLocalTempccuoNssB.o:3.cpp:(.text+0x58): undefined reference to `std::ios_base::Init::Init()’ collect2.exe: error: ld returned 1 exit status
Мой совет — попробуйте g++
Если Вы планируете писать софт, который должен будет работать под UNIX-подобными ОС, например Linux или OpenBSD то устанавливать MinGW не стоит.
Попробуйте добавить в Ваш Windows подсистему для Linux и установить gcc там.
Установка gcc в подсистеме Linux для Windows
sudo apt install build-essentials
Установка Cygwin
Если по каким-то причинам Вам не подходят перечисленные выше варианты — установите cygwin cygwin.com
У меня пока что только негативный опыт работы с ним, но у Вас может получиться лучше.
Установка GCC в Linux
В зависимости от типа Linux выполните
sudo apt -y install gcc
Для Debian , Ubuntu и других deb
sudo yum -y install gcc
Для CentOS , Rocky , RHEL и других rpm
Источник: www.andreyolegovich.ru