GNU Compiler Collection
Набір компіля́торів GNU (GNU Compiler Collection, GCC) — набір компіляторів для різних мов програмування. GCC — вільне програмне забезпечення, розроблене Фондом Вільних Програм під ліцензією GNU GPL та GNU LGPL, і є ключовою складовою набору знарядь розробки GNU (GNU development toolchain). Це стандартний компілятор для вільних Юнікс-подібних операційних систем, і деяких пропрієтарних систем, що з них розвинулись, наприклад Mac OS X.
| |
GCC, під керуванням командного рядка | |
Тип | набір компіляторів |
---|---|
Розробник | The GNU Project |
Перший випуск | 23 травня 1987[1] |
Стабільний випуск | 10.1 (7 травня 2020 ) |
Репозиторій | gcc.gnu.org/git/ |
Платформа | крос-платформова програма |
Операційна система | декілька |
Мова програмування | C, C++, Ada |
Доступні мови | англійська, російська та багато інших |
Стан розробки | Активний |
Ліцензія | GPL |
Вебсайт | gcc.gnu.org |
GNU Compiler Collection у Вікісховищі |
Спочатку називався GNU Компілятор Сі, оскільки підтримував лише одну мову програмування — C. Пізніше був розширений для підтримки C++, Fortran, Java (компілятор GCJ), Ada, D, та інших.
Огляд
GCC започаткований Річардом Столменом у 1985 році як компілятор для проєкту GNU Project, аби мати компілятор який є вільним програмним забезпеченням. Його розробкою тісно опікувався Фонд Вільних Програм. Перша версія випущена навесні 1987, на кінець 1987 року з'явилася підтримка C++. GCC був першим незалежно створеним (не базувався на препроцесорі CFront Б'ярна Страуструпа) та першим власне компілятором (а не препроцесором у C) мови C++.
У 1997 група розробників, незадоволена повільним темпом і закритістю офіційної розробки GCC, створила проєкт EGCS (Experimental/Enhanced GNU Compiler System — Експериментальна/Покращена Збірка Компіляторів GNU), який об'єднав декілька експериментальних відгалужень GCC. Розробка EGCS з часом виявилась більш життєвою ніж GCC, і у квітні 1999 року EGCS оголошена офіційною версією GCC.
GCC тепер розробляється широкою групою розробників зі всього світу. Вона перенесена на більшу кількість типів процесорів та операційних систем ніж будь-який інший компілятор.
GCC є офіційним компілятором GNU, включно із GNU/Linux, прийнятий як основний компілятор і для інших операційних систем, таких як варіанти *BSD, Mac OS X, NeXTSTEP, і BeOS. Версія GCC під Microsoft Windows забезпечується проєктами MinGW та Cygwin, під DOS — проєктом DJGPP (лише C/C++).
Мови
Версія 4.0.0 (випущена 20 квітня 2005), у типовій збірці підтримує наступні мови:
- Ада (GCC для Ada також відомий як GNAT)
- Сі
- C++ (GCC для C++ також відомий як G++)
- Fortran (GCC для Фортрану також відомий як GFortran)
- Java (GCC для Java також відомий як GCJ. Видалений починаючи з версії GCC 7.1[2])
- Objective-C
- Go (GCC для Go, або gccgo) (починаючи з версії 4.6)
- D (GCC D) (починаючи з версії 9.1)
Підтримка CHILL припинена через недостатню активність розробки. Додаткові проєкти підтримують мови програмування Pascal, Modula-2, Modula-3, Mercury, VHDL, PL/I та Objective-C++.
Архітектури
GCC (версії 4.1) створює код для таких процесорних архітектур:
|
Менш відомі серед підтримуваних процесорів включають A29K, ARC, Atmel AVR, C4x, CRIS, D30V, DSP16xx, FR-30, FR-V, Intel i960, IP2000, M32R, 68HC11, MCORE, MMIX, MN10200, MN10300, NS32K, ROMP, Stormy16, V850 і Xtensa. Окремими проєктами підтримується D10V, PDP-10 і Z8000.
Структура
Зовнішній інтерфейс GCC є стандартом для компіляторів на платформі Unix. Користувач викликає управляючу програму, яка називається gcc. Вона інтерпретує аргументи командного рядка, визначає і запускає для кожного вхідного файлу свої компілятори потрібної мови, запускає, якщо необхідно, асемблер і компонувальник.
Компілятор кожної мови є окремою програмою, яка отримує початковий текст і породжує вихід на мові асемблера. Всі компілятори мають загальну внутрішню структуру:
- front end, який проводить синтаксичний розбір і породжує абстрактне синтаксичне дерево,
- і back end, який конвертує дерево в Register Transfer Language (RTL), виконує різні оптимізації, потім породжує програму на мові асемблера, використовуючи архітектурно-залежне зіставлення зі зразком.
GCC майже повністю написаний на Сі, хоча значна частина front-end для Ади написана на Ада.
В травні 2010 Керівний комітет GCC вирішив дозволити використовувати C++ компілятор для компіляції GCC. В серпні 2012 року комітет дозволив також використовувати C++ мову для розробки GCC і деякі складні структури даних (напр хеш-таблиці ітп) були переписані з допомогою C++ з використанням шаблонів. Для компіляції GCC зараз вимагається компілятор мови C++, що підтримує щонайменше ISO/IEC C++03 стандарт.
Етапи компіляції програми мовою С на GCC
Компіляція програми на мові C за допомогою gcc передбачає такі послідовні етапи: препроцесор (prepocessing), компіляція (compilation), збирання (assembly), лінкування(linking). Розглянемо кожен з даних етапів на прикладі програми 'hello.c'. Зверніть увагу, що для компіляції hello.c нема потреби викликати кожну із нижче розглянутих команд окремо. Усі програми автоматично викликає компілятор і їх виклики можна відслідковувати додавши опцію '-v' до команди gcc. Розглянувши кожну команду окремо ми будемо краще розуміти роботу компілятора. Поряд з тим, що 'hello' є досить простою програмою, у ній використано зовнішні бібліотеки, тому під час компіляції даної програми будуть пройдені усі вище вказані етапи.
Препроцесор
Першим етапом компіляції є виклик препроцесора. Препроцесор розгортає(підставляє значення у) макроси та додає у 'hello.c' код необхідних header-файлів. Для цього gcc викликає таку команду: cpp hello.c > hello.i Результатом виконання даної команди є файл 'hello.i', у якому міститься source-код з розгорнутими макросами і вставленими header-файлами. Зверніть увагу, що вихідні файли роботи препроцесора мають розширення '.i' для програм на мові С і '.ii' для програм на мові С++. По замовчуванню hello.i та інші проміжні файли після компіляції не буде збережено на диску, проте, це можливо змінити вказавши опцію '-save-temps=obj' під час виклику gcc, тобто
gcc -save-temps=obj -c hello.c
Компілятор
Наступним етапом є власне компіляція вихідного файлу препроцесора(hello.i). Результатом цього етапу є файл 'hello.s'. У даному файлі міститься код на мові ассемблер. Файл 'hello.s' є проміжним, тому компілятор по замовчуванню його видаляє. Щоб зберегти 'hello.s' і переглянути його вміст необхідно виконати таку команду: gcc -S hello.i Результатом цієї команди є файл 'hello.s' Ось як виглядає 'hello.s' для процесора з архітектурою x86_64.
.file "hello.c"
.section .rodata
.LC0:
.string "Hello World"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
call puts
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4"
Збирання
Метою даного етапу є перетворення коду мовою асемблер на машинний код і генерація object-файлу. Якщо у коді є виклики зовнішніх функцій, асемблер залишає адреси початку цих зовнішніх функцій невизначеними. Їх значення будуть заповнені компонувальником на наступному етапі компіляції. Для виклику асемблера:
as hello.s -o hello.o
Як ми бачимо вихідний файл команди вказано за допомогою опції -о. Результатом роботи асемблера є файл hello.o, що містить програму 'hello' у вигляді машинних інструкцій, де також є, поки що невизначена, адреса(undefined reference) початку функції printf().
Лінкування
Останнім етапом компіляції є лінкування(linking) об'єктного файлу для створення executable-файлу, власне програми 'hello'. На практиці, executable-файли потребують багатьох зовнішніх функцій і динамічних (run-time) бібліотек С. Таким чином, справжні команди лінкування, котрі внутрішньо автоматично виконує gcc, є досить складними. Таким чином, повна команда для лінкування 'hello':
ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i686/3.3.1/crtbegin.o -L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.o
Дана команда лінкує object-файл 'hello.o' із стандартною бібліотекою C і створює вихідний executable-файл 'hello'. Для запуску 'hello':
./hello
Таким, чином виконання команди 'gcc -o hello hello.c' можливо зобразити так:
hello.c -> | PREPROCESSOR(cpp) | -> hello.i -> | COMPILER(cc) | -> hello.s -> | ASSEMBLER(as) | -> hello.o -> | LINKER(ld) | -> hello
Зневадження програм, скомпільованих за допомогою GCC
Головним інструментом для зневадження програм, скомпільованих за допомогою GCC, є GNU Debugger (gdb). Існують також вузькоспеціалізовані засоби для зневаджування:
- Valgrind для пошуку витоків пам'яті
- GNU Profiler (gprof) використовується для того, щоб визначити, скільки часу йде на виконання тієї або іншої частини програми, як часто викликаються ті або інші процедури; для використання gprof необхідно компілювати програму із спеціальними опціями для включення «профілізації».
Інструментальні оболонки
Компілятори мають десятки опцій і користуватися ними напряму не зовсім зручно. Для спрощення роботи використовують оболонки або інтегровані середовища розробки — Code::Blocks, Dev-C++/wxDev-C++, Eclipse, KDevelop, NetBeans.
Відзнаки
У 2014 Асоціація обчислювальної техніки (ACM), найавторитетніша міжнародна організація, в області комп'ютерних систем присудила проєкту GCC премію за внесок у розвиток мов програмування (SIGPLAN Programming Languages Software Award).[3] Премія присуджується за значний вплив на пов'язані з мовами програмування дослідження, реалізації технологій і інструменти.
Посилання
- сторінка GCC
- Керівництво v4.0
- Керівництво v3.4.3
- тижневі новини[недоступне посилання з червня 2019]
- GCC Wiki
Література
- Richard M. Stallman: Using and Porting the GNU Compiler Collection, Free Software Foundation, ISBN 0-595-10035-X
- Richard M. Stallman: Using Gcc: The Gnu Compiler Collection Reference, Free Software Foundation, ISBN 1-882114-39-6
- Brian J. Gough: An Introduction to GCC, Network Theory Ltd., ISBN 0-9541617-9-3
- Arthur Griffith, GCC: The Complete Reference. McGrawHill/Osborne. ISBN 0-07-222405-3.
Виноски
- GCC Releases. GNU Project. Архів оригіналу за 23 червня 2013. Процитовано 27 грудня 2006.
- GCC 7 Release Series
- Programming Languages Software Award