Перейти до вмісту

GNU Compiler Collection

Матеріал з Вікіпедії — вільної енциклопедії.
GNU Compiler Collection
GCC, під керуванням командного рядка
Типнабір компіляторів
РозробникThe GNU Project
Перший випуск23 травня 1987[1]
Стабільний випуск12.1 (6 травня 2022; 2 роки тому (2022-05-06))
Платформакросплатформова програма
Операційна системадекілька
Мова програмуванняC, C++, Ada
Доступні мовианглійська, російська та багато інших
Стан розробкиАктивний
ЛіцензіяGPL
Репозиторійgcc.gnu.org/git/gcc.git
Вебсайтgcc.gnu.org

Набір компіля́торів GNU (GNU Compiler Collection, GCC) — набір компіляторів для різних мов програмування. GCC — вільне програмне забезпечення, розроблене Фондом Вільних Програм під ліцензією GNU GPL та GNU LGPL, і є ключовою складовою набору знарядь розробки GNU (GNU development toolchain). Це стандартний компілятор для вільних Unix-подібних операційних систем, і деяких пропрієтарних систем, що з них розвинулись, наприклад Mac OS X.

Спочатку називався 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)
  • (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] Премія присуджується за значний вплив на пов'язані з мовами програмування дослідження, реалізації технологій і інструменти.

Посилання

[ред. | ред. код]

Література

[ред. | ред. код]

Виноски

[ред. | ред. код]
  1. GCC Releases. GNU Project. Архів оригіналу за 23 червня 2013. Процитовано 27 грудня 2006.
  2. GCC 7 Release Series. Архів оригіналу за 2 вересня 2020. Процитовано 6 червня 2020.
  3. Programming Languages Software Award. Архів оригіналу за 7 серпня 2014. Процитовано 14 червня 2014.

Див. також

[ред. | ред. код]