Сайт о телевидении

Сайт о телевидении

» » Что такое компиляция кода. Определение и история появления. Класс и компилятор

Что такое компиляция кода. Определение и история появления. Класс и компилятор

Компьютеров, оснащённых векторным процессором .

  • Гибкий . Составлен по модульному принципу, управляется таблицами и запрограммирован на языке высокого уровня или реализован с помощью компилятора компиляторов.
  • Диалоговый . См.: диалоговый транслятор.
  • Инкрементальный . Повторно транслирует фрагменты программы и дополнения к ней без перекомпиляции всей программы.
  • Интерпретирующий (пошаговый) . Последовательно выполняет независимую компиляцию каждого отдельного оператора (команды) исходной программы.
  • Компилятор компиляторов . Транслятор, воспринимающий формальное описание языка программирования и генерирующий компилятор для этого языка.
  • Отладочный . Устраняет отдельные виды синтаксических ошибок.
  • Резидентный . Постоянно находится в основной памяти и доступен для повторного использования многими задачами.
  • Самокомпилируемый . Написан на том же языке, с которого осуществляется трансляция.
  • Универсальный . Основан на формальном описании синтаксиса и семантики входного языка. Составными частями такого компилятора являются: ядро, синтаксический и семантический загрузчики.
  • Виды компиляции

    • Пакетная . Компиляция нескольких исходных модулей в одном пункте задания.
    • Построчная . То же, что и интерпретация .
    • Условная . Компиляция, при которой транслируемый текст зависит от условий, заданных в исходной программе. Так, в зависимости от значения некоторой константы, можно включать или выключать трансляцию части текста программы.

    Основы

    Большинство компиляторов переводит программу с некоторого высокоуровневого языка программирования в машинный код , который может быть непосредственно выполнен центральным процессором . Как правило, этот код также ориентирован на исполнение в среде конкретной операционной системы , поскольку использует предоставляемые ею возможности (системные вызовы , библиотеки функций). Архитектура (набор программно-аппаратных средств), для которой производится компиляция, называется целевой машиной .

    Некоторые компиляторы (например, низкоуровневом языке. Такой язык - байт-код - также можно считать языком машинных команд, поскольку он подлежит интерпретации виртуальной машиной . Например, для языка Java это JVM (язык виртуальной машины Java), или так называемый байт-код Java (вслед за ним все промежуточные низкоуровневые языки стали называть байт-кодами). Для языков программирования на платформе .NET Framework ( , Managed C++, Visual Basic .NET и другие) - это MSIL (Microsoft Intermediate Language).

    Программа на байт-коде подлежит интерпретации виртуальной машиной , либо ещё одной компиляции уже в машинный код непосредственно перед исполнением. Последнее называется «Just-In-Time компиляция» (MSIL-код компилируется в код целевой машины также JIT-компилятором, а библиотеки .NET Framework компилируются заранее).

    Для каждой целевой машины (Apple и т. д.) и каждой операционной системы или семейства операционных систем, работающих на целевой машине, требуется написание своего компилятора. Существуют также так называемые кросс-компиляторы , позволяющие на одной машине и в среде одной ОС получать код, предназначенный для выполнения на другой целевой машине и/или в среде другой ОС. Кроме того, компиляторы могут быть оптимизированы под разные типы процессоров из одного семейства (путём использования специфичных для этих процессоров инструкций). Например, код, скомпилированный под процессоры семейства MMX, SSE2.

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

    Существуют программы, которые решают обратную задачу - перевод программы с низкоуровневого языка на высокоуровневый. Этот процесс называют декомпиляцией, а программы - декомпиляторами . Но поскольку компиляция - это процесс с потерями, точно восстановить исходный код, скажем, на C++, в общем случае невозможно. Более эффективно декомпилируются программы в байт-кодах - например, существует довольно надёжный декомпилятор для Flash . Сходным процессом является дизассемблирование машинного кода в код на языке ассемблера, который всегда выполняется успешно. Связано это с тем, что между кодами машинных команд и командами ассемблера имеется практически однозначное соответствие.

    Структура компилятора

    Процесс компиляции состоит из следующих этапов:

    1. Лексический анализ . На этом этапе последовательность символов исходного файла преобразуется в последовательность лексем .
    2. Синтаксический (грамматический) анализ . Последовательность лексем преобразуется в дерево разбора.
    3. Семантический анализ. Дерево разбора обрабатывается с целью установления его семантики (смысла) - например, привязка идентификаторов к их декларациям, типам, проверка совместимости, определение типов выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным деревом разбора, новым деревом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки.
    4. Оптимизация . Выполняется удаление излишних конструкций и упрощение кода с сохранением его смысла. Оптимизация может быть на разных уровнях и этапах - например, над промежуточным кодом или над конечным машинным кодом.
    5. Генерация кода . Из промежуточного представления порождается код на целевом языке.

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

    Трансляция и компоновка

    Важной исторической особенностью компилятора, отражённой в его названии (англ. compile - собирать вместе, составлять), являлось то, что он мог производить и компоновку (то есть содержал две части - транслятор и компоновщик). Это связано с тем, что раздельная компиляция и компоновка как отдельная стадия сборки выделились значительно позже появления компиляторов, и многие популярные компиляторы (например, GCC) до сих пор физически объединены со своими компоновщиками. В связи с этим, вместо термина «компилятор» иногда используют термин «транслятор» как его синоним : либо в старой литературе, либо когда хотят подчеркнуть его способность переводить программу в машинный код (и наоборот, используют термин «компилятор» для подчёркивания способности собирать из многих файлов один).

    Примечания

    См. также

    Реализации компиляторов
    • Sun Studio - компиляторы C, C++ и Fortran от Sun Microsystems Inc.
    • Open Watcom - свободное продолжение компиляторов Watcom C/C++/Fortran.
    • ICC AVR

    Литература

    • Альфред В. Ахо, Моника С. Лам, Рави Сети, Джеффри Д. Ульман. Компиляторы: принципы, технологии и инструментарий = Compilers: Principles, Techniques, and Tools. - 2-е изд. - М.: Вильямс , 2008. - ISBN 978-5-8459-1349-4
    • Робин Хантер. Основные концепции компиляторов = The Essence of Compilers. - М.: Вильямс , 2002. - С. 256. - ISBN 0-13-727835-7
    • Хантер Р. Проектирование и конструирование компиляторов / Пер. с англ. С. М. Круговой. - М.: Финансы и статистика, 1984. - 232 с.
    • Д. Креншоу. Давайте создадим компилятор! .

    Wikimedia Foundation . 2010 .

    Смотреть что такое "Компиляция (программирование)" в других словарях:

      Компиляция: В Викисловаре есть статья «компиляция» Компиляция (литература) (лат. … Википедия

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

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

      Just in time compilation (JIT, компиляция «на лету»), dynamic translation (динамическая компиляция) технология увеличения производительности программных систем, использующих байт код, путём компиляции байт кода в машинный код… … Википедия

      Эту статью следует викифицировать. Пожалуйста, оформите её согласно правилам оформления статей. Условные обозначения … Википедия

      Python Класс языка: функциональный, объектно ориентированный, императивный, аспектно ориентированный Тип исполнения: интерпретация байт кода, компиляция в MSIL, компиляция в байт код Java Появился в: 1990 г … Википедия

      ГОСТ 19781-90: Обеспечение систем обработки информации программное. Термины и определения - Терминология ГОСТ 19781 90: Обеспечение систем обработки информации программное. Термины и определения оригинал документа: 9. Абсолютная программа Non relocatable program Программа на машинном языке, выполнение которой зависит от ее… … Словарь-справочник терминов нормативно-технической документации

    Компиля́тор - программа или техническое средство, выполняющее компиляцию .

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

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

    Виды компиляторов

      Векторизующий . Транслирует исходный код в машинный код компьютеров, оснащённых векторным процессором.

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

      Диалоговый . См.: диалоговый транслятор.

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

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

      Компилятор компиляторов . Транслятор, воспринимающий формальное описание языка программирования и генерирующий компилятор для этого языка.

      Отладочный . Устраняет отдельные виды синтаксических ошибок.

      Резидентный . Постоянно находится в оперативной памяти и доступен для повторного использования многими задачами.

      Самокомпилируемый . Написан на том же языке, с которого осуществляется трансляция.

      Универсальный . Основан на формальном описании синтаксиса и семантики входного языка. Составными частями такого компилятора являются: ядро, синтаксический исемантический загрузчики.

    Виды компиляции

      Пакетная . Компиляция нескольких исходных модулей в одном пункте задания.

      Построчная . То же, что и интерпретация.

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

    Структура компилятора

    Процесс компиляции состоит из следующих этапов:

      Лексический анализ. На этом этапе последовательность символов исходного файла преобразуется в последовательность лексем.

      Синтаксический (грамматический) анализ. Последовательность лексем преобразуется в дерево разбора.

      Семантический анализ. Дерево разбора обрабатывается с целью установления его семантики (смысла) - например, привязка идентификаторов к их декларациям, типам, проверка совместимости, определение типов выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным деревом разбора, новым деревом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки.

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

      Генерация кода. Из промежуточного представления порождается код на целевом языке.

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

    Генерация кода

    Генерация машинного кода

    Большинство компиляторов переводит программу с некоторого высокоуровневого языка программирования в машинный код, который может быть непосредственно выполнен процессором. Как правило, этот код также ориентирован на исполнение в среде конкретной операционной системы, поскольку использует предоставляемые ею возможности (системные вызовы, библиотеки функций). Архитектура (набор программно-аппаратных средств), для которой производится компиляция, называется целевой машиной .

    Результат компиляции - исполнимый модуль - обладает максимальной возможной производительностью, однако привязан к определённой операционной системе и процессору (и не будет работать на других).

    Для каждой целевой машины (IBM, Apple, Sun и т. д.) и каждой операционной системы или семейства операционных систем, работающих на целевой машине, требуется написание своего компилятора. Существуют также так называемые кросс-компиляторы , позволяющие на одной машине и в среде одной ОС генерировать код, предназначенный для выполнения на другой целевой машине и/или в среде другой ОС. Кроме того, компиляторы могут оптимизировать код под разные модели из одного семейства процессоров (путём поддержки специфичных для этих моделей особенностей или расширений наборов инструкций). Например, код, скомпилированный под процессоры семейства Pentium, может учитывать особенности распараллеливания инструкций и использовать их специфичные расширения - MMX, SSE и т. п.

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

    Генерация байт-кода

    Результатом работы компилятора может быть программа на специально созданном низкоуровневом языке, подлежащем интерпретации виртуальной машиной . Такой язык называется псевдокодом или байт-кодом. Как правило, он не является машинным кодом какого-либо компьютера и программы на нём могут исполняться на различных архитектурах, где имеется соответствующая виртуальная машина, но в некоторых случаях создаются аппаратные платформы, напрямую поддерживающие псевдокод какого-либо языка. Например, псевдокод языка Java называется байт-кодом Java (англ. Java bytecode ) и выполняется в Java Virtual Machine, для его прямого исполнения была создана спецификация процессора picoJava. Для платформы.NET Framework псевдокод называется Common Intermediate Language (CIL), а среда исполнения - Common Language Runtime (CLR).

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

    Динамическая компиляция

    Основная статья: JIT-компиляция

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

    CIL-код также компилируется в код целевой машины JIT-компилятором, а библиотеки.NET Framework компилируются заранее.

    Декомпиляция

    Существуют программы, которые решают обратную задачу - перевод программы с низкоуровневого языка на высокоуровневый. Этот процесс называют декомпиляцией, а такие программы - декомпиляторами. Но поскольку компиляция - это процесс с потерями, точно восстановить исходный код, скажем, на C++, в общем случае невозможно. Более эффективно декомпилируются программы в байт-кодах - например, существует довольно надёжный декомпилятор для Flash. Разновидностью декомпилирования являетсядизассемблирование машинного кода в код на языке ассемблера, который почти всегда выполняется успешно (при этом сложность может представлять самомодифицирующийся код или код, в котором собственно код и данные не разделены). Связано это с тем, что между кодами машинных команд и командами ассемблера имеется практически взаимно-однозначное соответствие.

    Раздельная компиляция

    Раздельная компиляция (англ. separate compilation ) - трансляция частей программы по отдельности с последующим объединением их компоновщиком в единый загрузочный модуль.

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

    Появление раздельной компиляции и выделение компоновки как отдельной стадии произошло значительно позже создания компиляторов. В связи с этим вместо термина «компилятор» иногда используют термин «транслятор» как его синоним: либо в старой литературе, либо когда хотят подчеркнуть его способность переводить программу в машинный код (и наоборот, используют термин «компилятор» для подчёркивания способности собирать из многих файлов один).

    Когда программисты разговаривают о программировании, они часто говорят: «программа откомпилировалась без ошибок», или, когда говорят программисту: «скомпилируй программу, посмотрим на результат работы». Такие разговорчики позднее могут стать источником путаницы для . Компиляция и создание исполняемого файла — не синонимы! Создание исполняемых файлов — это многоступенчатый процесс, основные составляющие которого: компиляция и компоновка. На самом деле, даже если программа «откомпилировалась без ошибок», она может не работать из-за возможной ошибки во время стадии компоновки. Весь процесс трансляции файлов исходного кода в исполняемый файл лучше было бы называть построением проекта.

    Компиляция!

    Компиляция относится к обработке файлов исходного кода (.c, .cc, или.cpp) и создании объектных файлов проекта. На этом этапе не создается исполняемый файл. Вместо этого компилятор просто транслирует высокоуровневый код в машинный язык. Например, если вы создали (но не скомпоновали) три отдельных файла, у вас будет три объектных файла, созданные в качестве выходных данных на этапе компиляции. Расширение таких файлов будет зависеть от вашего компилятора, например *.obj или *.o. Каждый из этих файлов содержит машинные инструкции, которые эквивалентны исходному коду. Но вы не можете запустить эти файлы! Вы должны превратить их в исполняемые файлы операционной системы, только после этого их можно использовать. Вот тут за дело берётся компоновщик.

    Компоновка!

    Из нескольких объектных файлов создается единый исполняемый файл. На этом этапе полученный файл является единственным, а потому компоновщик будет жаловаться на найденные неопределенные функции. На этапе компиляции, если компилятор не мог найти определение для какой-то функции, считается, что функция была определена в другом файле. Если это не так, компилятор об этом знать не будет, так как не смотрит на содержание более чем одного файла за раз. Компоновщик, с другой стороны, может смотреть на несколько файлов и попытаться найти ссылки на функции, которые не были упомянуты.

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

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

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

    Эти два этапа берёт на себя и вам не стоит беспокоиться о том, какие из файлов были изменены. IDE сама решает,когда создавать объекты файлов, а когда нет.

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

    Если вы только начинаете изучать программирование или же просто интересовались данным вопросом, наверняка вам на глаза попадалось таинственное слово «компилятор». Это с виду страшное понятие способно отпугнуть людей. В данной статье постараемся разобраться, так ли все ужасно. Что такое компилятор?

    Определение и история появления

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

    Появились такие программы вместе с зарождением первых языков программирования. Произошло это в конце 50-х годов. Получается, что история, которая связана с компиляторами и языками программирования насчитывает уже более шести десятков лет. Несмотря на такой серьезный срок, данное направление компьютерной науки ни в коем случае нельзя назвать устаревшим или устоявшимся. Наоборот, с ходом времени, с появлением новых отраслей и задач, для решения которых применяются компьютеры, возникает потребность в разработке новых, более удобных языков программирования. Соответственно, для этих языков нужны компиляторы. Windows, Linux, MacOS - для каждой платформы существуют свои разработки.

    Принцип работы

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

    Просто, но сложно

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

    С другой точки зрения, сама тема создания таких программ подразумевает большое число теоретических и технологических аспектов, которые связаны с программированием. Многие разработчики полагают, что эта тема вообще является самой привлекательной во всей информатике. Когда программист разрабатывает какую-либо программу, которая решает некую задачу, он пишет ее на определенном языке. В процессе разработки он оперирует терминами, близкими именно к той области, с которой приходится иметь дело. Компьютер совсем не понимает того, что ему говорит человек. Он способен разобраться лишь в достаточно простых вещах, к которым можно отнести числа и переменные, ячейки и регистры, постоянную и временную память. Что такое программа, задача которой - перевод понятий, близких к разработчика в понятия, которыми способен манипулировать компьютер.

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

    Трудности в создании

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

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

    Класс и компилятор

    Наверное, многие слышали о таких языках, как C и C++. Ведь они являются одними из самых популярных и распространенных. Это очень серьезные языки программирования, содержащие мощные понятия, которые удобны для того, чтобы отображать понятия прикладных областей, в сфере которых трудятся разработчики. К примеру, есть там понятие классов, функций. Они являются основополагающими для многих языков, но для C++ они в особенности характерны.

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

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

    Разработка компиляторов как работа

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

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

    Таким образом, теперь вам должно быть понятно, что такое компилятор. Это программа-переводчик между разработчиком и компьютером, без которой в сфере компьютерной науки никуда.

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

    Для подготовки программы к выполнению, специальная программа собирает ее из исходного кода на языке программирования в машинный код - команды процессора. Этот процесс называется компиляция. Linux - это свободное программное обеспечение, а поэтому исходные коды программ доступны всем желающим. Если программы нет в репозитории или вы хотите сделать что-то нестандартное, то вы можете выполнить компиляцию программы.

    В этой статье мы рассмотрим, как выполняется компиляция программ Linux, как происходит процесс компиляции, а также рассмотрим насколько гибко вы сможете все настроить.

    Мы будем компилировать программы, написанные на Си или С++, так как это наиболее используемый язык для программ, которые требуют компиляции. Мы уже немного рассматривали эту тему в статье установка из tar.gz в Linux, но та статья ориентирована больше на новичков, которым нужно не столько разобраться, сколько получить готовую программу.

    В этой же статье тема рассмотрена более детально. Как вы понимаете, для превращения исходного кода в команды процессора нужно специальное программное обеспечение. Мы будем использовать компилятор GCC. Для установки его и всех необходимых инструментов в Ubuntu выполните:

    sudo apt install build-essential manpages-dev git automake autoconf

    Затем вы можете проверить правильность установки и версию компилятора:

    Но перед тем как переходить к самой компиляции программ рассмотрим более подробно составляющие этого процесса.

    Как выполняется компиляция?

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

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

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

    Затем все объектные файлы собираются в одну программу, связываются с системными библиотеками. После завершения этого этапа программу остается только установить в файловую систему и все. Вот такие основные фазы компиляции программы, а теперь перейдем ближе к практике.

    Компиляция программ Linux

    Первое что нам понадобиться - это исходники самой программы. В этом примере мы будем собирать самую последнюю версию vim. Это вполне нейтральная программа, достаточно простая и нужная всем, поэтому она отлично подойдет для примера.

    Получение исходников

    Первое что нам понадобиться, это исходные коды программы, которые можно взять на GitHub. Вы можете найти исходники для большинства программ Linux на GitHub. Кроме того, там же есть инструкции по сборке:

    Давайте загрузим сами исходники нашей программы с помощью утилиты git:

    git clone https://github.com/vim/vim

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

    Настройка configure

    Дальше нам нужно запустить скрипт, который проверит нашу программу на совместимость с системой и настроит параметры компиляции. Он называется configure и поставляется разработчиками программы вместе с исходниками. Весь процесс компиляции описан в файле Makefile, его будет создавать эта утилита.

    Если configure нет в папке с исходниками, вы можете попытаться выполнить такие скрипты чтобы его создать:

    ./bootstrap
    $ ./autogen.sh

    Также для создания этого скрипта можно воспользоваться утилитой automake:

    aclocal
    $ autoheader
    $ automake --gnu --add-missing --copy --foreign
    $ autoconf -f -Wall

    Утилита automake и другие из ее набора генерируют необходимые файлы на основе файла Mackefile.am. Этот файл обязательно есть в большинстве проектов.

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

    ./configure --help

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

    • --prefix=PREFIX - папка для установки программы, вместо /, например, может быть /usr/local/, тогда все файлы будут распространены не по основной файловой системе, а в /usr/local;
    • --bindir=DIR - папка для размещения исполняемых файлов, должна находится в PREFIX;
    • --libdir=DIR - папка для размещения и поиска библиотек по умолчанию, тоже в PREFIX;
    • --includedir=DIR - папка для размещения man страниц;
    • --disable-возможность - отключить указанную возможность;
    • --enable-возможность - включить возможность;
    • --with-библиотека - подобно enable активирует указанную библиотеку или заголовочный файл;
    • --without-библиотека - подобное disable отключает использование библиотеки.

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

    Во время настройки утилита будет проверять, есть ли все необходимые библиотеки в системе, и если нет, вам придется их установить или отключить эту функцию, если это возможно. Например, может возникнуть такая ошибка: no terminal library found checking for tgetent()... configure: error: NOT FOUND!

    В таком случае нам необходимо установить требуемую библиотеку. Например, программа предлагает ncurses, поэтому ставим:

    sudo apt install libncurces-dev

    Приставка lib всегда добавляется перед библиотеками, а -dev - означает, что нам нужна библиотека со всеми заголовочными файлами. После удовлетворения всех зависимостей настройка пройдет успешно.

    Сборка программы

    Когда настройка будет завершена и Makefile будет готов, вы сможете перейти непосредственно к сборке программы. На этом этапе выполняется непосредственно преобразование исходного кода в машинный. Утилита make на основе Makefile сделает все необходимые действия:

    После этого программа будет установлена в указанную вами папку, и вы сможете ее использовать. Но более правильный путь - создавать пакет для установки программы, это делается с помощью утилиты checkinstall, она позволяет создавать как deb, так и rpm пакеты, поэтому может использоваться не только в Ubuntu. Вместо make install выполните:

    Затем просто установите получившийся пакет с помощью dpkg:

    sudo dpkg install vim.deb

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

    Если вы устанавливали программу с помощью make install, то удалить ее можно выполнив в той же папке обратную команду:

    sudo make uninstall

    Команда удалит все файлы, которые были скопированы в файловую систему.

    Выводы

    В этой статье мы рассмотрели, как выполняется компиляция программы Linux. Этот процесс может быть сложным для новичков, но в целом, все возможно, если потратить на решение задачи несколько часов. Если у вас остались вопросы, спрашивайте в комментариях!

    На завершение видео о том, что такое компилятор и интерпретатор: