Разработчик (и) | Проект GNU |
---|---|
Первый выпуск | 23 мая 1987 г.; 33 года назад (1987-05-23) |
Стабильный выпуск | 10.2 / 23 июля 2020 г.; 2 месяца назад (2020-07-23) |
Репозиторий | |
Написано на | C с некоторыми частями, написанными на C ++ |
Операционная система | Кросс-платформенная |
Платформа | GNU |
Тип | Компилятор |
Лицензия | GPLv3 + с исключением библиотеки времени выполнения GCC |
Веб-сайт | gcc.gnu.org |
Коллекция компиляторов GNU (GCC ) - это система компилятора, созданная GNU Проект поддерживает различные языки программирования. GCC является ключевым компонентом GNU toolchain и стандартным компилятором для большинства проектов, связанных с GNU и Linux, включая ядро Linux. Фонд свободного программного обеспечения (FSF) распространяет GCC под Стандартной общественной лицензией GNU (GNU GPL). GCC сыграл важную роль в развитии бесплатного программного обеспечения как инструмент и пример.
Когда он был впервые выпущен в 1987 году, GCC 1.0 назывался GNU C Compiler, поскольку он обрабатывал только язык программирования C. В декабре того же года он был расширен для компиляции C ++. Внешние интерфейсы были позже разработаны для Objective-C, Objective-C ++, Fortran, Java, Ada и Go, среди прочего.
Версия 4.5 спецификации OpenMP теперь поддерживается в компиляторах C и C ++ и "значительно улучшена "также поддерживается реализация спецификации OpenACC 2.0a. По умолчанию текущая версия поддерживает gnu ++ 14, расширенный набор C ++ 14, и gnu11, расширенный набор C11, также доступна строгая стандартная поддержка. Начиная с GCC 9, поддержка C ++ 17 больше не является экспериментальной, и она, или строго gnu ++ 17, используется по умолчанию в (предстоящем) GCC 11. GCC также предоставляет экспериментальную поддержку для C ++ 20.
GCC был перенесен на широкий спектр архитектур наборов команд и широко используется в качестве инструмента при разработке как бесплатных, так и фирменное программное обеспечение. GCC также доступен для многих встроенных систем, включая ARM ; Микросхемы на базе AMCC и Freescale Power ISA. Компилятор может работать с широким спектром платформ.
Помимо того, что GCC является официальным компилятором операционной системы GNU, он был принят в качестве стандартного компилятора многими другими современными Unix-подобными компьютерами операционные системы, включая большинство дистрибутивов Linux. Большинство операционных систем семейства BSD также перешли на GCC, хотя с тех пор некоторые BSD, включая FreeBSD и OpenBSD, с тех пор перешли на Clang компилятор. macOS также переключился на Clang после использования GCC. Также доступны версии для Microsoft Windows и других операционных систем; GCC может компилировать код для Android и iOS.
В целях начальной загрузки операционной системы GNU, Ричард Столлман попросил Эндрю С. Таненбаума, автора Amsterdam Compiler Kit (также известного как Free University Compiler Kit) для разрешение на использование этого программного обеспечения для GNU. Когда Таненбаум сообщил ему, что компилятор не является бесплатным и что свободен только университет, Столлман решил написать новый компилятор. Первоначальный план Столлмана состоял в том, чтобы переписать существующий компилятор из Ливерморской национальной лаборатории с Pastel на C с некоторой помощью Len Tower и других. Столлман написал новый интерфейс C для компилятора Livermore, но затем понял, что для этого требуются мегабайты стекового пространства, что невозможно в системе 68000 Unix, имеющей только 64 КБ, и пришел к выводу, что ему придется написать новый компилятор с нуля. Ни один из кодов компилятора Pastel не попал в GCC, хотя Столлман действительно использовал написанный им интерфейс на C.
GCC был впервые выпущен 22 марта 1987 г., доступен по FTP с Массачусетский технологический институт. Столлман был указан как автор, но процитировал других за их вклад, включая Джека Дэвидсона и Кристофера Фрейзера за идею использования RTL в качестве промежуточного языка, Пола Рубина для написания большей части препроцессора и Леонарда Тауэра за " части анализатора, генератора RTL, определений RTL и описания машины Vax ". Описанный Салусом «первым хитом свободного программного обеспечения», компилятор GNU появился как раз в то время, когда Sun Microsystems отделяла свои инструменты разработки от своей операционной системы, продавая их отдельно по более высокой комбинированной цене, чем предыдущий комплект, что побудило многих пользователей Sun купить или загрузить GCC вместо инструментов поставщика. К 1990 году GCC поддерживал тринадцать компьютерных архитектур, превосходил по производительности компиляторы нескольких поставщиков, поставлялся Data General и NeXT с их рабочими станциями и использовался Lotus Development Corporation.
Поскольку GCC был лицензирован по GPL, программисты, желающие работать в других направлениях, особенно те, которые пишут интерфейсы для языков, отличных от C, могли свободно разрабатывать свои собственные fork компилятора при условии, что они соответствуют условиям GPL., включая его требования по распространению исходного кода. Однако использование нескольких форков оказалось неэффективным и громоздким, а трудность принятия работы официальным проектом GCC сильно разочаровывала многих. FSF так строго контролировал то, что было добавлено в официальную версию GCC 2.x, что GCC использовался в качестве одного из примеров «соборной» модели развития в Эрик С. Реймонд в эссе Собор и базар.
В 1997 году группа разработчиков сформировала Experimental / Enhanced GNU Compiler System (EGCS), чтобы объединить несколько экспериментальных форков в один проект. Основой слияния стал снимок состояния разработки GCC, сделанный между версиями 2.7 и 2.81. Объединенные проекты включали g77 (Fortran), PGCC (P5 Pentium -optimized GCC), множество улучшений C ++, а также множество новых архитектур и вариантов операционной системы. Разработка EGCS оказалась значительно более энергичной, чем разработка GCC, настолько, что FSF официально остановила разработку своего компилятора GCC 2.x, благословила EGCS в качестве официальной версии GCC и назначила проект EGCS сопровождающими GCC в апреле 1999 года. с выпуском GCC 2.95 в июле 1999 года эти два проекта снова были объединены.
GCC с тех пор поддерживается разнообразной группой программистов со всего мира под руководством руководящего комитета. Он был перенесен на большее количество типов процессоров и операционных систем, чем любой другой компилятор.
GCC был перенесен на широкий спектр архитектур наборов команд и широко используется в качестве инструмента для разработки как бесплатного, так и проприетарного программного обеспечения. GCC также доступен для многих встроенных систем, включая Symbian (называемый gcce), на базе ARM ; Микросхемы на базе AMCC и Freescale Power ISA. Компилятор может работать с широким спектром платформ, включая игровые консоли, такие как PlayStation 2, Cell SPE для PlayStation 3 и Dreamcast.
Внешний интерфейс GCC следует соглашениям Unix. Пользователи вызывают программу драйвера для конкретного языка (gcc
для C, g ++
для C ++ и т. Д.), Которая интерпретирует аргументы команды, вызывает фактический компилятор, запускает ассемблер на выходе, а затем, при необходимости, запускает компоновщик для создания полного исполняемого файла двоичного файла.
Каждый из компиляторов языка представляет собой отдельную программу, которая считывает исходный код и выводит машинный код. Все имеют общую внутреннюю структуру. Интерфейс для каждого языка анализирует исходный код на этом языке и создает абстрактное синтаксическое дерево (сокращенно «дерево»).
Они при необходимости преобразуются во входное представление среднего конца, называемое ОБЩЕЙ формой; средний конец затем постепенно трансформирует программу в ее окончательную форму. Оптимизация компилятора и методы статического анализа кода (такие как FORTIFY_SOURCE, директива компилятора, которая пытается обнаружить некоторые переполнения буфера ) применяются к коду. Они работают с несколькими представлениями, в основном с архитектурно-независимым представлением GIMPLE и архитектурно-зависимым представлением RTL. Наконец, машинный код создается с использованием зависящего от архитектуры сопоставления с образцом, первоначально основанного на алгоритме Джека Дэвидсона и Криса Фрейзера.
GCC был написан в основном на C, за исключением частей Ada внешнего интерфейса. Дистрибутив включает стандартные библиотеки для Ada, C ++ и Java, код которых в основном написан на этих языках. На некоторых платформах дистрибутив также включает низкоуровневую библиотеку времени выполнения libgcc, написанную на комбинации машинно-независимого C и зависящего от процессора машинного кода, предназначенного в первую очередь для обработки арифметических операций. операции, которые целевой процессор не может выполнять напрямую.
В мае 2010 года руководящий комитет GCC решил разрешить использование компилятора C ++ для компиляции GCC. Компилятор был предназначен для написания на C плюс подмножество функций из C ++. В частности, это было решено, чтобы разработчики GCC могли использовать функции C ++ деструкторы и generics.
В августе 2012 года руководящий комитет GCC объявил, что GCC теперь использует C ++ в качестве языка реализации. Это означает, что для сборки GCC из исходных кодов требуется компилятор C ++, который понимает стандарт ISO / IEC C ++ 03.
18 мая 2020 г. GCC перешел от стандарта ISO / IEC C ++ 03 к стандарту ISO / IEC C ++ 11 (т.е. необходим для компиляции, bootstrap, сам компилятор; однако по умолчанию он компилирует более поздние версии C ++).
Каждый интерфейс использует синтаксический анализатор для создания абстрактное синтаксическое дерево заданного исходного файла. Из-за абстракции синтаксического дерева исходные файлы любого из различных поддерживаемых языков могут обрабатываться одной и той же серверной частью . GCC начал использовать парсеры LALR, созданные с помощью Bison, но постепенно переключился на написанные вручную парсеры с рекурсивным спуском для C ++ в 2004 году, а также для C и Objective- C в 2006 году. В настоящее время все интерфейсы используют рукописные синтаксические анализаторы с рекурсивным спуском.
До GCC 4.0 древовидное представление программы не было полностью независимым от целевого процессора.
Значение дерева было несколько различным для различных языковых интерфейсов, и внешние интерфейсы могли предоставлять свои собственные древовидные коды. Это было упрощено с появлением GENERIC и GIMPLE, двух новых форм не зависящих от языка деревьев, которые были представлены с появлением GCC 4.0. GENERIC более сложен, он основан на промежуточном представлении интерфейса Java GCC 3.x. GIMPLE - это упрощенный GENERIC, в котором различные конструкции относятся к нескольким инструкциям GIMPLE. Внешние интерфейсы C, C ++ и Java создают GENERIC непосредственно во внешнем интерфейсе. Вместо этого другие интерфейсы имеют разные промежуточные представления после синтаксического анализа и преобразования их в GENERIC.
В любом случае так называемый «gimplifier» затем преобразует эту более сложную форму в более простую форму GIMPLE на основе SSA, которая является общим языком для большого числа мощных языковых программ. и независимая от архитектуры глобальная оптимизация (объем функций).
GENERIC - это язык промежуточного представления, используемый в качестве «среднего уровня» при компиляции исходного кода в исполняемые двоичные файлы. Подмножество, называемое GIMPLE, предназначено для всех интерфейсов GCC.
Средний этап GCC выполняет весь анализ кода и оптимизацию, работая независимо как от скомпилированного языка, так и от целевой архитектуры, начиная с GENERIC представления и расширяя его до зарегистрировать язык перевода (RTL). Представление GENERIC содержит только подмножество императивных программных конструкций, оптимизированных средним концом.
При преобразовании исходного кода в GIMPLE сложные выражения разбиваются на трехадресный код с использованием временных переменных. Это представление было вдохновлено представлением SIMPLE, предложенным в компиляторе McCAT Лори Дж. Хендрен для упрощения анализа и оптимизации императивных программ.
Оптимизация может происходить во время любой этап компиляции; однако основная часть оптимизаций выполняется после синтаксиса и внешнего интерфейса и до генерации кода серверной части; таким образом, обычное, хотя и несколько противоречивое, название этой части компилятора - "средний конец".
Точный набор оптимизаций GCC варьируется от выпуска к выпуску по мере его разработки, но включает стандартные алгоритмы, такие как оптимизация цикла, потоковая передача с переходом, исключение общего подвыражения, планирование инструкций и так далее. Оптимизация RTL имеет меньшее значение с добавлением глобальных оптимизаций на основе SSA для деревьев GIMPLE, поскольку RTL-оптимизации имеют гораздо более ограниченную область действия и содержат меньше высокоуровневой информации.
Некоторые из этих оптимизаций, выполняемых на этом уровне, включают устранение мертвого кода, устранение частичной избыточности, нумерацию глобального значения, разреженное условное постоянное распространение, и. Также выполняются оптимизации на основе зависимости от массива, такие как автоматическая векторизация и автоматическое распараллеливание. Оптимизация на основе профиля также возможна.
Бэкэнд GCC частично определяется макросами препроцессора и функциями, специфичными для цели архитектура, например, для определения ее порядка байтов, размера слова и соглашений о вызовах. Передняя часть серверной части использует их, чтобы помочь решить генерацию RTL, поэтому, хотя RTL GCC номинально не зависит от процессора, начальная последовательность абстрактных инструкций уже адаптирована к цели. В любой момент фактические инструкции RTL, формирующие представление программы, должны соответствовать целевой архитектуре.
Файл описания машины содержит шаблоны RTL, а также ограничения операндов и фрагменты кода для вывода окончательной сборки. Ограничения указывают, что конкретный шаблон RTL может применяться (например) только к определенным аппаратным регистрам или (например) разрешать немедленные смещения операндов только ограниченного размера (например, 12, 16, 24,... битовые смещения и т. Д.)). Во время генерации RTL проверяются ограничения для данной целевой архитектуры. Чтобы выдать данный фрагмент RTL, он должен соответствовать одному (или нескольким) шаблонам RTL в файле описания машины и удовлетворять ограничениям для этого шаблона; в противном случае было бы невозможно преобразовать окончательный RTL в машинный код.
К концу компиляции действительный RTL сводится к строгой форме, в которой каждая инструкция ссылается на регистры реальной машины и образец из файла описания целевой машины. Формирование строгого RTL - сложная задача; важным шагом является выделение регистров, где реальные аппаратные регистры выбираются для замены первоначально назначенных псевдорегистров. Затем следует фаза «перезагрузки»; любые псевдорегистры, которым не был назначен реальный аппаратный регистр, «переливаются» в стек, и генерируется RTL для выполнения этого распределения. Точно так же смещения, которые слишком велики для размещения в реальной инструкции, должны быть разбиты и заменены последовательностями RTL, которые будут подчиняться ограничениям смещения.
На заключительном этапе машинный код создается путем вызова небольшого фрагмента кода, связанного с каждым шаблоном, для генерации реальных инструкций из целевого набора инструкций с использованием последних регистров., смещения и адреса, выбранные на этапе перезагрузки. Фрагмент создания сборки может быть просто строкой, и в этом случае выполняется простая строковая подстановка регистров, смещений и / или адресов в строку. Фрагмент создания сборки также может быть коротким блоком кода C, выполняющим некоторую дополнительную работу, но в конечном итоге возвращающим строку, содержащую допустимый код сборки.
Некоторые функции GCC включают:
Стандартный компилятор выпуски, начиная с 7, включают интерфейсы для C (gcc
), C ++ (g ++
), Objective-C, Objective-C ++, Фортран (gfortran
), Ада (GNAT ) и Go (gccgo
). Также поддерживается популярное расширение параллельного языка OpenMP. В версии 5.0 добавлена поддержка Cilk Plus, в версии 9.1 добавлена поддержка D, а начиная с версии 5.1, имеется предварительная поддержка OpenACC. Версии до GCC 7 также поддерживали Java (gcj
), что позволяло компилировать Java в собственный машинный код.
Интерфейс Fortran был g77
до версии 4.0, которая поддерживает только FORTRAN 77. В более новых версиях g77
удаляется в пользу нового внешнего интерфейса GNU Fortran (с сохранением большинства языковых расширений g77), который поддерживает Fortran 95 и большую часть Fortran 2003 и Fortran 2008, а также. Интерфейс для CHILL был удален из-за отсутствия обслуживания.
Сторонние интерфейсы существуют для Pascal (gpc
), Modula-2, Modula-3, PL / I и VHDL (ghdl
).
Существует несколько экспериментальных ветвей для поддержки дополнительных языков, таких как компилятор GCC UPC для Unified Parallel C.
семейства целевых процессоров GCC как версии 4.3 включают (примечание, GCC 6 и более ранние версии больше не поддерживаются):
Начиная с GCC 10, поддерживается еще несколько (например, SPU, то есть Cell, удален), например графические процессоры Nvidia, то есть промежуточный код Nvidia PTX, а также AMD Код GCN, 64-битный ARM (AArch64 ), а не только 32-битный, RISC-V, MSP430 и eBPF ( полный язык, отличный от Тьюринга, работающий в ядре Linux ).
Малоизвестные целевые процессоры, поддерживаемые в стандартном выпуске, включают изд:
GCC поддерживает дополнительные процессоры версии, поддерживаемые отдельно от версии FSF:
Компилятор Java gcj может быть нацелен либо на архитектуру машинного языка, либо на байт-код Java виртуальной машины . При перенацеливании GCC на новую платформу часто используется самонастройка. Motorola 68000, Zilog Z80 и другие процессоры также используются в версиях gcc, разработанных для различных программируемых графических калькуляторов Texas Instruments, Hewlett Packard, Sharp и Casio.
Текущая стабильная версия GCC - 10.2, выпущенный 23 июля 2020 года.
Начиная с версии 4.8, GCC реализован на C ++.
GCC 4.6 поддерживает много новых Objective-C функции, такие как объявленные и синтезированные свойства, точечный синтаксис, быстрое перечисление, дополнительные методы протокола, атрибуты метода / протокола / класса, расширения классов и новый API времени выполнения GNU Objective-C. Он также поддерживает язык программирования Go и включает библиотеку libquadmath
, которая предоставляет математические функции четверной точности для целей, поддерживающих тип данных __float128
.. Библиотека используется для предоставления типа REAL (16)
в GNU Fortran для таких целей.
GCC использует в своей сборке множество стандартных инструментов, включая Perl, Flex, Bison и другие распространенные инструменты. Кроме того, в настоящее время для сборки требуется наличие трех дополнительных библиотек: GMP и MPFR.
Основная часть разработки концентрирует основную часть усилий по разработке, где внедряются новые функции и проверено.
GCC лицензируется в соответствии с версией 3 Стандартной общественной лицензии GNU.
Исключение времени выполнения GCC разрешает компиляцию проприетарных и бесплатных software программы с GCC и использование бесплатных программных плагинов. Наличие этого исключения не подразумевает какое-либо общее предположение о том, что на стороннее программное обеспечение не распространяются требования об авторском леве лицензии GCC.
Несколько компаний делают бизнес на поставке и поддержке портов GCC для различных платформ.
На Викискладе есть материалы, относящиеся к GCC. |
В Wikibooks есть книга по теме: Внутреннее устройство компилятора GNU C |