Знайомство з компілятором GCC

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”


Робота з системними викликами

МЕТОДИЧНІ ВКАЗІВКИ

до лабораторної роботи № 3

з курсу «Операційні системи»

Львів 2015

Тема: Робота з системними викликами

Мета: Оволодіти практичними навичками роботи з компілятором GCC та системними викликами в операційній системі Linux. Ознайомитись із механізмом виконання системних викликів, процесом компіляції та побудови виконавчих файлів в ОС Linux.

Порядок виконання роботи

По номеру варіанту вибрати завдання і відповідно до методичних вказівок, за матеріалами рекомендованої літератури і конспекту лекцій виконати завдання і оформити звіт по роботі.

Зміст звіту

1. Початкові дані і постановка задачі.

2. Текст програми.

3. Результати виконання програми

4. Висновки.


Методичні вказівки

Знайомство з компілятором GCC

Засобами, традиційно використовуваними для створення програм для відкритих операційних систем, є інструменти розробника GNU. Проект GNU був заснований в 1984 році Річардом Столлманом. Його необхідність була викликана тим, що в той час співпраця між програмістами не обходилась без труднощів, оскільки власники комерційного програмного забезпечення чинили численні перешкоди для такої співпраці. Метою проекту GNU було створення комплекту програмного забезпечення під єдиною ліцензією, яка не допускала б можливості присвоювання кимось ексклюзивних прав на це ПЗ. Частиною цього комплекту і є набір інструментів для розробника, яким ми і будемо користуватися, і який повинен входити в усі дистрибутиви Linux.

Одним з цих інструментів є компілятор GCC. Спочатку ця абревіатура розшифровувалась, як GNU C Compiler. Зараз вона означає - GNU Compiler Collection. Розглянемо створення простої програми за допомогою GCC. За сформованою традицією перша програма буде просто виводити в консолі привітання «Hello world!».



Файли з вихідними кодами програм, які ми будемо створювати, це звичайні текстові файли, і створювати їх можна за допомогою будь-якого текстового редактора (наприклад GEdit KWrite, Kate, а також більш традиційні для користувачів Linux – nano, vi і emacs). Окрім текстових редакторів, існують спеціалізовані середовища розробки зі своїми вбудованими редакторами. Одним з таких засобів є KDevelop. Цікаво, що в ньому є вбудований редактор і вбудована консоль, розташована прямо під редактором. Так що можна в одній програмі, не перемикаючись між вікнами, і редагувати код і вводити консольні команди. Одним за найпопулярніших вільних інтегрованих середовищ розробки програмного забезпечення є Eclipse. Написаний в основному на Java, може бути використаний для розробки застосунків на Java і, за допомогою різних плаґінів, на інших мовах програмування, включаючи Ada, C, C++, COBOL, Fortran, Perl, PHP, Python, R, Ruby (включно з каркасом Ruby on Rails), Scala, Clojure та Scheme. Ще одним швидким та кросплатформенним редактором початкових текстів програм, який варто згадати є Sublime Text.

Отже, для знайомства з роботою GCC створимо окремий каталог hello. Це буде каталог нашого першого проекту. У ньому потрібно створити текстовий файл hello.c з наступним текстом:

#include

int main(void)

{

printf("Hello world!\n");

return(0);

}

Потім, в консолі, зайшовши в каталог проекту, набираємо команду:

gcc hello.c

У каталозі з'явився новий файл a.out. Це і є виконуваний файл. Запустимо його, для цього в консолі потрібно ввести:

./a.out

Програма повинна запуститися, тобто повинен з'явитися текст:

Hello world !

Компілятор gcc за замовчуванням присвоює всім створеним виконуваним файлам ім'я a.out. Якщо хочете назвати його по-іншому, потрібно до команди на компіляцію додати прапорець -o та ім'я, яким ви хочете його назвати. Давайте наберемо таку команду:
gcc hello.c -o hello

Ми бачимо, що в каталозі з'явився виконуваний файл з назвою hello. Запустимо його.
./hello
Як бачимо, вийшов такий самий виконуваний файл, тільки зі зручною для нас назвою.
Прапорець -o є лише одним з численних прапорців компілятора gcc. Деякі інші прапорці ми розглянемо пізніше. Щоб переглянути всі можливі прапорці, можна скористатися довідковою системою man. Наберіть в командному рядку:

man gcc

Перед вами постане довідкова система по цій програмі. Перегляньте, що означає кожен прапор. З деякими з них ми скоро зустрінемося. Вихід з довідкової системи здійснюється за допомогою клавіші q. Коли ми запускаємо програму з нашого каталогу розробки, ми перед назвою файлу набираємо крапку і слеш. Навіщо ж ми це робимо? Справа в тому, що, якщо ми наберемо тільки назву виконуваного файлу, операційна система буде шукати його в каталогах / usr / bin та / usr / local / bin, і, природно, не знайде. Каталоги / usr / bin та / usr / local / bin - системні каталоги для розміщення виконуваних програм. Перший з них призначений для розміщення стабільних версій програм, як правило, входять в дистрибутив Linux. Другий – для програм, що встановлюються самим користувачем (за стабільність яких ніхто не ручається). Така система потрібна, щоб відокремити їх один від одного. За замовчуванням при збиранні програми встановлюються в каталог / usr / local / bin. Вкрай небажано поміщати що-небудь зайве в / usr / bin або видаляти щось звідти вручну, тому що це може привести до краху системи. Там повинні розміщуватися програми, за стабільність яких відповідають розробники дистрибутиву. Щоб запустити програму, що знаходиться в іншому місці, треба прописати повний шлях до неї, наприклад так: / Home / dima / projects / hello / hello. Або інший варіант: прописати шлях щодо поточного каталогу, в якому ви в даний момент перебуваєте в консолі. При цьому одна крапка означає поточний каталог, дві крапки – батьківський. Наприклад, команда ./hello запускає програму hello, що знаходиться в поточному каталозі, команда ../hello - програму hello, що знаходиться в батьківському каталозі, команда ./projects/hello/hello - програму у вкладених каталогах, що знаходяться всередині поточного.

Є можливість додавати в список системних шляхів до програм додаткові каталоги. Для цього треба додати новий шлях в системну змінну PATH.

Тепер розглянемо, що ж робить програма gcc. Її робота включає три етапи: обробка препроцесором, компіляція і компоновка (або лінковка).

Препроцесор включає в основний файл вміст всіх заголовків файлів, зазначених у директивах #include. В заголовних файлах зазвичай знаходяться оголошення функцій, які використовуються у програмі, але не визначені у тексті програми. Їх визначення знаходяться десь в іншому місці: або в інших файлах з вихідним кодом або в бінарних бібліотеках.

Друга стадія - компіляція. Вона полягає в перетворенні тексту програми мовою C / C++ в набір машинних команд. Результат зберігається в об'єктному файлі. Зрозуміло, на машинах з різною архітектурою процесора виконавчі файли виходять у різних форматах, і на одній машині неможливо запустити бінарник, зібраний на іншій машині (лише, якщо у них однакова архітектура процесора і однакові операційні системи). Ось чому програми для UNIX-подібних систем поширюються у вигляді вихідних кодів: вони повинні бути доступні всім користувачам, незалежно від того, в кого який процесор і яка операційна система.

Остання стадія - компоновка. Вона полягає у зв'язуванні всіх об'єктних файлів проекту в один, зв'язуванні викликів функцій з їх визначеннями, і приєднанням бібліотечних файлів, що містять функції, які викликаються, але не визначені в проекті. В результаті формується виконавчий файл – наша кінцева мета. Якщо якась функція в програмі використовується, але компоновщик не знайдете місце, де ця функція визначена, він видасть повідомлення про помилку, і відмовиться створювати виконуваний файл.

Тепер подивимося на практиці, як все це виглядає. Напишемо іншу програму. Це буде примітивний калькулятор, здатний додавати, віднімати, множити і ділити. При запуску він буде запитувати по черзі два числа, над якими слід провести дію, а потім знак арифметичної дії. Це можуть бути чотири знаки: «+», «-», «*», «/». Після цього програма виводить результат і зупиняється (повертає нас в операційну систему, а точніше - в командний інтерпретатор, з якого ми програму і викликали).

Створимо для проекту нову папку kalkul, в ній створимо файл kalkul.c.

#include

int main(void)

{

float num1;

float num2;

char op;

printf("Перше число: ");

scanf("%f",&num1);

printf("Друге число: ");

scanf("%f",&num2);

printf("Оператор ( + - * / ): ");

while ((op = getchar()) != EOF)

{

if (op == '+')

{

printf("%6.2f\n",num1 + num2);

break;

}

else if(op == '-')

{

printf("%6.2f\n",num1 - num2);

break;

}

else if(op == '*')

{

printf("%6.2f\n",num1 * num2);

break;

}

else if(op == '/')

{

if(num2 == 0)

{

printf("Помилка: ділення на нуль!\n");

break;

}

else

{

printf("%6.2f\n",num1 / num2);

break;

}

}

}

return 0;

}

Отже, насамперед, як було сказано, виконується препроцесінг. Для того, щоб подивитися, що на цьому етапі робиться, скористаємося опцією -E. Ця опція зупиняє виконання програми на етапі обробки препроцесором. У результаті виходить файл вихідного коду з включеним в нього вмістом заголовних файлів.

У нашому випадку ми включали один файл-заголовок – stdio.h – колекцію стандартних функцій вводу-виводу. Ці функції і виводили на консоль потрібний текст, а також зчитували з консолі введені нами слова.

Введіть наступну команду:

gcc -E kalkul.c -o kalkul.cpp

Отриманому файлу ми дали ім'я kalkul.cpp. Відкривши його побачимо, що він вельми довгий. Це тому, що в нього увійшов весь код stdio.h. Крім того, препроцесор сюди додав деякі теги, що вказують компілятору спосіб зв'язку з оголошеними функціями. Основний текст нашої програми видно тільки в самому низу. Можна також подивитись, які ще функції оголошені в заголовному файлі stdio.h. Якщо вам захочеться одержати інформацію про яку-небудь функцію, можна одержати інформацію про неї у вбудованому керівництві man. Наприклад, якщо вам раптом захочеться дізнатися, що ж робить функція fopen, можна ввести:

man fopen

Багато інформації також є в довідковій системі info.

info fopen

Можна отримати інформацію і про весь заголовний файл одразу.

man stdio.h

info stdio.h

Подивимось тепер наступний етап. Створимо об'єктний файл. Об'єктний файл є «дослівний» переклад нашого програмного коду на машинну мову, поки без зв'язку функцій, що викликаються з їх визначеннями. Для формування об'єктного файлу служить опція -c.
gcc -c kalkul.c

Назву одержуваного файлу можна не вказувати, оскільки компілятор просто бере назву вихідного файлу і змінює розширення .c на .o (вказати можна, якщо нам захочеться назвати його по-іншому).

Якщо ми створюємо об'єктний файл з вихідного, вже обробленого препроцесором (наприклад, такого, який ми отримали вище), то ми повинні обов'язково вказати явно, що компільований файл є файлом вихідного коду, оброблений препроцесором, і має теги препроцесора. В іншому випадку він буде оброблятися, як звичайний файл C ++, без урахування тегів препроцесора, а значить зв'язок з оголошеними функціями не буде встановлено. Для явної вказівки на мову і формат оброблюваного файлу служить опція -x. Файл C ++, оброблений препроцесором позначається cpp-output.

gcc -x cpp-output -c kalkul.cpp

Нарешті, останній етап - компоновка. Отримання з об'єктного файлу виконуваний.

gcc kalkul.o -o kalkul

Можна його запускати.

./kalkul
Виникає питання: «Навіщо знати про всі ці проміжні етапи? Чи не краще просто один раз ввести команду gcc kalkul.c -o kalkul? » Справа в тому, що справжні програми дуже рідко складаються з одного файлу. Як правило вихідних файлів декілька, і вони об'єднані в проект. І в деяких виняткових випадках програму доводиться компонувати з декількох частин, написаних на різних мовах. У цьому випадку доводиться запускати компілятори різних мов, щоб кожен отримав об'єктний файл зі свого вихідного, а потім вже ці отримані об'єктні файли компонувати в виконувану програму.

Загальна будова і робочий процес двигуна
Специальность «Математика» с дополнительной специальностью «Информатика»
Вертикальные формы кооперации
Система финансовых отношений
I.Выдержки из истории болезни 2 часть
За допомогою керуючої палітри
Типи уроків з української мови
Эубиотики. Антибиотики и другие химиотерапевтические препараты
Оборотність оборотних засобів безпосередньо впливає на кінцеві результати роботи підприємства, зокрема приріст прибутку на рівень рентабельності.
Приготування соків
Формы феодального землевладения.
Общие свойства и классификация протоколов маршрутизации
Коллективные средства защиты.
Современные геополитические интересы Индии
Доказове право та заходи забезпечення кримінального провадження
Оцінка параметра до методом крос-перевірки
Робота здисками, файлами, папками в TOTAL COMMANDER
Перша допомога при травмі ока.
Види робіт при спорудженні гірничих виробок
Искусственные средства охлаждения воздуха (использование холодильных машин потребляющих электрическую и тепловую энергию).
Полномочия органов местного самоуправления в области жилищно-коммунального хозяйства.
Нам была дана власть во Христе
Глава XXII. О местах князей-избирателей в процессиях и кому надлежит вести инсигнии
Главная Страница