Компиляция приложений


Содержание

Компиляция приложений

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

Некоторые компиляторы (например, низкоуровневом языке. Такой язык — байт-код — также можно считать языком машинных команд, поскольку он подлежит интерпретации виртуальной машиной. Например, для языка Java это JVM (язык виртуальной машины Java), или так называемый байт-код Java (вслед за ним все промежуточные низкоуровневые языки стали называть байт-кодами). Для языков программирования на платформе .NET Framework (C#, 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) до сих пор физически объединены со своими компоновщиками. В связи с этим, вместо термина «компилятор» иногда используют термин «транслятор» как его синоним: либо в старой литературе, либо когда хотят подчеркнуть его способность переводить программу в машинный код (и наоборот, используют термин «компилятор» для подчёркивания способности собирать из многих файлов один).

Интересные факты

  • На заре развития компьютеров первые компиляторы (трансляторы) называли «программирующими программами» [6] (так как в тот момент программой считался только машинный код, а «программирующая программа» была способна из человеческого текста сделать машинный код, то есть запрограммировать ЭВМ).

Примечания

  1. ГОСТ 19781-83 // Вычислительная техника. Терминология: Справочное пособие. Выпуск 1 / Рецензент канд. техн. наук Ю. П. Селиванов. — М.: Издательство стандартов, 1989. — 168 с. — 55 000 экз. — ISBN 5-7050-0155-X
  2. 1234567Першиков В. И., Савинков В. М. Толковый словарь по информатике / Рецензенты: канд. физ.-мат. наук А. С. Марков и д-р физ.-мат. наук И. В. Поттосин. — М.: Финансы и статистика, 1991. — 543 с. — 50 000 экз. — ISBN 5-279-00367-0
  3. 123 СТ ИСО 2382/7-77 // Вычислительная техника. Терминология. Указ. соч.
  4. Борковский А. Б. Англо-русский словарь по программированию и информатике (с толкованиями). — М.: Русский язык, 1990. — 335 с. — 50 050 (доп.) экз. — ISBN 5-200-01169-3
  5. Толковый словарь по вычислительным системам = Dictionary of Computing / Под ред. В. Иллингуорта и др.: Пер. с англ. А. К. Белоцкого и др.; Под ред. Е. К. Масловского. — М.: Машиностроение, 1990. — 560 с. — 70 000 (доп.) экз. — ISBN 5-217-00617-X (СССР), ISBN 0-19-853913-4 (Великобритания)
  6. Н. А. Криницкий, Г. А. Миронов, Г. Д. Фролов. Программирование / Под ред. М. Р. Шура-Бура. — М.: Государственное издательство физико-математической литературы, 1963.

См. также

  • Компилятор компиляторов
  • «Книга дракона» — классический учебник о построении компиляторов.
  • Синтаксический анализ
  • Интерпретатор

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

  • GCC
  • Free Pascal Compiler
  • Sun Studio — компиляторы C, C++ и Fortran от Sun Microsystems Inc.
  • Open Watcom — свободное продолжение компиляторов Watcom C/C++/Fortran.
  • Intel C++/Fortran compiler
  • 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 .

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

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

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

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

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

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

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

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

Паскаль (язык) — Pascal Семантика: процедурный Тип исполнения: компилятор Появился в: 1970 г. Автор(ы): Никлаус Вирт Паскаль (англ. Pascal) высокоуровневый язык программирования общего назначения. Один из наиболее известных языков программирования, широко… … Википедия

Паскаль (язык программирования) — Эта статья или раздел нуждается в переработке. В Паскале нет модулей, ООП и прочих новомодных веяний. Описание расширений должно присутствовать только в статьях о соответ … Википедия

D (язык программирования) — У этого термина существуют и другие значения, см. D. D Семантика: мультипарадигменный: императивное, объектно ориентированное, обобщённое программирование Тип исполнения: компилятор Появился в: 1999 Автор(ы) … Википедия

Компиляция и распространение приложений

Компиляция проекта

Вкладка Make

Настройка параметров компиляции

Использование Package and Deployment Wizard

Распространение приложений

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

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

Компиляция проекта

До чего же приятно заканчивать работу над приложением! Сотни часов проектирования, программирования, тестирования и отладки остались позади. Похоже, все работает нормально. Прежде всего сохраните свою работу, но позаботьтесь о том, чтобы это была последняя версия программы. Теперь необходимо откомпилировать проект и превратить его в выполняемый файл (ЕХЕ), библиотеку динамической компоновки (DLL) или элемент ActiveX (OCX). Благодаря этому другие пользователи смогут пользоваться вашей программой, и при этом им не придется покупать и устанавливать на своем компьютере Visual Basic. В этом уроке мы научимся компилировать проекты на примере приложения Visual Basic Terminal.

Но даже на стадии компиляции работа еще не закончена. Вы должны создать программу, устанавливающую ваше приложение и сопутствующие файлы на компьютер пользователя. Для этого в Visual Basic предусмотрен специальный мастер -Package and Deployment Wizard. Эта удобная утилита создает полноценную программу установки на основании всего нескольких простейших вопросов. Существуют и другие утилиты (как коммерческие, так и условно бесплатные), которые создают хорошие программы инсталляции, но в нашем примере будет использован именно Package and Deployment Wizard.

Предположим, вы только что закончили работу над приложением и теперь собираетесь откомпилировать его и заняться тестированием. Откройте проект VB Terminal (файл Vbterm.vbp из каталога \Samples\CompTool\MsComm), затем действуйте так:


1. Откройте проект VB Terminal (файл Vbterm.vbp из каталога \MSDN\98VS\1033\ Samples\VB98\MsComm).

2. Выполните команду File > Make vbterm.exe в меню Visual Basic.

3. Когда откроется диалоговое окно Make Project, в поле File Name должна содержаться строка vbterm.exe. Нажмите кнопку Options.

На экране появляется упрощенный вариант диалогового окна свойств проекта. Он состоит всего из двух вкладок, Make и Compile, каждая из которых рассматривается в следующих разделах.

Вкладка Make

На вкладке Make содержатся различные параметры, влияющие на ход сборки программы. Вы можете изменять номер версии, лицензионную информацию и т. д. Вкладка Make делится на четыре группы: Version Number, Application, Version Information, — и два текстовых поля с именами Command Line Arguments и Conditional Compilation Arguments (рис. 14.1). В диалоговом окне VBTerm также присутствует вкладка Compile, на которой содержатся параметры для компиляции приложения в Р-код или в машинный код. Эти возможности рассматриваются далее, в разделе «Вкладка Compile».

Рис. 14.1. Вкладка Make диалогового окна свойств проекта VВТет

Номер версии

Рамка Version Number содержит три поля и один флажок. В этом разделе мы научимся задавать номер версии приложения. Номер версии состоит из трех частей: основного (major) и вспомогательного (minor) номеров, а также номера ревизии (также называемого номером сборки). Нумерация версий приложения обычно начинается с 1.0.0, что соответствует самой первой сборке первой версии. Обратите внимание на то, что в поле Revision на рис. 14.1 содержится значение 8139. Вряд ли наше учебное приложение может иметь столько сборок, но, во всяком случае, ребята из Редмонда ввели именно такое значение. Установка флажка Auto Increment в нижней части рамки приводит к тому, что Visual Basic будет автоматически увеличивать номер ревизии приложения при каждой компиляции. Старайтесь включать в свои проекты номера версии и ревизии. Благодаря им вы и ваши пользователи сможете различать выполняемые файлы приложения и определять, к какой сборке они относятся. Номер версии выводится с остальными свойствами программы — для этого следует щелкнуть правой кнопкой мыши на файле приложения в Проводнике Windows, выбрать из контекстного меню команду Properties 1 и перейти на вкладку Version в диалоговом окне Properties. Номера ревизий бывают особенно полезны, когда пользователи обращаются за технической поддержкой. Если вы раздали несколько версий вашего приложения, каждая из которых обладает своими ошибками, то по номеру ревизии всегда можно определить, получил ли пользователь исправленную версию. Помимо установки флажка Auto Increment я рекомендую вам сохранять информацию об изменениях в каждой сборке. Возможно, эти описания даже стоит занести в базу данных и отсортировать записи по номерам версий и ревизий. Это сильно облегчит вашу будущую работу по сопровождению продукта.

ПОДСКАЗКАСтарайтесь документировать изменения, вносимые в очередную версию программы. Эта информация окажется полезной при решении технических проблем или реализации новых возможностей.

Приложение

Рамка Application содержит два поля — Title и Icon. В поле Title содержится имя приложения, совпадающее с именем, под которым был сохранен проект. Список из поля Icon позволяет выбрать из проекта форму, значок которой будет представлять ваше приложение. Значок приложения обычно задается в главной форме, которая, как вы уже знаете, как правило, получает имя frmMain. В этом случае в поле Icon выбирается форма frmMain. При выборе нужной формы из списка справа от него появляется изображение значка.

Сведения о версии

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

Выбрав из списка Туре строку Comments, можно ввести любые комментарии по поводу текущей версии, например сообщить, что текущая сборка является бета-версией. Сюда можно ввести любую информацию, не относящуюся к другим разделам. Если вы захотите указать организацию, которой принадлежат права на ваше приложение, выберите из списка Туре строку Company Name и введите описание в поле Value. Строка File Description служит для ввода любой информации, относя щейся к откомпилированному файлу.

1 Команда Свойства в локализованной версии. — Примем, перев.

Авторские права

Строка Legal Copyright, вероятно, определяет одно из самых важных свойств откомпилированного приложения. Позвольте мне сказать несколько слов на эту тему: когда вы создаете программу, произведение искусства и т. д., вы автоматически становитесь обладателем авторских прав на нее. Вы можете отказаться от них и явно указать, что ваша работа (в нашем случае — приложение) является общим достоянием (public domain). Если же вы хотите извлечь выгоду из своих авторских прав, зарегистрируйте свое приложение в Бюро по вопросам авторских прав в США. Данная тема выходит за рамки этой книги, но если вы намерены продавать свою программу, найдите книгу по авторским правам и товарным знакам. Включая в поле Legal Copyright информацию об авторских правах, вы сообщаете пользователям, кому принадлежит данный продукт. Чтобы информация об авторском праве имела юридическую силу, необходимо указать имя приложения, слово Copyright (именно в таком написании) и год выхода первой версии. Если вы хотите, чтобы ваши авторские привилегии сохранялись и за рубежом, необходимо также включить слова «All rights Reserved». Например, формулировка авторских прав может выглядеть так:

МуАрр Version 1.0.5 Copyright 1996 — Steve Brown

All rights Reserved

И все же не стоит полагаться на мои слова — найдите хорошую книгу по авторскому праву или даже проконсультируйтесь с юристом.

ПОДСКАЗКАОбязательно включайте в свои приложения сведения об авторских правах. Тем самым вы сообщаете пользователю, кому принадлежат юридические права на программу.

Если ваша программа содержит эмблему компании или другое изображение, которое представляет вас, ваши организацию или продукт, включите соответствующие ссылки в поле Legal Trademarks.

В поле Product Name указывается полное имя приложения. Например, строка VBTerm выглядит не слишком содержательно, поэтому в поле Value можно указать ее расшифровку — Visual Basic Terminal. Кроме того, полное имя помогает различить приложения с одинаковыми сокращенными именами. Допустим, у вас есть два выполняемых файла с именем Hello.exe: первый — приложение Hello World, написанное нами в самом начале книги, а второй — программа Hello, которая автоматически приветствует пользователя при запуске компьютера. Сами видите, как важно иногда знать полное имя приложения. При повторной компиляции приложения вам не придется вводить текст в этих полях. Visual Basic запоминает их содержимое и использует при всех последующих компиляциях. Вам остается лишь изменять эту информацию в случае необходимости.

Илон Маск рекомендует:  Шаблон сайта центр HTML, CSS, Шрифты, Photoshop (psd), JavaScripts, 6 страниц

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: На стипендию можно купить что-нибудь, но не больше. 8983 — | 7233 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

Компиляция приложений gtk

26.08.2020

Для разработки приложений с использованием библиотеки gtk нужно немного: установить пакет libgtk2.0-dev и должным образом отредактировать make файл вашего приложения. В принципе ничего сложного. Но я хотел бы подробнее остановиться на этой строчке, которую нужно добавить в make файл.

Полная строка компиляции вашего приложения должна выглядеть примерно так:

Здесь main.cpp — файл с иcходным кодом вашего приложения, main — имя исполняемого модуля.

Добавочная строка, заключенная в обратные апострофы — тот самый придаток, необходимый для компиляции приложения, использующего библиотеку gtk. Она приведена во всех книгах и руководствах по gtk, но практически нигде не дается ее расшифровка. Что она делает? Зачем нужна? Давайте разбираться.

Начнем с апострофов. Они нужны для изменения порядка выполнения операций. Сначала выполняется команда заключенная в них, а потом ее результат передается компилятору g++ при его вызове. Если бы строка была заключена в обычные кавычки, то она передавалась бы компилятору как есть. Разумеется, он не смог бы ее обработать и возникла бы ошибка. По сути обратные апострофы делают то же самое, что и конструкция $(). То есть, команда, приведенная ниже эквивалентна исходной

Но, поскольку эта строка прописывается в make файле, а утилита make иначе интерпретирует конструкцию $(), то второй вариант не используют. Результат работы строки, заключенной в обратные апострофы подставляется на место ее вызова. То есть итоговый вызов компилятора имеет вид:

С этим разобрались. Теперь посмотрим на то, что делает эта строка в обратных апострофах:

В ней вызывается утилита pkg-config. Она предназначена для сбора и должного оформления информации об используемой библиотеке (в нашем случае, gtk+-2.0). Работает это следующим образом. При установке библиотеки gtk+-2.0 (и не только ее) в специальный каталог помещается текстовый файл с расширением pc. В нем сохраняется список библиотек и заголовочных файлов, которые необходимы для компиляции вашего приложения. Наш файл gtk+-2.0.pc расположен в каталоге /usr/lib/x86_64-linux-gnu/pkgconfig/ (у вас он может отличаться) и имеет следующее содержание.

Утилита pkg-config берет этот файл, анализирует его содержимое и передает компилятору g++. Ключи —cflags и —libs указывают pkg-config какую информацию нужно извлекать из pc файла. А именно:

—cflags — выводить флаги препроцессора и компилятора;

Декомпиляция и Компиляция APK приложения Андроид

вкл. 24 Сентябрь 2020 . Опубликовано в Android — Общее

Декомпиляция и Компиляция APK приложения Андроид. Для того чтобы редактировать APK приложения. Прежде всего их нужно декомпилировать, а после скомпилировать! Как это сделать и чем можно узнать в этом уроке.

В прошлом уроке вы узнали из чего состоят основные внутренности приложения, а также что данные что APK приложения (в дальнейшем просто APK) можно открыть архиватором, но что либо изменить у вас не получиться! Нужна Декомпиляция APK приложения Android!

Декомпиляция и Компиляция APK приложения Android — Необходимые компоненты

1. Java JDK — среда разработки;

2. ApkTool — программа декомпилятор;

4. Sign Android — подпись приложения APK

Установка необходимых компонентов. Настройка Java

После установки Java JDK , необходимо, добавить ее в переменную Windows . Если кто не понял официальное куроводство то,

Скопируйте путь Java JDK:

Перейдите в меню Дополнительные настройки

(Мой) Компьютер ->Свойства системы->Дополнительные параметры системы->Дополнительно->Системные переменные->Правка

Java JDK настроена.

Настройка ApkTool

  1. Создать папку на диске C:\ и в нее переместить файлы apktool_x_x.jar и apktool.bat
  2. Файл apktool_x_x.jar переименовать в apktool.jar

Если появилось наподобие такой вывод информации, то все сделано правильно.

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

Чтобы декомпилировать приложение, скопируйте файл APK приложения в папку где находится apktool, далее необходимо выполнить вот что, в командной строке ввести команду:

Декомпиляция APK завершена.

После того как вы отредактируете или русифицируете APK, его надо Компилировать

Компиляция APK

Вводим в командной строке:

После чего перейдите в папку проекта ( в данном случае папка browser) и вы увидете две новые папки:

  • build
  • dist


В папке dist будет находится готовое приложение:

Если папки dist не обнаружили, значит apktool не смог собрать редактируемый проект, причиной тому может быть то, что измения которые вы вносили(«поломали») не позволяют собрать приложение apk.

После компиляции приложения apk его необходимо подписать.

Подпись APK

1. Для этого Вам надо разархивировать архив Sign Android

2. Скопировать готовое приложение в папку с распакованным Sign Android

3. Потянуть приложение на файл Sign_APK.bat после чего приложение будет подписано

Готовое подписанное приложение будет носить название apk_signed.apk

Работа с системными APK

Для того чтобы модифицировать системные приложения необходимо прежде всего необходимо скормить программе APKTOOL системный файл framework -res.apk который находиться в системном разделе Android:

Для того чтобы скормить Apktool данный файл необходимо, ввести команду:

Учитывайте что, команду нужно вводить относительно пути расположения, то есть если файл framework -res.apk находиться в папке C:\primer, то команда будет выглядеть следующим обзором:

Также для того чтобы можно было модифицировать системные файлы прошивка должна быть вначале Deodex-ирована.

Теперь как это можно все упросить! (не использовать командную строку)

Скачайте приложение SmartApkTool, данное программа имеет графический интерфейс и очень легкая в использование.

Как пользоваться SmartApkTool

Прежде всего вам надо установить и настроить Java JDK и Apktool как указано выше.

Откройте программу SmartApkTool

Если Вам необходимо Декомпилировать приложение в SmartApkTool, то выберите данный пункт и необходимое приложение

Если компилировать, то

и выбрать файл в проекте apktool.yml

Для подписи приложения APK, нажать обзор, выбрать приложение и подписать

Все так легко и просто!

Альтернативный вариант

Для тех кому не понравился SmartApkTool, есть альтернатива Android MultiTool

Введение в платформу .NET Framework и ASP.NET

Компиляция приложений .NET

Как мы разобрались в предыдущей лекции, процесс компиляции и исполнения приложений . NET отличается от процесса исполнения традиционных ( native ) приложений. При компиляции приложения . NET на выходе получается бинарный файл , который содержит команды на языке MSIL , а не инструкции для центрального процессора. Этот факт отличает процесс функционирования приложений . NET . Фактически, приложения . NET компилируются в два этапа:

  • Исходный код (на языке C#, Visual Basic или др.) преобразуется в MSIL;
  • Код на языке MSIL преобразуется в машинный код.

Теоретически, программный код, разработанный на разных языках программирования в среде . NET (C#, Visual Basic . NET и др.) и преобразованный в код на языке MSIL , в конечном счете, будет иметь одинаковый вид. Кроме того, после преобразования программного кода в MSIL будет затруднительно определить исходный язык программирования .

Для чего необходима подобная двухэтапная компиляция приложения? Те, кто разрабатывал на языках низкого уровня знают, что разработка программного кода имеет специфику при разработке для каждой платформы. Это означает, что разработка приложения для 32- и 64-разрядной платформы может иметь существенные различия. При этом при игнорировании особенностей разработки под конкретную платформу могут быть как некритические последствия (например, в виде снижения производительности), так и критические (например, неработоспособность приложения). В связи с этим зачастую можно видеть два типа пакетов распространения приложения (32- и 64-разрядных). Более того, для более эффективной работы приложения нередко требуется оптимизация его кода. Все эти задачи имеют непростую природу и могут отнимать у разработчика приложения много времени. Разработчик в этом случае должен тратить свое время не на улучшение логики программы, а заботиться об инфраструктурных задачах. Однако, несмотря на всю сложность этого процесса, существуют алгоритмы, которые способны выполнить большую часть работы по оптимизации кода под конкретную платформу без участия человека. Именно этой идеологии придерживается платформа . NET Framework.

При запуске кода на языке IL происходит его преобразование в машинный код. При этом весь процесс преобразования происходит в той среде, где приложение должно быть запущено (на компьютере конечного пользователя, где исполняется приложение ). Этот факт позволяет оптимизировать конечный машинный код, который получается в процессе преобразования, для той платформы, в рамках которой он будет исполняться. Также при таком подходе нет необходимости иметь две различных сборки для разных сред (32- и 64-разрядных) – конечный машинный код будет получен с учетом специфики платформы. Поскольку преобразование » MSIL – машинный код» требует определенного времени, среда исполнения записывает полученный машинный код в системных папках и при последующем запуске приложения, которое запускалось ранее, используется уже готовый код. Общий процесс компиляции выглядит следующим образом.

Механизм, который занимается преобразованием кода MSIL в машинный код, называется компилятором JIT (» just-in-time «). Этот компилятор преобразует код MSIL в машинный код «на лету». Это позволяет сделать процесс запуска приложений более «прозрачным». При запуске исполняемого файла . NET компилятор автоматически определяет, была ли эта сборка скомпилирована.

Поскольку процесс получения машинного кода является трудоемкой задачей, компилятор JIT работает » по запросу». Дело в том, что JIT — компилятор не пытается получить машинный код для всей сборки в момент запуска приложения – машинный код получается только для той части сборки, которая должна быть исполнена в данный момент. Получение машинного кода для остальных частей сборки происходит в момент запуска этих частей на исполнение .

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

В случае, когда необходимо выполнить предкомпиляцию приложения до его запуска (для предотвращения ситуации компиляции приложения «на лету»), можно воспользоваться утилитой NGen ( native image generator ), которая поставляется в составе . NET Framework. Утилита NGen использует аналогичные методы компиляции приложения, что и компилятор JIT . Однако, от компилятора JIT эту утилиту отличает три аспекта:

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

Утилита NGen является консольным приложением и запускается из командной строки. Она позволяет сделать несколько различных действий:

  • скомпилировать сборку и установить ее в кэш сборок (ключ install );
  • удалить сборку из кэша сборок (ключ uninstall );
  • обновить сборку в кэше сборок (ключ update );
  • отобразить состояние процесса компиляции (ключ display );
  • управлять очередью выполнения компиляции (ключ queue ).

Общий процесс компиляции приложений . NET представлен на следующей схеме.

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

Краткие итоги

Все приложения . NET поставляются в виде скомпилированного кода MSIL . Весь процесс компиляции приложения . NET состоит из двух этапов – преобразования исходного кода программы в код на языке MSIL и преобразование кода MSIL в машинный код. Такой процесс позволяет абстрагироваться от платформы исполнения, а также оптимизировать машинный код под конкретную платформу. Преобразование кода MSIL в машинный код происходит в момент запуска программы JIT -компилятором, а результат сохраняется в специальном кэше. Поэтому первый запуск . NET приложения может осуществляться с небольшой задержкой. Однако, этого можно избежать, если использовать утилиту NGen.

Компиляторы

Программы для компиляции (преобразования) скриптов в EXE

Vbs To Exe — компилятор Vbs-сценариев в Exe файл, эта бесплатная программа преобразует скрипты Vbs в исполняемые Exe файлы.

Bat To Exe Converter — конвертер BAT в EXE файл. Бесплатная программа которая может преобразовать пакетный BAT файл в EXE.

HTML Compiler — программа для компиляции HTML в EXE файл, простой компилятор который может упаковать HTML в автономные EXE приложения Windows.

Quick Batch File Compiler — программа для компиляции BAT файлов в EXE формат.

Batch Compiler — программа для преобразования CMD и BAT файлов в формат EXE. Удобный компилятор, который поможет вам создать из пакетных файлов автономные исполняемые файлы.

PHPFlexer — компилятор PHP скриптов в исполняемый файл EXE.

Advanced BAT to EXE Converter — конвертер для преобразования Bat файлов в EXE формат.
Достаточно легкая в обращении программа которая может быстро преобразовать пакетный файл BAT в автономный EXE .

Flash Builder — бесплатный компилятор SWF файлов в EXE, позволяет создать исполняемый EXE файл из любого SWF, в том числе и анимированного.


ScriptCryptor Compiler — компилятор VBScript и JScript в EXE файл.

JarToExe — конвертер для преобразования Jar в Exe. Эта бесплатная утилита позволяет преобразовывать JAR-файлы в исполняемые файлы Exe.

ExeScript — конвертер скриптов в компактные исполняемые файлы, позволяет компилировать BAT, CMD, VBS, JS, HTA, PS1 и WSF файлы в формат EXE.

SiteInFile Compiler — компилятор HTML в EXE. Простая программа для создания электронных книг, маркетинговых презентаций, фотоальбомов и различных руководств из веб-страниц или всего сайта.

Dr.Batcher — программа для создания и редактирования BAT файлов.
Удобное приложение, которое поможет вам с легкостью изменить содержимое пакетных файлов, а также быстро создать новый BAT и CMD-файл .

xlExe — компилятор Excel в исполняемые файлы совместимые со всеми версиями Windows.
Эта небольшая и удобная программа позволяет создать исполняемый файл из .xls, .xlsx, .xlsm и .xltm документов созданных в Microsoft Excel .

Vbs2Exe — бесплатный компилятор для конвертирования VBScript, JavaScript и Batch files в исполняемые EXE файлы. Это приложение поможет вам компилировать скрипты VBS, JS и BAT в EXE файл без каких-либо усилий .

BAT2EXE — конвертер командных файлов в EXE. Эта небольшая бесплатная программа поможет вам преобразовать командные BAT или CMD файлы в исполняемый .EXE файл.

Раздельная компиляция программ на C++

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

Термины

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

Исходный код — программа, написанная на языке программирования, в текстовом формате. А также текстовый файл, содержащий исходный код.

Компилятор — программа, выполняющая компиляцию (неожиданно! не правда ли?). На данный момент среди начинающих наиболее популярными компиляторами C/C++ являются GNU g++ (и его порты под различные ОС) и MS Visual Studio C++ различных версий. Подробнее см. в Википедии статьи: Компиляторы, Компиляторы C++.

Компиляция — преобразование исходного кода в объектный модуль.

Объектный модуль — двоичный файл, который содержит в себе особым образом подготовленный исполняемый код, который может быть объединён с другими объектными файлами при помощи редактора связей (компоновщика) для получения готового исполняемого модуля, либо библиотеки. (подробности)

Компоновщик (редактор связей, линкер, сборщик) — это программа, которая производит компоновку («линковку», «сборку»): принимает на вход один или несколько объектных модулей и собирает по ним исполнимый модуль. (подробности)

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

Препроцессор — программа для обработки текста. Может существовать как отдельная программа, так и быть интегрированной в компилятор. В любом случае, входные и выходные данные для препроцессора имеют текстовый формат. Препроцессор преобразует текст в соответствии с директивами препроцессора. Если текст не содержит директив препроцессора, то текст остаётся без изменений. Подробнее см. в Википедии: Препроцессор и Препроцессор Си.

IDE (англ. Integrated Development Environment) — интегрированная среда разработки. Программа (или комплекс программ), предназначенных для упрощения написания исходного кода, отладки, управления проектом, установки параметров компилятора, линкера, отладчика. Важно не путать IDE и компилятор. Как правило, компилятор самодостаточен. В состав IDE компилятор может не входить. С другой стороны с некоторыми IDE могут быть использованы различные компиляторы. (подробности)

Объявление — описание некой сущности: сигнатура функции, определение типа, описание внешней переменной, шаблон и т.п. Объявление уведомляет компилятор о её существовании и свойствах.

Определение — реализация некой сущности: переменная, функция, метод класса и т.п. При обработке определения компилятор генерирует информацию для объектного модуля: исполняемый код, резервирование памяти под переменную и т.д.

От исходного кода к исполняемому модулю

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

Часто компиляцией программы называют весь процесс преобразования исходного кода в исполняемы модуль. Что неправильно. Обратите внимание, что в IDE этот процесс называется построение (build) проекта.

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

Итак, допустим, у нас есть программа на C++ «Hello, World!»:

Сначала исходный код обрабатывается препроцессором. Препроцессор находит директиву #include , ищет файл iostream и заменяет директиву текстом из этого файла, попутно обрабатывая все директивы препроцессора во включаемом тексте.

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

Илон Маск рекомендует:  Тег area

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

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

Что бы получить нормальный исполняемый модуль, необходимо «разрешить» внешние ссылки. Т.е. добавить в исполняемый модуль код отсутствующих подпрограмм и настроить соответствующим образом все ссылки на этот код. Этим занимается компоновщик. Он анализирует таблицу внешних ссылок объектного модуля, ищет в объектных библиотеках недостающие модули, копирует их в исполняемый модуль и настраивает ссылки. После этого исполняемый модуль готов.

Библиотека (объектная библиотека) — это набор откомпилированных подпрограмм, собранных в единый файл определённой структуры. Подключение библиотеки происходит на этапе компоновки исполняемого файла из объектных файлов (т.е. из тех файлов, которые получаются в результате компиляции исходного текста программы).

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

Если исходный код программы разделён на несколько файлов, то процесс компиляции и сборки происходит аналогично. Сначала все единицы компиляции по отдельности компилируются, а затем компоновщик собирает полученные объектные модули (с подключением библиотек) в исполняемый файл. Собственно, этот процесс и называется раздельной компиляцией.

Разделение текста программы на модули

Разделение исходного текста программы на несколько файлов становится необходимым по многим причинам:

  1. С большим текстом просто неудобно работать.
  2. Разделение программы на отдельные модули, которые решают конкретные подзадачи.
  3. Разделение программы на отдельные модули, с целью повторного использования этих модулей в других программах.
  4. Разделение интерфейса и реализации.

Я намеренно использовал слово «модуль», поскольку модулем может быть как класс, так и набор функций — вопрос используемой технологии программирования.

Как только мы решаем разделить исходный текст программы на несколько файлов, возникают две проблемы:

  1. Необходимо от простой компиляции программы перейти к раздельной. Для этого надо внести соответствующие изменения либо в последовательность действий при построении приложения вручную, либо внести изменения в командные или make-файлы, автоматизирующие процесс построения, либо внести изменения в проект IDE.
  2. Необходимо решить каким образом разбить текст программы на отдельные файлы.

Первая проблема — чисто техническая. Она решается чтением руководств по компилятору и/или линкеру, утилите make или IDE. В самом худшем случае просто придётся проштудировать все эти руководства. Поэтому на решении этой проблемы мы останавливаться не будем.

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

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

Во-вторых, нужно определить интерфейсы для модулей. Здесь есть вполне чёткие правила.

Интерфейс и реализация

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

Таким образом, модуль состоит из двух файлов: заголовочного (интерфейс) и файла реализации.

Заголовочный файл, как правило, имеет расширение .h или .hpp, а файл реализации — .cpp для программ на C++ и .c, для программ на языке C. (Хотя в STL включаемые файлы вообще без расширений, но, по сути, они являются заголовочными файлами.)

Заголовочный файл должен содержать все объявления, которые должны быть видны снаружи. Объявления, которые не должны быть видны снаружи, делаются в файле реализации.

Что может быть в заголовочном файле

Правило 1. Заголовочный файл может содержать только объявления. Заголовочный файл не должен содержать определения.

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

Единственным «исключением» из этого правила является определение метода в объявлении класса. Но по стандарту языка, если метод определён в объявлении класса, то для этого метода используется инлайновая подстановка. Поэтому, такое объявление не порождает исполняемого кода — код будет генерироваться компилятором только при вызове этого метода.

Аналогичная ситуация и с объявлением переменных-членов класса: код будет порождаться при создании экземпляра этого класса.

Правило 2. Заголовочный файл должен иметь механизм защиты от повторного включения.

Защита от повторного включения реализуется директивами препроцессора:

Для препроцессора при первом включении заголовочного файла это выглядит так: поскольку условие «символ SYMBOL не определён» ( #ifndef SYMBOL ) истинно, определить символ SYMBOL ( #define SYMBOL ) и обработать все строки до директивы #endif . При повторном включении — так: поскольку условие » символ SYMBOL не определён» ( #ifndef SYMBOL ) ложно (символ был определён при первом включении), то пропустить всё до директивы #endif .

В качестве SYMBOL обычно применяют имя самого заголовочного файла в верхнем регистре, обрамлённое одинарными или сдвоенными подчерками. Например, для файла header.h традиционно используется #define __HEADER_H__ . Впрочем, символ может быть любым, но обязательно уникальным в рамках проекта.

В качестве альтернативного способа может применяться директива #pragma once . Однако преимущество первого способа в том, что он работает на любых компиляторах.

Заголовочный файл сам по себе не является единицей компиляции.

Что может быть в файле реализации

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

Правило 3. В файле реализации должна быть директива включения соответствующего заголовочного файла.

Понятно, что объявления, которые видны снаружи модуля, должны быть также доступны и внутри.

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


Правило 4. В файле реализации не должно быть объявлений, дублирующих объявления в соответствующем заголовочном файле.

При выполнении Правила 3, нарушение Правила 4 приведёт к ошибкам компиляции.

Практический пример

Допустим, у нас имеется следующая программа:

main.cpp

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

Итак, что у нас имеется?

  1. глобальная константа cint , которая используется и в классе, и в main ;
  2. глобальная переменная global_var , которая используется в функциях func1 , func2 и main ;
  3. глобальная переменная module_var , которая используется только в функциях func1 и func2 ;
  4. функции func1 и func2 ;
  5. класс CClass ;
  6. функция main .

Вроде вырисовываются три единицы компиляции: (1) функция main , (2) класс CClass и (3) функции func1 и func2 с глобальной переменной module_var , которая используется только в них.

Не совсем понятно, что делать с глобальной константой cint и глобальной переменной global_var . Первая тяготеет к классу CClass , вторая — к функциям func1 и func2 . Однако предположим, что планируется и эту константу, и эту переменную использовать ещё в каких-то, пока не написанных, модулях программы. Поэтому прибавится ещё одна единица компиляции.

Теперь пробуем разделить программу на модули.

Сначала, как наиболее связанные сущности (используются во многих местах программы), выносим глобальную константу cint и глобальную переменную global_var в отдельную единицу компиляции.

globals.h

globals.cpp

Обратите внимание, что глобальная переменная в заголовочном файле имеет спецификатор extern . При этом получается объявление переменной, а не её определение. Такое описание означает, что где-то существует переменная с таким именем и указанным типом. А определение этой переменной (с инициализацией) помещено в файл реализации. Константа описана в заголовочном файле.

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

Также обратите внимание (1) на защиту от повторного включения заголовочного файла и (2) на включение заголовочного файла в файле реализации.

Затем выносим в отдельный модуль функции func1 и func2 с глобальной переменной module_var . Получаем ещё два файла:

funcs.h

funcs.cpp

Поскольку переменная module_var используется только этими двумя функциями, её объявление в заголовочном файле отсутствует. Из этого модуля «на экспорт» идут только две функции.

В функциях используется переменная из другого модуля, поэтому необходимо добавить #include «globals.h» .

Наконец выносим в отдельный модуль класс CClass :

CClass.h

CClass.cpp

Обратите внимание на следующие моменты.

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

(2) Класс имеет статический член класса. Т.е. для всех экземпляров класса эта переменная будет общей. Её инициализация выполняется не в конструкторе, а в глобальной области модуля.

(3) В файл реализации добавлена директива #include «globals.h» для доступа к константе cint .

Классы практически всегда выделяются в отдельные единицы компиляции.

В файле main.cpp оставляем только функцию main . И добавляем необходимые директивы включения заголовочных файлов.

main.cpp

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

Типичные ошибки

Ошибка 1. Определение в заголовочном файле.

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

Ошибка 2. Отсутствие защиты от повторного включения заголовочного файла.

Тоже проявляет себя при определённых обстоятельствах. Может вызывать ошибку компиляции «многократное определение символа . ».

Ошибка 3. Несовпадение объявления в заголовочном файле и определения в файле реализации.

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

Ошибка 4. Отсутствие необходимой директивы #include .

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

Ошибка 5. Отсутствие необходимого модуля в проекте построения программы.

Вызывает ошибку компоновки «не определён символ . ». Обратите внимание, что имя символа в сообщении компоновщика почти всегда отличается от того, которое определено в программе: оно дополнено другими буквами, цифрами или знаками.

Ошибка 6. Зависимость от порядка включения заголовочных файлов.

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

Заключение

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

LibreBay

Статьи про ОС Ubuntu. Языки программирования Си и C++.
Инструменты разработки и многое другое.

понедельник, 5 декабря 2020 г.

Как скомпилировать программу на C/C++ в Ubuntu

Помню, когда я только начинал программировать, у меня возник вопрос: «Как скомпилировать программу на C в Ubuntu?» Для новичков это не легкая задача, как может показаться на первый взгляд.

Мой путь изучения C начался с бестселлера «Брайан Керниган, Деннис Ритчи, Язык программирования C, 2-е издание». Там рассказывается как скомпилировать программу в операционной системе Unix, но этот способ не работает в Linux. Авторы книги выкрутились, написав следующее:

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

Текстовый редактор gedit

Для написания первых программ подойдет обычный, используемый по умолчанию в Ubuntu, текстовый редактор с подсветкой синтаксиса — gedit.

Рис. 1. Запуск текстового редактора.

Первой программой по традиции является «Hello, World!», выводящее приветствие на экран:

Печатаем или копируем текст программы в gedit и сохраняем в файл Hello.c , например, на рабочий стол. Не самое лучше место для сохранения, но это позволит рассмотреть случай, когда в имени директории содержится пробел.

Рис. 2. Программа hello, World.

Компиляция программы на C

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

Далее в терминале нам необходимо перейти в директорию, куда сохранили файл с текстом программы. Перемещение выполняется командой cd (англ. change directory — изменить каталог). Чтобы воспользоваться командой в начале пишется cd , затем через пробел путь , куда нужно перейти.

Для перехода на рабочий стол, команда будет следующей:

Обратите внимание на символ обратной косой черты \ в имени директории Рабочий стол . Обратная косая экранирует пробел, и сообщает команде cd , что пробел и следующие за ним символы являются частью имени. Символ

в начале пути обозначает путь до домашней папки пользователя.


Для просмотра содержимого директории применяется команда ls (сокращение от англ. list).

Рис. 3. Работа в терминале.

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

где:

  • gcc — компилятор для языка программирования C;
  • -Wall — ключ вывода всех предупреждений компилятора;
  • -o hello — с помощью ключа -o указывается имя выходного файла;
  • hello.c — имя нашего исходного файла, который компилируем.

Выполнив команду ls , увидим, что появилась наша скомпилированная программа hello , отмеченная цветом, обозначающим исполняемые программы.

В завершение запустим hello , вводом имени программы с префиксом ./ :

Префикс ./ сообщает терминалу о необходимости выполнить программу с заданным именем в текущем каталоге. (Точка — это условное название текущего каталога.)

Рис. 4. Работа в терминале, продолжение.

Компиляция программы на С++

Программы на C++ компилируются аналогично, как и программы на C. «Hello, World!» на C++ можно написать так:

Сохраняем текст программы в файл под именем hello2.cpp . Таким образом, команда компилирования будет иметь вид:

Для запуска результата вводим в терминале:

Заключение

Данный способ позволяет скомпилировать программу лишь из одного файла с исходным кодом. Но этого вполне достаточно, чтобы начать изучение языков программирования C/C++ по книгам или по статьям в интернете.

Более подробно об программировании в Ubuntu или в любом другом дистрибутиве Linux можно прочитать в книгах:

  • Иванов Н. Н. — Программирование в Linux. Самоучитель. — 2-е издание;
  • Нейл Метьэ, Ричард Стоунс — Основы программирования в Linux: Пер. с англ. — 4-е издание;
  • Колисниченко Д. Н. — Разработка Linux-приложений.

KNZSOFT Разработка ПО, консультации, учебные материалы

Князев Алексей Александрович. Независимый программист и консультант.

С++ для начинающих. Урок 1. Компиляция

    Содержание

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

Существует множество компиляторов с языка C++, которые можно использовать для создания исполняемого кода под разные платформы. Проекты компиляторов можно классифицировать по следующим критериям.

  1. Коммерческие и некоммерческие проекты
  2. Уровень поддержки современных тенденций и стандартов языка
  3. Эффективность результирующего кода

Если на использование коммерческих компиляторов нет особых причин, то имеет смысл использовать компилятор с языка C++ из GNU коллекции компиляторов (GNU Compiler Collection). Этот компилятор есть в любом дистрибутиве Linux, и, он, также, доступен для платформы Windows как часть проекта MinGW (Minumum GNU for Windows). Для работы с компилятором удобнее всего использовать какой-нибудь дистрибутив Linux, но если вы твердо решили учиться программировать под Windows, то удобнее всего будет установить некоммерческую версию среды разработки QtCreator вместе с QtSDK ориентированную на MinGW. Обычно, на сайте производителя Qt можно найти инсталлятор под Windows, который сразу включает в себя среду разработки QtCreator и QtSDK. Следует только быть внимательным и выбрать ту версию, которая ориентирована на MinGW. Мы, возможно, за исключением особо оговариваемых случаев, будем использовать компилятор из дистрибутива Linux.

GNU коллекция компиляторов включает в себя несколько языков. Из них, группу языков Си составляет три компилятора.

  1. g++ — компилятор с языка C++.
  2. gcc — компилятор с языка C (GNU C Compiler).
  3. gcc -lobjc — Objective-C — это, фактически, язык C с некоторой макро-магией, которая доступна в объектной библиотеке objc. Ее следует поставить и указать через ключ компиляции -l.

Этапы компиляции

Процесс обработки текстовых файлов с кодом на языке C++, который упрощенно называют «компиляцией», на самом деле, состоит из четырех этапов.

  1. Препроцессинг — обработка текстовых файлов утилитой препроцессора, который производит замены текстов согласно правилам языка препроцессора C/C++. После препроцессора, тексты компилируемых файлов, обычно, значительно вырастают в размерах, но теперь в них содержится все, что потребуется компилятору для создания объектного файла.
  2. Ассемблирование — процесс превращения текста на языке C++ в текст на языке Ассемблера. Для компиляторов GNU используется синтаксис ассебмлера AT&T.
  3. Компилирование — процесс превращения текстов на языке Ассемблера в объектные файлы. Это файлы состоящие из кодов целевого процессора, но в которых еще не проставлены адреса объектов, которые находятся в других объектных файлах или библиотеках.
  4. Линковка — процесс объединения объектных файлов проекта и используемых библиотек в единую целевую сущность для целевой платформы. Это может быть исполняемая программа или библиотека статического или динамического типа.
Илон Маск рекомендует:  Что такое код globalpageunlock

Рассмотрим подробнее упомянутые выше стадии обработки текстовых файлов на языке C++.

Препроцессинг

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

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

На входе препроцессора мы имеем исходный файл с текстом на языке C++ включающим в себя элементы языка препроцессора.

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

Ассемблирование

Процесс ассемблирования с одной стороны достаточно прост для понимания и с другой стороны является наиболее сложным в реализации. По своей сути это процесс трансляции выражений одного языка в другой. Более конкретно, в данном случае, мы имеем на входе утилиты ассемблера файл с текстом на языке C++ (компиляционный лист), а на выходе мы получаем файл с текстом на языке Ассемблера. Язык Ассемблера это низкоуровневый язык который практически напрямую отображается на коды инструкций процессора целевой системы. Отличие только в том, что вместо числовых кодов инструкций используется англоязычная мнемоника и кроме непосредственно кодов инструкций присутствуют еще директивы описания сегментов и низкоуровневых данных, описываемых в терминологии байтов.

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

Компиляция

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

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

Вообще, разница между объявлением (declaration) и определением (definition) состоит в том, что объявление (declaration) говорит об имени сущности и описывает ее внешний вид — например, тип объекта или параметры функции, в то время как определение (definition) описывает внутреннее устройство сущности: класс памяти и начальное значение объекта, тело функции и пр.

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

Линковка

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

Средства сборки проекта

Традиционно, программа на языке C++ собирается средствами утилиты make исполняющей сценарий из файла Makefile. Сценарий сборки можно писать самостоятельно,
а можно создавать его автоматически с помощью всевозможных средств организации проекта. Среди наиболее известных средств организации проекта можно указать следующие.

  1. GNU Toolchain — Старейшая система сборки проектов известная еще по сочетанию команд configure-make-«make install».
  2. CMake — Кроссплатформенная система сборки, которая позволяет не только создать кроссплатформенный проект но и создать сценарий компиляции под любые известные среды разработки, для которых написаны соответствующие генераторы сценариев.
  3. QMake — Достаточно простая система сборки, специально реализованная для фреймворка Qt и широко используемая именно для сборки Qt-проектов. Может быть использована и просто для сборки проектов на языке C++. Имеет некоторые проблемы с выявлением сложных зависимостей метакомпиляции, специфической для Qt, поэтому, даже в проектах Qt, рекомендуется использование системы сборки CMake.

Современные версии QtCreator могут работать с проектами, которые используют как систему сборки QMake, так и систему сборки CMake.

Простой пример компиляции

Рассмотрим простейший проект «Hello world» на языке C++. Для его компиляции мы будет использовать консоль, в которой будем писать прямые команды компиляции. Это позволит нам максимально прочувствовать описанные выше этапы компиляции. Создадим файл с именем main.cpp и поместим в него следующий текст программы.

В представленом примере выполнена нумерация строк, чтобы упростить пояснения по коду. В реальном коде нумерации не должно быть, так как она не входит в синтаксическое описание конструкций языка C++.

В первой строке кода записана директива включения файла с именем iostream в текст проекта. Как уже говорилось, все строки, которые начинаются со знака решетки (#) интерпретируются в языках C/C++ как директивы препроцессора. В данном случае, препроцессор, обнаружив директиву включения файла в текст программы, директиву include, выполнит включение всех строк указанного в директиве файла в то место программы, где стоит инструкция include. В результате этого у нас получится большой компиляционный лист, в котором будут присутствовать множество символов объявленных (declaration) в указанном файле. Включаемые файлы, содержащие объявления (declaration) называют заголовочными файлами. На языке жаргона можно услышать термины «header-файлы» или «хидеры».

Чтобы увидеть результат препроцессинга можно воспользоваться опцией -E компилятора g++. По умолчанию, в этом случае, результат препроцессинга будет выведен в стандартный поток вывода. Чтобы можно было удобно рассмотреть его, следует перенаправить стандартный поток вывода в какой-нибудь текстовый файл. В представленном ниже примере это будет файл main.E.

В третьей строке программы описана функция main(). В контексте операционной системы, каждое приложение должно иметь точку входа. Такой точкой входа в операционных системах *nix является функция main(). Именно с нее начинается исполнение приложения после его загрузки в память вычислительной системы. Так как операционная система Windows имеет корни тесно переплетенные с историей *nix, и, фактически, является далеким проприентарным клоном *nix, то и для нее справедливо данное правило. Поэтому, если вы пишете приложение, то начинается оно всегда с функции main().

При вызове функции main(), операционная система передает в нее два параметра. Первый параметр — это количество параметров запуска приложения, а второй — строковый массив этих параметров. В нашем случае, мы их не используем.

В пятой строке мы обращаемся к предопределенному объекту cout из пространства имен std, который связан с потоком вывода приложения. Используя синтаксис операций, определенных для указанного объекта, мы передаем в него строку «Hello world» и символ возврата каретки и переноса строки.

В седьмой строке мы возвращаем код 0, как код возврата функции main(). В организации процессов в операционной системы, это число будет восприниматься как код возврата приложения.

Следующим шагом проведения эксперимента выполним останов компиляции файла main.cpp после этапа ассемблирования. Для этого воспользуемся ключом -S для компилятора g++. Здесь и далее, знак доллара ($) обозначает стандартное приглашение к вводу команды в консоли *nix. Писать знак доллара не требуется.

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

Для остановки компиляции после, собственно, компиляции следует воспользоваться ключом -c для компилятора g++.

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

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

Добавить комментарий Отменить ответ

Для отправки комментария вам необходимо авторизоваться.

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Компилятор

Компиля́тор — программа или техническое средство, выполняющее компиляцию [1] [2] [3] .

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

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

Содержание

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Интересные факты

На заре развития компьютеров первые компиляторы (трансляторы) называли «программирующими программами» [6] (так как в тот момент программой считался только машинный код, а «программирующая программа» была способна из человеческого текста сделать машинный код, то есть запрограммировать ЭВМ).

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL