Как запустить файл cpp в линукс. Программирование на Си (C) в Ubuntu (Linux)

09.05.2019

Последнее обновление: 28.08.2017

В прошлой теме было рассмотрено создание первой программы на Windows. Теперь рассмотрим создание первой программы на Linux, в частности, в среде Ubuntu 16.04. На Linux также популярным компилятор для создания программ является g++. Поэтому в данном случае также будем использовать этот компилятор.

Как правило, многие дистрибутивы Linux, в том числе и Ubuntu, уже по умолчанию содержат установленный компилятор g++, который мы сразу же можем использовать. Но даже если вдруг он не установлен, то его можно доустановить в терминале через команду:

Sudo apt-get install g++

В остальном, если мы будем использовать для компиляции компилятор g++, все будет аналогично созданию программы на Windows.

Определим в файловой системе каталог для исходных файлов с кодом на С++ и создадим в нем новый файл hello.c со следующим кодом:

#include // подключаем заголовочный файл iostream int main() // определяем функцию main { // начало функции std::cout << "Hello World!"; // выводим строку на консоль return 0; // выходим из функции } // конец функции

И это тот же код, что был в случае с Windows, потому что программы на С++ на уровне исходного кода в большей степени обладают переносимостью.

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

#include

Данная строка представляет директиву препроцессора, которая позволяет подключить библиотеку iostream. Эта библиотека нужна для вывода строки на консоль.

Функция main состоит из четырех элементов:

    Тип возвращаемого значения . В данном случае это тип int . Этот тип указывает, что функция должна возвращать целое число.

    Имя функции . В данном случае функция называется main.

    Список параметров . После имени функции в скобках идет список параметров. Но в данном случае скобки пустые, то есть функция main не принимает параметров.

    Тело функции . После списка параметров в фигурных скобках идет тело функции. Здесь и определяются собственно те действия, которые выполняет функция main.

    { std::cout << "Hello World!\n"; return 0; }

В теле функции происходит вывод строки на консоль. Для обращения к консоли используется стандартный поток вывода std::cout . С помощью оператора << в этот поток (в данном случае фактически на консоль) передается строка символов, которую надо вывести на консоль, то есть "Hello World!". В конец строки добавлена специальная управляющая последовательность "\n", которая позволит после вывода текста перевести курсор на новую строку.

В функции осуществляем выход из функции с помощью оператора return . Так как функция должна возвращать целое число, то после return указывается число 0. Ноль используется в качестве индикатора успешного завершения программы.

После каждой инструкции в языке C++ ставятся точка с запятой.

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

g++ hello.cpp -o hello

Кроме имени файла с исходным кодом компилятору передается параметр -o hello . Он указывает, что мы хотим скомпилировать файл по имени hello. Если этот параметр не передать, то будет создан файл с именем по умолчанию - a.out.

В итоге после выполнения выше приведенной команды в папке с файлом hello.cpp появится скомпилированный файл, который будет называться hello . И мы сможем его запустить с помощью следующей команды:

И на консоль будет выведена строка "Hello World!".

Операционная система (ОС) Linux/Unix и язык C - "близненцы-братья". Вспомните, что язык программирования C был создан (Д.Ритчи, 1972 г) специально для написания ОС Unix, и с тех пор и "каноническая" ОС Unix, а также все ее клоны и подобные ей ОС пишутся на языке C. Поэтому во всех версиях Unix и Unix-подобных систем компилятор языка C в большинстве случаев входит в комплект поставки системы.

Одним из первых программных продуктов, созданных в рамках проекта GNU, также явился компилятор языка С с открытым кодом. Этот компилятор включается в поставку всех версий ОС Linux.

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

  • cc - стандартный компилятор языка C;
  • c++ - стандартный компилятор языка C++;
  • gcc - GNU-компилятор языка C;
  • g++ - GNU-компилятор языка C++.

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

Компилятор языка C выполняет как собственно компиляцию - перевод исходного текста на машинный язык, результатом чего является объектный модуль, так и редактирование связей - сборку из нескольких объектных модулей (в том числе, и библиотечных) исполняемого модуля.

Файлы с исходными текстами C-программ должны иметь расширение.c , например: hello.c . Результатом компиляции является файл, содержащий объектный модуль, его имя совпадает с именем исходного модуля, а расширение - .o , например: hello.o . Для файла, содержащего исполняемый модуль стандартного расширения не существует. При компиляции программы, состоящей из единственного исходного модуля, объектный модуль автоматически удаляется после создания компилятором исполняемого модуля.

Общий формат команды вызова компилятора имеет следующий вид (компилирование в linux):

Gcc [опции] [выходной_файл] файл1 [файл2:]

Наиболее часто употребляемые опции компилятора следующие:

-c Подавляет фазу редактирования связей, создает объектный модуль для каждого исходного модуля из перечисленных в параметрах вызова. Выходной_файл с этой опцией не задается. Опция может применяться вместе с опцией -I
   
-o Компиляция и редактирование связей. Cоздает объектный модуль для каждого исходного модуля из перечисленных в параметрах вызова и имеющих расширение.c . Файлы с расширением.c рассматриваются как исходные модули и компилируются; файлы, имеющие расширение.o , рассматриваются как объектные модули и подключаются при редактировании связей. Параметр выходной_файл задает имя файла исполняемого модуля. Опция может применяться вместе с опциями -L , -l , -I .
   
-L каталог Добавить каталог в список каталогов, которые содержат объектные библиотечные модули.
   
-l библиотека При редактировании связей подключить модули из библиотеки .
   
-I каталог Искать включаемые (#include) файлы, имена которых не начинаются с / сначала в каталоге , а лишь затем - в стандартных каталогах для включаемых файлов.
   
-E Выполнить обработку указанных исходных модулей только препроцессором, результат направляется в стандартный вывод. Выходной_файл с этой опцией не задается. Опция может применяться вместе с опцией -I .
   
-w Подавить выдачу предупреждающих сообщений.

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

gcc hello.c gcc -c hello.c gcc -o hello hello.o gcc -o hello hello.o hello1.c
Компиляция исходного модуля hello.c с выдачей сообщений об ошибках на стандартный вывод. Файл объектного модуля не создается.
   
Компиляция исходного модуля hello.c с выдачей сообщений об ошибках на стандартный вывод. При успешной компиляции объектный модуль записывается в файл hello.o .
   
Редактирование связей для объектного модуля hello.o , исполняемый модуль записывается в файл hello .
   
Создание исполняемого модуля в файле hello из объектного модуля hello.o и модуля hello1.c (последний модуль является исходным, он предварительно компилируется.
   
gcc -o hello hello.o hello1.o -l hellolib Создание исполняемого модуля в файле hello из объектных модулей hello.o и hello1.o c с подключением объектных модулей из библиотеки hellolib .
   
gcc -o hello hello1.с -lm Создание исполняемого модуля в файле hello из исходного модуля hello.с с выдачей сообщений об ошибках на стандартный вывод с подключением бибилиотеки math.h . Файл объектного модуля не создается.

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

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

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

А вообще, писать программы для Linux можно почти на любом языке начиная от Java и Python и заканчивая С# и даже Pascal. Для всех языков есть компиляторы и интерпретаторы. Писать программы на С++ сложно, а Си многими уже считается устаревшим, поэтому множество программистов используют другие языки для написания программ. Например, множество системных инструментов написаны на Python или Perl. Большинство программ от команды Linux Mint, установщик Ubuntu и некоторые скрипты apt написаны на Python. Множество скриптов, в том числе простые скрипты оптимизации написаны на Perl. Иногда для скриптов используется Ruby. Это скрипты OpenShift или, например, фреймворк Metasploit. Некоторые разработчики кроссплатформенных программ используют Java. Но основные компоненты системы написаны все же на Си.

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

Зачем учить Си:

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

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

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

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

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

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

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

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

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

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

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

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

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

sudo apt install gcc

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

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

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

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

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

include
#include

int main(){
printf("сайт\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. Этот файл состоит из целей и имеет такой синтаксис:

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

В качестве зависимости цели может быть файл или другая цель, основная цель - 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:

Всем привет! Это первая статья о программировании на Си, в котором мы настроим тестовый редактор и узнаем немного о истории языка Си, возможностях, преимуществах и недостатках.

Языку Си в 2012 году исполнилось 40 лет. Си стал родоначальником C++, Java, Perl, C#, JavaScript и тд. Это самый популярный язык программирования в мире. Си процедурный язык программирования. Файлы кода имеют расширение.c а заголовочные файлы.h. На Си вы можете программировать для Linux, Windows, Windows Phone, Mac OS, iOS, Android и тд. Любой программист должен владеть языком программирования Си. Что бы стать программистом читать одних книг и статей мало. Нужно еще и практиковать. Поэтому мы рассмотрим наши уроки обязательно с примерами. Если у вас возникнет какие то вопросы, то можете задавать в комментариях. Так же этим мануалом могут пользоваться пользователи Windows и Mac OS. Пользователи других ОС могут пользоваться например NetBeans в качестве компилятора (NetBeans поддерживает не только Си но и Java, PHP, C++, Python и Ruby)

Настройка

Для программирования на понадобится текстовый редактор (gedit) и компилятор (gcc - входит в состав Ubuntu). Компилятор настраивать не нужно, а вот текстовый редактор настроим сейчас.

Откройте Правка -> Настройки . Установите галочки на следующие пункты:

  • Показывать номера строк;
  • Подсвечивать текущую строку;
  • Подсвечивать парные скобки;
  • Можно так же изменить тему в вкладке Шрифты и цвета.

Пара выполненных «махинаций» с gedit упростят на работу с текстовым редактором. А в дальнейшем мы рассмотрим какой-нибудь IDE (интегрирования среда разработки).

Похожие статьи