Как скомпилировать программу на си
Перейти к содержимому

Как скомпилировать программу на си

  • автор:

Язык Си в примерах/Компиляция программ

Программа на языке Си — один или несколько текстовых файлов, которые также называются исходными.

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

Процесс преобразования исходных файлов в исполняемый называется компиляцией. Если ваша программа состоит из одного исходного файла hello.c , то для его компиляции компилятором GNU С достаточно выполнить команду:

bash$ gcc hello.c -o hello

Если не получается или будете создавать папку для проекта, то разместите её поближе к корневой пользователя /home/username/folder/hello.c и запустите команду:

[username@localhost ~]$ gcc ~/development/hello.c -o hello

В результате получится файл hello , имя которого мы указали в опции -o . Этот файл является исполняемым и его можно запускать (execute) при помощи команды:

bash$ ./hello

Пара символов ./ перед hello означает «искать исполняемый файл hello в текущей директории».

bash$ gcc xxx.c yyy.c -o zzz -I./common -I.. -lm

соответствует команде: «скомпилировать файлы xxx.c yyy.c в программу zzz; заголовочные файлы находятся в директориях ./common и ..; подключить библиотеку libm»

Библиотека libm (подключаемая с помощью опции -lm ) содержит откомпилированные математические функции, которые объявляются в заголовочном файле math.h . Если вы используете функции из этой библиотеки (такие как log , sin , cos , exp ), то не забывайте подключать её при компиляции.

Подробную информацию об опциях компилятора gcc можно получить, если набрать

bash$ man gcc
bash$ info gcc

Ссылки [ править ]

  • http://digteh.ru/MCS51/C51/c51.php — Язык программирования СИ для микроконтроллеров
  • http://www.christian-heffner.de — Бесплатная среда разработки для windows со встроенным компилятором

Процесс компиляции программ на C++

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

Все действия будут производиться на Ubuntu версии 16.04.
Используя компилятор g++ версии:

$ g++ --version g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

Состав компилятора g++

Мы не будем вызывать данные компоненты напрямую, так как для того, чтобы работать с C++ кодом, требуются дополнительные библиотеки, позволив все необходимые подгрузки делать основному компоненту компилятора — g++.

Зачем нужно компилировать исходные файлы?

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

Этапы компиляции:

Перед тем, как приступать, давайте создадим исходный .cpp файл, с которым и будем работать в дальнейшем.

driver.cpp:

#include using namespace std; #define RETURN return 0 int main()

1) Препроцессинг

Самая первая стадия компиляции программы.

Препроцессор — это макро процессор, который преобразовывает вашу программу для дальнейшего компилирования. На данной стадии происходит происходит работа с препроцессорными директивами. Например, препроцессор добавляет хэдеры в код (#include), убирает комментирования, заменяет макросы (#define) их значениями, выбирает нужные куски кода в соответствии с условиями #if, #ifdef и #ifndef.

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

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

g++ -E driver.cpp -o driver.ii

Взглянув на тело функции main в новом сгенерированном файле, можно заметить, что макрос RETURN был заменен:

int main()

В новом сгенерированном файле также можно увидеть огромное количество новых строк, это различные библиотеки и хэдер iostream.

2) Компиляция

На данном шаге g++ выполняет свою главную задачу — компилирует, то есть преобразует полученный на прошлом шаге код без директив в ассемблерный код. Это промежуточный шаг между высокоуровневым языком и машинным (бинарным) кодом.

Ассемблерный код — это доступное для понимания человеком представление машинного кода.

Используя флаг -S, который сообщает компилятору остановиться после стадии компиляции, получим ассемблерный код в выходном файле driver.s:

$ g++ -S driver.ii -o driver.s

driver.s

 .file "driver.cpp" .local _ZStL8__ioinit .comm _ZStL8__ioinit,1,1 .section .rodata .LC0: .string "Hello, world!" .text .globl main .type main, @function main: .LFB1021: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $.LC0, %esi movl $_ZSt4cout, %edi call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi movq %rax, %rdi call _ZNSolsEPFRSoS_E movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1021: .size main, .-main .type _Z41__static_initialization_and_destruction_0ii, @function _Z41__static_initialization_and_destruction_0ii: .LFB1030: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movl %edi, -4(%rbp) movl %esi, -8(%rbp) cmpl $1, -4(%rbp) jne .L5 cmpl $65535, -8(%rbp) jne .L5 movl $_ZStL8__ioinit, %edi call _ZNSt8ios_base4InitC1Ev movl $__dso_handle, %edx movl $_ZStL8__ioinit, %esi movl $_ZNSt8ios_base4InitD1Ev, %edi call __cxa_atexit .L5: nop leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1030: .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii .type _GLOBAL__sub_I_main, @function _GLOBAL__sub_I_main: .LFB1031: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $65535, %esi movl $1, %edi call _Z41__static_initialization_and_destruction_0ii popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1031: .size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main .section .init_array,"aw" .align 8 .quad _GLOBAL__sub_I_main .hidden __dso_handle .ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609" .section .note.GNU-stack,"",@progbits

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

3) Ассемблирование

Так как x86 процессоры исполняют команды на бинарном коде, необходимо перевести ассемблерный код в машинный с помощью ассемблера.

Ассемблер преобразовывает ассемблерный код в машинный код, сохраняя его в объектном файле.

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

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

Получим машинный код с помощью ассемблера (as) в выходной объектный файл driver.o:

$ as driver.s -o driver.o

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

4) Компоновка

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

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

Получим исполняемый файл driver:

$ g++ driver.o -o driver // также тут можно добавить и другие объектные файлы и библиотеки

5) Загрузка

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

Запустим нашу программу:

$ ./driver // Hello, world!

Заключение

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

LibreBay

Статьи про ОС Ubuntu. Языки программирования Си и C++.
Инструменты разработки и многое другое.

понедельник, 5 декабря 2016 г.

Как скомпилировать программу на C/C++ в Ubuntu

ubuntu terminal

Помню, когда я только начинал программировать, у меня возник вопрос: «Как скомпилировать программу на C в Ubuntu?» Для новичков это не легкая задача, как может показаться на первый взгляд.

Мой путь изучения C начался с бестселлера «Брайан Керниган, Деннис Ритчи, Язык программирования C, 2-е издание». Там рассказывается как скомпилировать программу в операционной системе Unix, но этот способ не работает в Linux. Авторы книги выкрутились, написав следующее:

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

Побуду специалистом 🙂 и расскажу в данной статье, как скомпилировать первые программы на C и заодно на C++ в терминале Ubuntu.

Текстовый редактор gedit

Для написания первых программ подойдет обычный, используемый по умолчанию в Ubuntu, текстовый редактор с подсветкой синтаксиса — gedit.

Запуск текстового редактора
Рис. 1. Запуск текстового редактора.

Первой программой по традиции является «Hello, World!», выводящее приветствие на экран:

#include int main(int argc, char **argv)

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

Программа hello, World!
Рис. 2. Программа hello, World.

Компиляция программы на C

Теперь запускаем терминал, можно через Dash, а можно с помощью горячих клавиш + + . Здесь в начале установим инструменты сборки, куда входят необходимые компиляторы gcc для языка C и g++ для языка C++:

sudo apt install build-essential

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

Далее в терминале нам необходимо перейти в директорию, куда сохранили файл с текстом программы. Перемещение выполняется командой cd (англ. change directory — изменить каталог). Чтобы воспользоваться командой в начале пишется cd , затем через пробел путь , куда нужно перейти.

Для перехода на рабочий стол, команда будет следующей:

cd ~/Рабочий\ стол

Обратите внимание на символ обратной косой черты \ в имени директории Рабочий стол . Обратная косая экранирует пробел, и сообщает команде cd , что пробел и следующие за ним символы являются частью имени. Символ ~ в начале пути обозначает путь до домашней папки пользователя.

Для просмотра содержимого директории применяется команда ls (сокращение от англ. list).

Работа в терминале
Рис. 3. Работа в терминале.

Команда компиляции для программы на C выглядит следующим образом:

gcc -Wall -o hello hello.c
  • gcc — компилятор для языка программирования C;
  • -Wall — ключ вывода всех предупреждений компилятора;
  • -o hello — с помощью ключа -o указывается имя выходного файла;
  • hello.c — имя нашего исходного файла, который компилируем.

В завершение запустим hello , вводом имени программы с префиксом ./ :

./hello

Префикс ./ сообщает терминалу о необходимости выполнить программу с заданным именем в текущем каталоге. (Точка — это условное название текущего каталога.)

Работа в терминале, продолжение
Рис. 4. Работа в терминале, продолжение.

Компиляция программы на С++

Программы на C++ компилируются аналогично, как и программы на C. «Hello, World!» на C++ можно написать так:

#include int main(int argc, char **argv)

Сохраняем текст программы в файл под именем hello2.cpp . Таким образом, команда компилирования будет иметь вид:

g++ -Wall -o hello2 hello2.cpp

Для запуска результата вводим в терминале:

./hello2

Заключение

Данный способ позволяет скомпилировать программу лишь из одного файла с исходным кодом. Но этого вполне достаточно, чтобы начать изучение языков программирования C/C++ по книгам или по статьям в интернете.

  • Иванов Н. Н. — Программирование в Linux. Самоучитель. — 2-е издание;
  • Нейл Метьэ, Ричард Стоунс — Основы программирования в Linux: Пер. с англ. — 4-е издание;
  • Колисниченко Д. Н. — Разработка Linux-приложений.

Компиляция программы на Си на командной строке Windows

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

Что я хочу ?
Например, создаю файл file.c внутрь файла пишу задание , а потом через командую строку компилирую данную программу.

Подскажите теперь, как и что писать cmd , что бы скомпилировать не сложные программы

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Компиляция программы на C# в командной строке
using System; using System.Collections.Generic; using System.Linq; using System.Text; using.

Компиляция в командной строке (cl.exe) под платформы Windows XP и выше
Здравствуйте! Столкнулся с проблемой что во время компиляции в командной строке, выходной файл.

Компиляция в командной строке
Всем привет. Ребят не могу откомпилить файлик. Имеется 2 файлика директория котрых: .

Компиляция в командной строке
Всем привет! Ребят, тут вопрос такой. У меня имеется папка допустим называется "Project", в ней.

3802 / 2354 / 413
Регистрация: 09.09.2017
Сообщений: 10,206

Лучший ответ

Сообщение было отмечено robben_55 как решение

Решение

Ищете какой компилятор установлен, ищете путь к нему, прописываете его в %PATH%, либо просто куда-то запоминаете.
Ищете на него документацию и смотрите какие ключи для чего предназначены.
Запускаете компилятор с нужными ключами.
Например:
установлен Dev-C++ (gcc-mingw) в C:\Program files (x86)\Dev-Cpp , там можно найти собственно компилятор gcc, он расположен в .\WinGW64\bin\gcc.exe
Настраиваем PATH:

> PATH=%PATH%;C:\Program Files (x86)\Dev-Cpp\MinGW64\bin

но лучше это сделать через переменные операционной системы. Правда я не особо представляю как это делается.
запускаем компилятор:

> gcc main.c -Wall -Wextra -Wpedantic -Werror -Os -o prog.exe

либо, если не настраивали PATH:

> C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\gcc main.c -Wall -Wextra -Wpedantic -Werror -Os -o prog.exe

Если программа была написана правильно, появится файл prog.exe, который можно там же в консоли проверить

Добавлено через 2 минуты
UPD: в Win7 это делается кликом правой кнопкой на «мой компьютер» -> «свойства» -> слева кнопка «дополнительные параметры системы» -> вкладка «дополнительно» -> кнопка «переменные среды» -> выбираем PATH и редактируем

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Компиляция в командной строке.
Ребят задание скомпилировать код в командной строке vc++ и запустить программу.Делаю так: .

Компиляция кода в командной строке
на паре нам показывали как работать с прогой, написанной на ассемблере — cmd-> выбор директории ->.

Не работает компиляция в командной строке
Здравствуйте. Перестали компилироваться проекты из командной строки. До этого вроде бы все было.

Компиляция программы из командной строки
Всем привет, не знаю в чем причина. Скину фотки посмотрите. Всё перепробовал от перестановки jdk до.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *