Gcc linux как работать

Обновлено: 06.07.2024

Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal

Февраль 16, 2016

Основы

GCC входит в состав любого дистрибутива Linux и, как правило, устанавливается по умолчанию. Интерфейс GCC, это стандартный интерфейс компилятора на UNIX платформе, уходящий своими корнями в конец 60-х, начало 70-х годов прошлого века - интерфейс командной строки. Не стоит пугаться, за прошедшее время механизм взаимодействия с пользователем был отточен до возможного в данном случае совершенства, и работать с GCC (при наличии нескольких дополнительных утилит и путного текстового редактора) проще, чем с любой из современных визуальных IDE. Авторы набора постарались максимально автоматизировать процесс компиляции и сборки приложений. Пользователь вызывает управляющую программу gcc, она интерпретирует переданные аргументы командной строки (опции и имена файлов) и для каждого входного файла, в соответствии с использованным языком программирования, запускает свой компилятор, затем, если это необходимо, gcc автоматически вызывает ассемблер и линковщик (компоновщик).

Любопытно, компиляторы одни из немногих приложений UNIX для которых не безразлично расширение файлов. По расширению GCC определяет что за файл перед ним и, что с ним нужно (можно) сделать. Файлы исходного кода на языке C должны иметь расширение .c, на языке C++, как вариант, .cpp, заголовочные файлы на языке C .h, объектные файлы .o и так далее. Если использовать неправильное расширение, gcc будет работать не корректно (если вообще согласиться, что-либо делать).

Перейдём к практике. Напишем, откомпилируем и исполним какую-нибудь незамысловатую программу. Не будем оригинальничать, в качестве исходного файла примера программы на языке C сотворим файл с вот таким содержимым:

Теперь в каталоге c hello.c отдадим команду:

Через несколько долей секунды в каталоге появиться файл a.out:

Это и есть готовый исполняемый файл нашей программы. По умолчанию gcc присваивает выходному исполняемому файлу имя a.out (когда-то очень давно это имя означало assembler output).

Запустим получившийся программный продукт:

Почему в команде запуска на исполнение файла из текущего каталога необходимо явно указывать путь к файлу? Если путь к исполняемому файлу не указан явно, оболочка, интерпретируя команды, ищет файл в каталогах, список которых задан системной переменной PATH.

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin: /usr/bin:/sbin:/bin:/usr/games

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

Почему не рекомендуется вносить . в PATH? Считается, что в реальной многопользовательской системе всегда найдется какой-нибудь нехороший человек, который разместит в общедоступном каталоге вредоносную программу с именем исполняемого файла, совпадающим с именем какой-нибудь команды, часто вызываемой местным администратором с правами суперпользователя. Заговор удастся если . стоит в начале списка каталогов.

Утилита file выводит информацию о типе (с точки зрения системы) переданного в коммандной строке файла, для некоторых типов файлов выводит всякие дополнительные сведения касающиеся содержимого файла.

$ file hello.c
hello.c: ASCII C program text
$ file annotation.doc
annotation.doc: CDF V2 Document, Little Endian, Os: Windows, Version 5.1, Code page: 1251, Author: MIH, Template: Normal.dot, Last Saved By: MIH, Revision Number: 83, Name of Creating Application: Microsoft Office Word, Total Editing Time: 09:37:00, Last Printed: Thu Jan 22 07:31:00 2009, Create Time/Date: Mon Jan 12 07:36:00 2009, Last Saved Time/Date: Thu Jan 22 07:34:00 2009, Number of Pages: 1, Number of Words: 3094, Number of Characters: 17637, Security: 0

Вот собственно и всё, что требуется от пользователя для успешного применения gcc :)

Имя выходного исполняемого файла (как впрочем и любого другого файла формируемого gcc) можно изменить с помощью опции -o:

$ gcc -o hello hello.c
$ ls
hello hello.c
$ ./hello
Hello World

В нашем примере функция main() возвращает казалось бы ни кому не нужное значение 0. В UNIX-подобных системах, по завершении работы программы, принято возвращать в командную оболочку целое число - в случае успешного завершения ноль, любое другое в противном случае. Интерпретатор оболочки автоматически присвоит полученное значение переменной среды с именем ?. Просмотреть её содержимое можно с помощью команды echo $?:

Выше было сказано, что gcc это управляющая программа, предназначенная для автоматизации процесса компиляции. Посмотрим что же на самом деле происходит в результате исполнения команды gcc hello.c.

Процесс компиляции можно разбить на 4 основных этапа: обработка препроцессором, собственно компиляция, ассемблирование, линковка (связывание).

Опции gcc позволяют прервать процесс на любом из этих этапов.

Воспользовавшись опцией -E дальнейшие действия gcc можно прервать и просмотреть содержимое файла, обработанного препроцессором.

После обработки препроцессором исходный текст нашей программы разбух и приобрел не удобочитаемый вид. Код, который мы когда-то собственноручно набили, свелся к нескольким строчкам в самом конце файла. Причина - подключение заголовочного файла стандартной библиотеки C. Заголовочный файл stdio.h сам по себе содержит много всего разного да ещё требует включения других заголовочных файлов.

Обратите внимание на расширение файла hello.i. По соглашениям gcc расширение .i соответствует файлам с исходным кодом на языке C не требующим обработки препроцессором. Такие файлы компилируются минуя препроцессор:

$ gcc -o hello hello.i
$ ls
hello hello.c hello.i
$ ./hello
Hello World

После препроцессинга наступает очередь компиляции. Компилятор преобразует исходный текст программы на языке высокого уровня в код на языке ассемблера.

Значение слова компиляция размыто. Википедисты, например, считают, ссылаясь на международные стандарты, что компиляция это "преобразование программой-компилятором исходного текста какой-либо программы, написанного на языке программирования высокого уровня, в язык, близкий к машинному, или в объектный код." В принципе это определение нам подходит, язык ассемблера действительно ближе к машинному, чем C. Но в обыденной жизни под компиляцией чаще всего понимают просто любую операцию, преобразующую исходный код программы на каком-либо языке программирования в исполняемый код. То есть процесс, включающий все четыре означенных выше, этапа также может быть назван компиляцией. Подобная неоднозначность присутствует и в настоящем тексте. С другой стороны, операцию преобразования исходного текста программы в код на языке ассемблера можно обозначить и словом трансляция - "преобразование программы, представленной на одном из языков программирования, в программу на другом языке и, в определённом смысле, равносильную первой".

Остановить процесс создания исполняемого файла по завершении компиляции позволяет опция -S:

В каталоге появился файл hello.s, содержащий реализацию программы на языке ассемблера. Обратите внимание, задавать имя выходного файла с помощью опции -o в данном случае не потребовалось, gcc автоматически его сгенерировал, заменив в имени исходного файла расширение .c на .s. Для большинства основных операций gcc имя выходного файла формируется путем подобной замены. Расширение .s стандартное для файлов с исходным кодом на языке ассемблера.

Получить исполняемый код разумеется можно и из файла hello.s:

$ gcc -o hello hello.s
$ ls
hello hello.c hello.s
$ ./hello
Hello World

Следующий этап операция ассмеблирования - трансляция кода на языке ассемблера в машинный код. Результат операции - объектный файл. Объектный файл содержит блоки готового к исполнению машинного кода, блоки данных, а также список определенных в файле функций и внешних переменных (таблицу символов), но при этом в нем не заданы абсолютные адреса ссылок на функции и данные. Объектный файл не может быть запущен на исполнение непосредственно, но в дальнейшем (на этапе линковки) может быть объединен с другими объектными файлами (при этом, в соответствии с таблицами символов, будут вычислены и заполнены адреса существующих между файлами перекрестных ссылок). Опция gcc -c, останавливает процесс по завершении этапа ассемблирования:

$ gcc -c hello.c
$ ls
hello.c hello.o
$ file hello.o
hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

Для объектных файлов принято стандартное расширение .o.

Если полученный объектный файл hello.o передать линковщику, последний вычислит адреса ссылок, добавит код запуска и завершения программы, код вызова библиотечных функций и в результате мы будем обладать готовым исполняемым файлом программы.

$ gcc -o hello hello.o
$ ls
hello hello.c hello.o
$ ./hello
Hello World

То, что мы сейчас проделали (вернее gcc проделал за нас) и есть содержание последнего этапа - линковки (связывания, компоновки).

Ну вот пожалуй о компиляции и все. Теперь коснемся некоторых, на мой взгляд важных, опций gcc.

Опция -Iпуть/к/каталогу/с/заголовочными/файлам и - добавляет указанный каталог к списку путей поиска заголовочных файлов. Каталог, добавленный опцией -I просматривается первым, затем поиск продолжается в стандартных системных каталогах. Если опций -I несколько, заданные ими каталоги просматриваются слева на право, по мере появления опций.

Опция -Wall - выводит предупреждения, вызванные потенциальными ошибками в коде, не препятствующими компиляции программы, но способными привести, по мнению компилятора, к тем или иным проблемам при её исполнении. Важная и полезная опция, разработчики gcc рекомендуют пользоваться ей всегда. Например масса предупреждений будет выдана при попытке компиляции вот такого файла:

$ gcc -o remark remark.c
$ gcc -Wall -o remark remark.c
remark.c:7: warning: return type defaults to ‘int’
remark.c: In function ‘main’:
remark.c:13: warning: statement with no effect
remark.c:9: warning: unused variable ‘a’
remark.c:21: warning: control reaches end of non-void function
remark.c: At top level:
remark.c:3: warning: ‘k’ defined but not used
remark.c:4: warning: ‘l’ declared ‘static’ but never defined
remark.c: In function ‘main’:
remark.c:15: warning: ‘c’ is used uninitialized in this function
remark.c:19: warning: ‘p’ is used uninitialized in this function

Опция -Werror - превращает все предупреждения в ошибки. В случае появления предупреждения прерывает процесс компиляции. Используется совместно с опцией -Wall.

$ gcc -Werror -o remark remark.c
$ gcc -Werror -Wall -o remark remark.c
cc1: warnings being treated as errors
remark.c:7: error: return type defaults to ‘int’
remark.c: In function ‘main’:
remark.c:13: error: statement with no effect
remark.c:9: error: unused variable ‘a’

Опция -g - помещает в объектный или исполняемый файл информацию необходимую для работы отладчика gdb. При сборке какого-либо проекта с целью последующей отладки, опцию -g необходимо включать как на этапе компиляции так и на этапе компоновки.

Опции -O1, -O2, -O3 - задают уровень оптимизации кода генерируемого компилятором. С увеличением номера, степень оптимизации возрастает. Действие опций можно увидеть вот на таком примере.

Компиляция с уровнем оптимизации по умолчанию:

Компиляция с максимальным уровнем оптимизации:

Во втором случае в полученном коде даже нет намёка на какой-либо цикл. Действительно, значение i, можно вычислить ещё на этапе компиляции, что и было сделано.

Увы, для реальных проектов разница в производительности при различных уровнях оптимизации практически не заметна.

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

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

Опция -march=architecture - задает целевую архитектуру процессора. Список поддерживаемых архитектур обширен, например, для процессоров семейства Intel/AMD можно задать i386, pentium, prescott, opteron-sse3 и т.д. Пользователи бинарных дистрибутивов должны иметь в виду, что для корректной работы программ с указанной опцией желательно, что бы и все подключаемые библиотеки были откомпилированы с той же опцией.

Об опциях передаваемых линковщику будет сказано ниже.

Собственно о компиляции все. Далее поговорим о раздельной компиляции и создании библиотек.

Выше было сказано, что gcc определяет тип (язык программирования) переданных файлов по их расширению и, в соответствии с угаданным типом (языком), производит действия над ними. Пользователь обязан следить за расширениями создаваемых файлов, выбирая их так, как того требуют соглашения gcc. В действительности gcc можно подсовывать файлы с произвольными именами. Опция gcc -x позволяет явно указать язык программирования компилируемых файлов. Действие опции распространяется на все последующие перечисленные в команде файлы (вплоть до появления следующей опции -x). Возможные аргументы опции:

Назначение аргументов должно быть понятно из их написания (здесь cpp не имеет ни какого отношения к C++, это файл исходного кода предварительно обработанный препроцессором). Проверим:

$ mv hello.c hello.txt
$ gcc -Wall -x c -o hello hello.txt
$ ./hello
Hello World

Раздельная компиляция

Сильной стороной языков C/C++ является возможность разделять исходный код программы по нескольким файлам. Даже можно сказать больше - возможность раздельной компиляции это основа языка, без неё эффективное использование C не мыслимо. Именно мультифайловое программирование позволяет реализовать на C крупные проекты, например такие как Linux (здесь под словом Linux подразумевается как ядро, так и система в целом). Что даёт раздельная компиляция программисту?

1. Позволяет сделать код программы (проекта) более удобочитаемым. Файл исходника на несколько десятков экранов становиться практически неохватным. Если, в соответствии с некой (заранее продуманной) логикой, разбить его на ряд небольших фрагментов (каждый в отдельном файле), совладать со сложностью проекта будет гораздо проще.

2. Позволяет сократить время повторной компиляции проекта. Если изменения внесены в один файл нет смысла перекомпилировать весь проект, достаточно заново откомпилировать только этот изменённый файл.

3. Позволяет распределить работу над проектом между несколькими разработчиками. Каждый программист творит и отлаживает свою часть проекта, но в любой момент можно будет собрать (пересобрать) все получающиеся наработки в конечный продукт.

4. Без раздельной компиляции не существовало бы библиотек. Посредством библиотек реализовано повторное использование и распространение кода на C/C++, причем кода бинарного, что позволяет с одной стороны предоставить разработчикам простой механизм включения его в свои программы, с другой стороны скрыть от них конкретные детали реализации. Работая над проектом, всегда стоит задумываться над тем, а не понадобиться что-либо из уже сделанного когда-нибудь в будущем? Может стоит заранее выделить и оформить часть кода как библиотеку? По моему, такой подход, существенно упрощает жизнь и экономит массу времени.

GCC, разумеется, поддерживает раздельную компиляцию, причем не требует от пользователя каких либо специальных указаний. В общем все очень просто.

Вот практический пример (правда весьма и весьма условный).

Набор файлов исходного кода:

В общем имеем вот что:

$ ls
first.c first.h main.c second.c second.h
Все это хозяйство можно скомпилировать в одну команду:

$ gcc -Wall -o main main.c first.c second.c
$ ./main
First function.
Second function.
Main function.

Только это не даст нам практически ни каких бонусов, ну за исключением более структурированного и удобочитаемого кода, разнесённого по нескольким файлам. Все перечисленные выше преимущества появятся в случае такого подхода к компиляции:

$ gcc -Wall -c main.c
$ gcc -Wall -c first.c
$ gcc -Wall -c second.c
$ ls
first.c first.h first.o main.c main.o second.c second.h second.o
$ gcc -o main main.o first.o second.o
$ ./main
First function.
Second function.
Main function.

Что мы сделали? Из каждого исходного файла (компилируя с опцией -c) получили объектный файл. Затем объектные файлы слинковали в итоговый исполняемый. Разумеется команд gcc стало больше, но в ручную ни кто проекты не собирает, для этого есть утилиты сборщики (самая популярная make). При использовании утилит сборщиков и проявятся все из перечисленных выше преимуществ раздельной компиляции.

Возникает вопрос: как линковщик ухитряется собирать вместе объектные файлы, правильно вычисляя адресацию вызовов? Откуда он вообще узнаёт, что в файле second.o содержится код функции second(), а в коде файла main.o присутствует её вызов? Оказывается всё просто - в объектном файле присутствует так называемая таблица символов, включающая имена некоторых позиций кода (функций и внешних переменных). Линковщик просматривает таблицу символов каждого объектного файла, ищет общие (с совпадающими именами) позиции, на основании чего делает выводы о фактическом местоположении кода используемых функций (или блоков данных) и, соответственно, производит перерасчёт адресов вызовов в исполняемом файле.

Просмотреть таблицу символов можно с помощью утилиты nm.

Появление вызова puts объясняется использованием функции стандартной библиотеки printf(), превратившейся в puts() на этапе компиляции.

Таблица символов прописывается не только в объектный, но и в исполняемый файл:

Включение таблицы символов в исполняемый файл в частности необходимо для упрощения отладки. В принципе для выполнения приложения она не очень то и нужна. Для исполняемых файлов реальных программ, с множеством определений функций и внешних переменных, задействующих кучу разных библиотек, таблица символов становиться весьма обширной. Для сокращения размеров выходного файла её можно удалить, воспользовавшись опцией gcc -s.

Все действия в операционной системе выполняются с помощью программ, поэтому многим новичкам интересно не только использовать чужие программы, а писать свои. Многие хотят внести свой вклад в кодовую базу OpenSource.

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

1. На чем пишут программы?

Исторически сложилось так, что ядро Unix было написано на языке Си. Даже более того, этот язык был создан для написания ядра Unix. Поскольку ядро Linux было основано на ядре Minix (версии Unix), то оно тоже было написано на Си. Поэтому можно сказать, что основной язык программирования для Linux это Си и С++. Такая тенденция сохранялась на протяжении долгого времени.

Мы не будем рассматривать основы Си в этой статье. Си - сложный язык и вам понадобится прочитать как минимум одну книгу и много практиковаться чтобы его освоить. Мы рассмотрим как писать программы на Си в Linux, как их собирать и запускать.

2. Библиотеки

Естественно, что если вам необходимо вывести строку или изображение на экран, то вы не будете напрямую обращаться к видеокарте. Вы просто вызовете несколько функций, которые уже реализованы в системе и передадите им данные, которые нужно вывести на экран. Такие функции размещаются в библиотеках. Фактически, библиотеки - это наборы функций, которые используются другими программами. В них находится такой же код, как и в других программах, разница лишь в том, там необязательно присутствие функции инициализации.

Библиотеки делятся на два типа:

  • Статические - они связываются с программой на этапе компиляции, они связываются и после этого все функции библиотеки доступны в программе как родные. Такие библиотеки имеют расширение .a;
  • Динамические - такие библиотеки встречаются намного чаще, они загружены в оперативную память, и связываются с программной динамически. Когда программе нужна какая-либо библиотека, она просто вызывает ее по известному адресу в оперативной памяти. Это позволяет экономить память. Расширение этих библиотек - .so, которое походит от Shared Object.

Таким образом, для любой программы на Си нужно подключать библиотеки, и все программы используют какие-либо библиотеки. Также важно заметить, на каком языке бы вы не надумали писать, в конечном итоге все будет сведено к системным библиотекам Си. Например, вы пишите программу на Python, используете стандартные возможности этого языка, а сам интерпретатор уже является программой на Си/С++, которая использует системные библиотеки для доступа к основным возможностям. Поэтому важно понимать как работают программы на Си. Конечно, есть языки, вроде Go, которые сразу переводятся на ассемблер, но там используются принципы те же, что и здесь. К тому же системное программирование linux, в основном, это Си или С++.

3. Процесс сборки программы

Перед тем как мы перейдем к практике и создадим свою первую программу, нужно разобрать как происходит процесс сборки, из каких этапов он состоит.

Каждая серьезная программа состоит из множества файлов, это файлы исходников с расширением .c и заголовочные файлы с расширением .h. Такие заголовочные файлы содержат функции, которые импортируются в программу из библиотек или других файлов .с. Перед тем. как компилятор сможет собрать программу и подготовить ее к работе, ему нужно проверить действительно ли все функции реализованы, доступны ли все статические библиотеки и собрать ее в один файл. Поэтому, первым делом выполняется препроцессор, который собирает исходный файл, выполняются такие инструкции, как include для включения кода заголовочных файлов.

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

Далее к работе приступает компоновщик. Его задача связать объектный модуль со статическими библиотеками и другими объектными модулями. Для каждого исходного файла создается отдельный объектный модуль. Только теперь программа может быть запущена.

А теперь, давайте рассмотрим весь єтот процесс на практике с использованием компилятора GCC.

4. Как собрать программу

Для сборки программ в Linux используется два типа компиляторов, это Gcc и Clang. Пока что GCC более распространен, поэтому рассматривать мы будем именно его. Обычно, программа уже установлена в вашей системе, если же нет, вы можете выполнить для установки в Ubuntu:

sudo apt install gcc

Перед тем как мы перейдем к написанию и сборке программы, давайте рассмотрим синтаксис и опции компилятора:

$ gcc опции исходный_файл_1.с -o готовый_файл

С помощью опций мы говорим утилите что нужно сделать, какие библиотеки использовать, затем просто указываем исходные файлы программы. Давайте рассмотрим опции, которые будем сегодня использовать:

  • -o - записать результат в файл для вывода;
  • -c - создать объектный файл;
  • -x - указать тип файла;
  • -l - загрузить статическую библиотеку.

Собственно, это все самое основное, что нам понадобится. Теперь создадим нашу первую программу. Она будет выводить строку текста на экран и чтобы было интереснее, считать квадратный корень из числа 9. Вот исходный код:

int main() printf("losst.ru\n");
printf("Корень: %f\n", sqrt(9));
return 0;
>

Я специально добавил функцию корня чтобы показать как работать с библиотеками. Сначала нужно собрать объектный файл. Перейдите в папку с исходниками и выполните:

gcc -c program.c -o program.o


Это этап компиляции, если в программе нет ошибок, то он пройдет успешно. Если исходных файлов несколько, то такая команда выполняется для каждого из них. Далее выполняем линковку:

gcc -lm program.o -o program


Обратите внимание на опцию -l, с помощью нее мы указываем какие библиотеки нужно подключить, например, здесь мы подключаем библиотеку математических функций, иначе компоновщик просто не найдет где есть та или иная функция. Только после этого можно запустить программу на выполнение:


Конечно, все эти действия могут быть выполнены и с помощью различных графических сред, но выполняя все вручную, вы можете лучше понять как все работает. С помощью команды ldd вы можете посмотреть какие библиотеки использует наша программа:


Это две библиотеки загрузчика, стандартная libc и libm, которую мы подключили.

5. Автоматизация сборки

Когда мы рассматриваем программирование под Linux невозможно не отметить систему автоматизации сборки программ. Дело в том, что когда исходных файлов программы много, вы не будете вручную вводить команды для их компиляции. Можно записать их один раз, а затем использовать везде. Для этого существует утилита make и файлы Makefile. Этот файл состоит из целей и имеет такой синтаксис:

цель: зависимости
<Tab> команда

В качестве зависимости цели может быть файл или другая цель, основная цель - all, а команда выполняет необходимые действия по сборке. Например, для нашей программы Makefile может выглядеть вот так:

program: program.o
gcc -lm program.o -o program

program.o: program.c
gcc -c program.c -o program.o

Затем вам достаточно выполнить команду make для запуска компиляции, только не забудьте удалить предыдущие временные файлы и собранную программу:


Программа снова готова и вы можете ее запустить.

Выводы

Создание программ Linux очень интересно и увлекательно. Вы сами убедитесь в этом, когда немного освоитесь в этом деле. Сложно охватить все в такой небольшой статье, но мы рассмотрели самые основы и они должны дать вам базу. В этой статье мы рассмотрели основы программирования в linux, если у вас остались вопросы, спрашивайте в комментариях!

Курс программирования на Си под Linux:

Это краткое руководство объясняет, как компилировать и запускать программы на Си/Си++ в операционной системе GNU/Linux.

Если вы студент или новый пользователь Linux, который переходит с платформы Microsoft, то вам может быть интересно, как запускать программы на Си или Си++ в дистрибутиве Linux. Мы должны понимать, что компиляция и запуск кода на платформах Linux немного отличается от Windows.

Установка необходимых инструментов

Как вы, наверное, уже понимаете, для запуска кода нужно установить необходимые инструменты и компиляторы для работы. Ниже мы опишем как установить все инструменты разработки в Linux.

Для работы и тестирования у нас должен быть сервер с Linux. Лучший вариант - это VPS. В зависимости от географии проекта обычно выбирают две страны для серверов - VPS США и VPS России.

В этом кратком руководстве мы обсудим, как установить средства разработки в такие дистрибутивы Linux, как Arch Linux, CentOS, RHEL, Fedora, Debian, Ubuntu, openSUSE и др.

Эти средства разработки включают в себя все необходимые приложения, такие как компиляторы GNU GCC C/C++, make, отладчики, man-страницы и другие, которые необходимы для компиляции и сборки нового программного обеспечения и пакетов.

Инструменты разработчика могут быть установлены как по отдельности, так и все сразу. Мы собираемся установить все сразу, чтобы нам было намного проще работать.

Установка в Arch Linux

Для установки средств разработки в Arch Linux и его дистрибутивов, таких как Antergos, Manjaro Linux, просто запустите:

Вышеуказанная команда установит следующие пакеты в ваши системы на базе Arch:

  1. autoconf
  2. automake
  3. binutils
  4. bison
  5. fakeroot
  6. file
  7. findutils
  8. flex
  9. gawk
  10. gcc
  11. gettext
  12. grep
  13. groff
  14. gzip
  15. libtool
  16. m4
  17. make
  18. pacman
  19. patch
  20. pkg-config
  21. sed
  22. sudo
  23. texinfo
  24. util-linux
  25. which

Просто нажми ENTER, чтобы установить их все.


Если вы хотите установить пакет в определенную группу пакетов, просто введите его номер и нажмите ENTER, чтобы продолжить установку.

Установка средств разработки в RHEL, CentOS

Для установки средств разработки в Fedora, RHEL и его клонах, таких как CentOS, Scientific Linux, выполните следующие команды как пользователь root:

Вышеуказанная команда установит все необходимые инструменты разработчика, например:

  1. autoconf
  2. automake
  3. bison
  4. byacc
  5. cscope
  6. ctags
  7. diffstat
  8. doxygen
  9. elfutils
  10. flex
  11. gcc/gcc-c++/gcc-gfortran
  12. git
  13. indent
  14. intltool
  15. libtool
  16. patch
  17. patchutils
  18. rcs
  19. subversion
  20. swig


Установка инструментов разработки в Debian, Ubuntu и дистрибутивы

Для установки необходимых инструментов разработчика в системах на базе DEB, запустите:

Эта команда предоставит все необходимые пакеты для настройки среды разработки в Debian, Ubuntu и его дистрибутивов.

  1. binutils
  2. cpp
  3. gcc-5-locales
  4. g++-multilib
  5. g++-5-multilib
  6. gcc-5-doc
  7. gcc-multilib
  8. autoconf
  9. automake
  10. libtool
  11. flex
  12. bison
  13. gdb
  14. gcc-doc
  15. gcc-5-multilib
  16. and many.


Теперь у Вас есть необходимые средства разработки для создания программного обеспечения в Linux.

Скрипт Mangi

Если Вам не нравится метод установки средств разработки выше, есть также скрипт под названием "сценарий манги" (mangi), доступный для легкой настройки среды разработки в DEB-системах, таких как Ubuntu, Linux Mint и других производных Ubuntu.

После свежей установки Ubuntu возьмите этот скрипт из репозитория GitHub, сделайте его исполняемым и начните установку всех необходимых инструментов и пакетов для настройки полной среды разработки. Вам не нужно устанавливать инструменты один за другим.

Этот скрипт установит следующие среды разработки и инструменты на вашу систему Linux:

  1. Node.js
  2. NVM
  3. NPM
  4. Nodemon
  5. MongoDB
  6. Forever
  7. git
  8. grunt
  9. bower
  10. vim
  11. Maven
  12. Loopback
  13. curl
  14. python
  15. jre/jdk
  16. gimp
  17. zip unzip and rar tools
  18. filezilla
  19. tlp
  20. erlang
  21. xpad sticky notes
  22. cpu checker
  23. kvm acceleration
  24. Calibre Ebook Reader (I often use it to read programming books
  25. Dict – Ubuntu Dictionary Database and Client (CLI based)

Сначала установите следующее:

Скачайте скрипт манги, используя команду:

Извлеките загруженный архив:

Вышеуказанная команда распакует zip-файл в папку под названием mangi-script-master в вашей текущей рабочей директории. Перейдите в каталог и сделайте скрипт исполняемым, используя следующие команды:

Наконец, запустите скрипт с помощью команды:


Пожалуйста, имейте в виду, что этот скрипт не полностью автоматизирован. Вам необходимо ответить на ряд вопросов "Да/Нет" для установки всех инструментов разработки.

Установка инструментов разработки в openSUSE/SUSE

Для настройки среды разработки в openSUSE и SUSE enterprise выполните следующие команды от имени root пользователя:

Проверка установки

Теперь проверим, были ли установлены средства разработки или нет. Для этого запустите:


Как видно из приведенного выше вывода, средства разработки были успешно установлены. Теперь можно начать разрабатывать свои приложения.

Настройка среды разработки

Скрипт под названием 'mangi' поможет вам настроить полное окружение в системах на базе Ubuntu.

Еще раз, после установки необходимых средств разработки проверить их можно с помощью одной из следующих команд:

Эти команды покажут путь установки и версию компилятора gcc.


Компиляция и запуск программ C, C++

Сначала посмотрим, как скомпилировать и запустить простую программу, написанную на языке Си.

Компиляция и запуск программ на C

Напишите свой код/программу в любимом редакторе CLI/GUI.

Я собираюсь написать свою программу на Си с помощью редактора nano.

Примечание. Вам необходимо использовать расширение .c для программ на Си или .cpp для программ на Си++.

Скопируйте/вставьте следующий код:


Нажмите Ctrl+O и Ctrl+X для сохранения и выхода из файла.

Чтобы скомпилировать программу, запустите:

Наконец, запустите программу с помощью команды:

Вы увидите вывод, как показано ниже:

Чтобы скомпилировать несколько исходных файлов (например, source1 и source2) в исполняемый файл, запустите:

Для разрешения предупреждений, необходима отладка символов на выходе:

Скомпилировать исходный код в инструкции ассемблера:

Скомпилировать исходный код без связывания:

Вышеприведенная команда создаст исполняемый файл под названием source.o.

Если ваша программа содержит математические функции:

За более подробной информацией обращайтесь к man-страницам (страницы руководства).

Компиляция и запуск программ на C++

Напишите вашу C++ программу в любом редакторе по вашему выбору и сохраните ее с расширением .cpp.

Пример простой C++ программы:

Чтобы скомпилировать эту программу на C++ в Linux, просто запустите:

Если ошибок не было, то можно запустить эту Си++ программу под Linux с помощью команды:

В качестве альтернативы мы можем скомпилировать приведенную выше программу на C++, используя команду "make", как показано ниже.

Вы заметили? Я не использовал расширение .cpp в вышеприведенной команде для компиляции программы. Нет необходимости использовать расширение для компиляции Си++ программ с помощью команды make.

В 8 главе вы познакомились с языком командного интерпретатора и убедились, что на нем можно писать полезные сценарии. Но если вы раньше программировали под Windows, то интерпретатора вам маловато будет — понадобятся более мощные средства разработки. Разумеется, они в ОС Linux есть.

Основным C-компилятором в Linux служит gcc (GNU С Compiler). Если вы не установили средства разработки при установке дистрибутива, самое время сделать это сейчас. Запустите менеджер пакетов (рис. 21.1) и установите следующие пакеты:

? gcc — сам компилятор gcc;

? gcc-c++ — поддержка С++;

? gcc-doc — документация по gcc (очень рекомендую установить);

? compat-gcc — пакет, содержащий средства gcc для обратной совместимости. Данный пакет вам нужен, если вы планируете писать программы для более старых систем, чем ваша;

? compat-gcc-c++ — то же, что и compat-gcc, только с поддержкой С++;

? compat-cpp — препроцессор cpp для обратной совместимости;

? binutils — набор вспомогательных утилит, о которых мы поговорим в последнем пункте этой главы;

? glibc-devel — содержит библиотеки для разработки C-программ;

? libbfd — библиотека дескриптора двоичного файла (Binary File Descriptor library);

? libstdc++-devel — заголовочные файлы и библиотеки для программирования на С++;

? make — утилита, упрощающая процесс сборки больших проектов.


Рис. 21.1. Менеджер пакетов Fedora Core — system-config-packages

Данный текст является ознакомительным фрагментом.

Продолжение на ЛитРес

21.1. Компилятор gcc

21.1. Компилятор gcc В 8 главе вы познакомились с языком командного интерпретатора и убедились, что на нем можно писать полезные сценарии. Но если вы раньше программировали под Windows, то интерпретатора вам маловато будет — понадобятся более мощные средства разработки.

3.4.2. Компилятор gcc

3.4.2. Компилятор gcc Не открою большого секрета, если скажу, что практически все программное обеспечение для Linux написано на языке С. Если вы хотите откомпилировать программу из исходного кода, то вам сначала нужно установить компилятор gcc.Для этого введите следующую

Компилятор как таковой: таблицы и деревья

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

Читайте также: