Компиляция, сборка и выполнение программ
Результатом компиляции всех Delphi-проектов является исполняемый файл. Для компиляции исходных файлов, входящих в проект, используется команда Project/Compile главного меню интегрированной среды разработчика или комбинация клавиш Ctrl+F9. При этом выполняются следующие действия:
1) компилируются файлы с исходным текстом всех модулей, содержимое которых изменилось после последней компиляции. В результате для каждого файла с исходным текстом модуля создается файл с расширением *.Dcu. Если были внесены изменения в интерфейсную часть модуля, то перекомпилируется не только этот модуль, но и модули, использующие его (через директиву Uses);
2) после того как откомпилированы все модули, входящие в проект, Delphi компилирует файл проекта и создает *.Exe файл с именем, эквивалентным имени проекта.
При сборке проекта (в отличие от компиляции) компилируются все файлы, входящие в проект, вне зависимости от того, были в них внесены изменения после предыдущей компиляции или нет. Для сборки проекта используется команда Project/Build All главного меню интегрированной среды разработчика.
Для выполнения программы используется команда Run/Run главного меню интегрированной среды разработчика или клавиша F9. При вызове этой команды происходят те же действия, что и при вызове команды Project/Compile и Project/Build All, но после компиляции и сборки программа запускается на выполнение.
Установка параметров проекта
Существует два способа управления параметрами проекта. Можно установить параметры с помощью диалоговой панели Project Options, вызываемой с помощью команды Project/Options главного меню интегрированной среды разработчика, а можно воспользоваться директивами компилятора, расположенными в исходном тексте программы.
Диалоговая панель параметров проекта (рис. 17) состоит из нескольких страниц:
Forms – определяет главную форму, порядок создания остальных форм;
Application – задает название приложения, справочный файл, иконку;
Compiler – определяет параметры компилятора;
Linker – определяет параметры компоновщика;
Directories/Conditions – задает рабочие каталоги;
VersionInfo – установка параметров версии проекта;
Packages – позволяет определить, какие пакеты доступны для использования при разработке приложения, и прилинковать их при создании результирующего файла.
В проекте Delphi может быть несколько форм, но одна из форм является главной. Главная форма является исходной формой при запуске приложения и, как правило, первой отражается на экране. На странице Forms можно назначить любую из существующих в проекте форм главной. В списке Autocreate forms указываются названия форм, которые будут создаваться одновременно с главной формой. Формы могут создаваться и в процессе выполнения программы.
Для того чтобы задать название приложения, которое будет отображаться вместе с иконкой, когда окно будет минимизировано, необходимо выбрать параметр Title на странице Application. Здесь же можно задать имя файла, содержащего справочную систему для создаваемого приложения, и иконку, которая будет символизировать приложение.
На странице Compiler задаются параметры компилятора. Наиболее важным из них является использование или отмена использования отладочной информации – этот параметр сильно влияет на размер результирующего *.Exe-файла.
Назначение пунктов главного меню приводится в приложении 2 файла материалов.
Язык Object Pascal
Языком программирования Delphi является Object Pascal. В том, что касается основных программных конструкций, этот язык очень напоминает Pascal седьмой версии среды Borland Pascal. Под программными конструкциями следует понимать структуры, определяющие, в какой последовательности выполняются инструкции в программе. Примерами программных конструкций могут служить условные операторы If-Then-Else, операторы цикла Repeat-Until, а также механизмы вызова методов. Перенос в Delphi программ, написанных на языке Pascal, выполнить не всегда просто. Причина заключается в многочисленных изменениях, внесенных в язык, используемый в среде разработки приложений Borland Pascal.
Object Pascal является объектно-ориентированным языком программирования. Приложение Delphi состоит из объектов. Все элементы управления интерфейса программы (кнопки, списки, панели и т.д.) являются объектами. Объекты обеспечивают выполнение и стандартных, и специфических функций приложения.
Усовершенствованную модель объектного типа Turbo Pascal представляют собой классы Object Pascal. Классы Object Pascal имеют много общего с типом Object языка Turbo Pascal.
Класс – это определенный пользователем тип данных, который обладает внутренними данными и методами в форме процедур или функций и обычно описывает родовые признаки и способы поведения ряда похожих объектов. Экземпляр типа класс называется объектом. Объекты класса всегда распределяются в куче в отличие от экземпляров объектного типа. Предварительно определенные объекты, используемые в программе (такие как, например, компоненты Delphi), – это в действительности экземпляры классов.
В Object Pascal имеется также тип Object. До введения термина “класс” в языке Pascal существовала двусмысленность определения “объект”, который мог обозначать и тип, и переменную этого типа. В Object Pascal существует четкая граница: класс – это описание, объект – то, что создано в соответствии с этим описанием.
Типкласс– это структура данных, состоящая из полей, методов, свойств. Поля содержат данные определенного типа. Методы – это функции и процедуры, описанные внутри класса и предназначенные для операций над его полями. Свойства – это специальный механизм классов, регулирующий доступ к полям. Свойство описывает один или два метода, которые осуществляют некоторые действия над данными того же типа, что и свойство. Например, обычная кнопка в окне приложения обладает такими свойствами, как цвет, размеры, положение. Для экземпляра класса “кнопка” значения этих атрибутов задаются при помощи свойств – специальных переменных, определяемых ключевым словом Property. Цвет может задаваться свойством Color, размеры – свойствами Width и Height и т.д.
Так как свойство обеспечивает обмен данными с внешней средой, то для доступа к его значению используются специальные методы класса. Например:
Function GetColor : TSomeType;
Procedure SetColor (aNewValue : TSomeType);
Property AСolor : TSomeType Read GetColor Write SetColor;
В данном примере доступ к значению свойства AСolor осуществляется через вызовы методов GetColor и SetColor. К методам в явном виде не обращаются. Достаточно записать:
и компилятор оттранслирует эти операторы в вызовы методов.
Особым видом свойств являются события.События для среды Windows – это специфические сообщения о возникшей ситуации, которые перехватываются и обрабатываются Windows, чтобы обеспечить функциональные возможности интерфейса.
В Object Pascalсобытие – это свойство процедурного типа, предназначенное для создания пользовательской реакции на то или иное входное воздействие:
Property OnMyEvent : TMyEvent Read FOnMyEvent Write FOnMyEvent;
здесь FOnMyEvent – поле процедурного типа, содержащее адрес некоторого метода. Присвоить такому свойству значение – значит указать объекту адрес метода, который будет вызываться в момент наступления события. Такие методы называют обработчиками событий (обработчик события– фрагмент программы, который выполняется в ответ на определенное изменение в программе или в Windows).
Каждый новый класс в Delphi должен быть объявлен. Для этого используется зарезервированное слово Class. В отличие от других типов, тип Сlass можно объявлять только глобально. Объявление определяет функциональные возможности класса. Объявление классов в модуле производится в разделе объявления типов. Пример объявления класса и объекта в программе на Delphi:
Var Form1 : TForm1;
В объявлении типа определен новый класс – TForm1, наследуемый от класса TForm, содержащегося в библиотеке визуальных компонентов. На это указывает зарезервированное слово Class. Данный тип содержит указатели на компоненты, которые были помещены в форму: два компонента Label – объекты типа TLabel (иначе говоря, экземпляры класса TLabel) и два экземпляра класса TBitBtn. Для определения экземпляра нового класса объявлена переменная Form1.
Область видимости идентификатора компонента, объявленного в описании класса, простирается от его объявления до конца определения класса, а также распространяется на все потомки этого класса и на все блоки реализации методов класса. Область видимости идентификатора компонента зависит от атрибута видимости раздела, в котором объявлен этот идентификатор.
В объявлениях типов классов имеются разделы частных (private), общих (public), защищенных (protected) и опубликованных (published) объявлений.
В разделе частных объявлений размещаются поля данных и методы, недоступные за пределами модуля, содержащего объявление данного класса. Данные, описанные в этом разделе, могут обрабатываться только путем вызова методов внутри класса, а также внутри данного модуля.
Поля данных и методы, объявленные в разделе общих объявлений класса, доступны для всех процедур, программный код которых расположен в области видимости данного объекта. В разделе общих объявлений типа класс должны быть объявлены поля данных и методы, к которым будут иметь доступ методы объектов других модулей.
Поля, свойства и методы секции protected также доступны только внутри модуля с описываемым классом, но они доступны в классах, являющихся потомками данного класса, в том числе и в других модулях.
Все классы Object Pascal порождены от единственного родителя – класса TОbject. Этот класс не имеет полей и свойств, но включает в себя методы самого общего назначения, обеспечивающие весь жизненный цикл любых объектов – от их создания до уничтожения. Новый класс можно создать на основе этого базового класса.
В приведенном ниже тексте программы определяется новый тип класса, предназначенного для анализа данных, представляющих собой последовательность результатов измерений.
NumberOf Samples, NumberOfMaterials : Integer;
IsStandard, IsNoStandard : Boolean;
Function CountSamples : Integer;
Function CountMaterials : Integer;
Function Standard : Boolean;
По результатам серии экспериментов необходимо получить следующую информацию: число измерений, число определенных материалов в серии, какие результаты лежат в пределах допуска и какие вне его. Даны также названия испытываемых материалов. В качестве полей данных нового объекта определяются следующие переменные: два поля целочисленного типа; логическое поле; поле длинной строки для названия.
Для обеспечения доступа к данным пишется программный код, обрабатывающий эти данные. Код реализации этих методов помещается в implementation-секции модуля. В объявлении класса помещается только заголовок процедуры или функции. Процедура GetNames предназначена для определения названия материала. Для решения остальных задач описываются функции.
Принцип наследования приводит к созданию ветвящегося дерева классов, постепенно разрастающегося при перемещении от TObject к его потомкам. Каждый потомок дополняет возможности своего родителя новыми свойствами и передает их своим потомкам.
Для примера на рис. 18 показан небольшой фрагмент дерева Delphi. Класс TPersistent обогащает возможности своего родителя TObject: он умеет сохранять данные в файле и получать их из него, в результате это умеют делать и его потомки. Класс TComponent, в свою очередь, умеет взаимодействовать со средой разработчика и передает это умение своим потомкам. TControl не только способен работать с файлами и средой разработчика, но он уже умеет создавать и обслуживать видимые на экране изображения, а его потомок TWinControl может создавать Windows-окна и т.д.
В состав Delphi входит более 300 различных классов.
Статьи к прочтению:
- Компоненты sql server 2000
- Компьютеры с суперскалярной обработкой
ПРИКОЛЫ в СПОРТЕ, фейлы, курьезы, смешные моменты, компиляция
Похожие статьи:
- При выполнении этой программы на двухъядерном компьютере получается следующий результат. Основной поток запущен. Параллельно выполняемый цикл инициализации: 1.0537757 секунд Последовательно выполняемый цикл инициализации: 0.3457628 секунд…
- Выполнить компиляцию и запуск программы. Для этого необходимо: нажать на клавишуклавиатуры или выполнить команду Начать отладку элемента Отладка Стандартного меню. После нажатия на кнопку на…
Компиляция и сборка Android приложения (как это работает)
Дисклеймер: Я не 23 летний сеньор (мне 19 и до сеньора мне еще ой как далеко, года 4, поэтому супер статьи от меня не ждите.
Основа пути моего, разработчика как — обучение/изучение нового постоянное. Надеюсь, у вас тоже.
Я бы хотел подробно рассмотреть процесс компиляции и сборки Android приложения в конечный .apk. Да, при разработке очередного приложения какашкибезholoстилей эта информация вам нафиг не сдалась, но для общего развития будет полезна всем Android разработчикам.
- Напишите код
- Нажмите кнопочку Build & Run в вашей IDE
- Продолжайте быть Android разработчиком
В общих чертах процесс сборки приложения выглядит так:
Нас особенно интересует второй этап (компиляция и сборка ресурсов), так что, рассмотрим его более подробно (21 этап как никак):
Пожалуйста, не прокручивайте диаграмму из-за того, что вам лень вникать, она не сложная, к тому же переведенная. Это основа статьи.
(Оригинал здесь: developer.android.com/tools/building/index.html)
Что есть что на диаграмме:
1. Ресурсы приложения — это все xml ресурсы из папки res вашего проекта + некомпилируемые бинарные ресурсы, например, картинки из res/drawable или файлы из /res/raw, а так же файлы из /assets/
2. aapt — утилита, которая ищет в вашем проекте компилируемые ресурсы, такие как AndroidManifest.xml и xml файлы из res/ и компилирует их в бинарное представление, а изначально бинарные ресурсы, такие как картинки, и файлы из /res/raw и /assets не компилируются. Далее, эта утилита генерирует важнейший класс R.java для вашего приложения, благодаря которому вы можете обращаться к ресурсам из вашего кода без всяких заморочек с чтением файлов, как скажем с /assets.
Кстати, кроме компиляции xml ресурсов, aapt создает файл resources.arsc, который представляет собой таблицу для маппинга ресурсов во время выполнения приложение, туда входят все ресурсы из /res/, в том числе и /res/raw/, содержимое /assets не включается в таблицу.
Полезно знать: Утилита aapt находится в папке platform-tools вашего Android SDK. Если вам захотелось сделать реверс-инжиниринг скомпилированных ресурсов приложения, вы можете воспользоваться apk-tool (https://code.google.com/p/android-apktool/)
3. R.java — класс, генерируемый утилитой aapt для того, чтобы вы могли обращаться к ресурсам из папки res без явной работы с файловой системой через библиотеки ввода/вывода.
Если кто-то еще не знал — всякие R.string, R.menu и прочее — это статические вложенные классы, а в R.string.app_name, app_name — public static final int поле класса. Получается, что правило-принцип CamelCase, применяемый в Java, для них нарушен, должно то быть: R.String, R.Menu, а с константами — R.String.APP_NAME, айайай Google.
4. Исходный код приложения — это ваши (или украденные форкнутые с других проектов) .java файлы с кодом проекта из папки src, все просто.
5. Java интерфейсы — это не те, обычные интерфейсы (обычные входят в состав исходного кода приложения, предыдущий пункт), которые вы используете в вашем коде, это интерфейсы, сгенерированные утилитой aidl (следующий пункт содержит пояснение).
6. .aidl файлы — это интерфейсы, которые вы можете написать на Java с немного необычным синтаксисом (на самом деле, язык называется AIDL — Android Interface Defenition Language). Такие интерфейсы нужны для описания взаимодействия между различными процессами, например когда вам нужно, чтобы сервис (Service) вашего приложения работал не просто в отдельном потоке, а именно в отдельном процессе (у такого подхода есть как преимущества, например, раздельные квоты на память для процессов, так и недостатки — необходимость использования aidl), на Хабре есть статья, в которой раскрыта тема использования aidl http://habrahabr.ru/post/139432/).
7. aidl — утилита, которая транслирует ваши .aidl файлы в Java код, она находится в папке platform-tools вашего Android SDK.
8. Java компилятор — (наконец-то мы до него добрались!) это обычный javac из вашего JDK, которому дают на обработку исходный код приложения (4), R.java (3) и интерфейсы aidl, которые переведены в java код с помощью утилиты aidl
9. .class файлы — это «выхлоп» javac — байткод для JVM. Так как Dalvik VM не может интерпретировать java bytecode, а использует свой велосипед под название dex bytecode, то на этом компиляция проекта не заканчивается.
Разработчики Android выбрали регистровую архитектуру Dalvik VM, вместо привычной для JVM — стековой архитектуры из двух ключевых соображений:
1. Производительность регистровой ВМ выше (инфа 100%), особенно на процессорах с RISC-архитектурой, а это все ARM процессоры. Первые версии Dalviik VM даже не включали JIT (до Android 2.2), но давали терпимую производительность приложений, скажем я не испытывал особых проблем с HTC Desire на 2.1.
2. java bytecode транслируется в меньший по объему dex bytecode, что уменьшает размер скомпилированного приложения.
10. dex компилятор (а точнее транслятор) — он транслирует .class файлы в classes.dex (Java bytecode в Dalvik bytecode). Описание .dex вы можете прочитать здесь source.android.com/tech/dalvik/dex-format.html.
Сам компилятор находится в папке platform-tools вашего Android SDK, запускать его можно через dx.bat (для Windows), при этом будет задействован dx.jar из папки platform-tools/lib
11. Сторонние библиотеки и .class файлы — это все то, что вы подключаете в проект как библиотеку или включаете в Build Path. Так как в качестве основного ЯП для Android выбрана Java, вы можете без проблем использовать практически любые java библиотеки, они просто будут обработаны dex компилятором.
12. classes.dex — в данный файл dex компилятор записывает весь исполняемый код вашего проекта.
Да-да, все будет в одном файле, хотя в документации написано, что файлов .dex может быть несколько, но на практике, я не встречал, чтобы .apk содержал .dex файлы кроме classes.dex, может в комментариях меня поправят.
13. Скомпилированные ресурсы — xml ресурсы приложения, скомпилированные в бинарное представление.
14. Другие ресурсы — это реально другие ресурсы, которые не обрабатываются aapt — например файлы, которые вы зачем то хотите засунуть в .apk, так же туда попадают файлы из .jar`ов, которые добавлены в Build Path, но не являются компилируемыми.
15. apkbuilder — утилита, которой на вход подают скомпилированные ресурсы (2, 13), classes.dex (12) и другие ресурсы (14), а она собирает из этого наш вожделенный .apk файл. Утилита лежит в папке tools вашего Android SDK
16. Собранное приложение в файл .apk — это архив, содержащий скомпилированные и нескомпилированные ресурсы, classes.dex, resources.arsc, META-INF, AndroidManifest.xml и т.д.
Формат .apk это надстройка над .jar, а .jar — надстройка над zip, так что, .apk вы можете открыть zip архиватором, такая вот матрешка.
17. jarsigner — это Oracle`вская утилита для подписания .jar архивов. Он подписывает ваш .apk выбранным вами ключом.
Но не надо думать, что ваш .apk теперь защищен от декомпиляции, ничего подобного. В .apk только добавляется папка META-INF, в которой вы можете обнаружить публичную часть release (или debug) сертификата — файл CERT.RSA, а так же файл CERT.SF — который содержит контрольные суммы для всех файлов внутри .apk, кроме тех, что в папке META-INF
Пример содержания CERT.SF:
Signature-Version: 1.0
SHA1-Digest-Manifest-Main-Attributes: O1qITQssq6nv0FUt+eR1aLnqk5w=
Created-By: 1.6.0_43 (Apple Inc.)
SHA1-Digest-Manifest: OwzyFA/Qjd+5X1ZwaJQSxFgdciU=
Name: res/drawable-mdpi-v4/ic_premium_pin.png
SHA1-Digest: 8ksQB8osCHTnMlpL6Ho/GDc719Q=
Name: res/drawable/round_bottom_white.xml
SHA1-Digest: rQelve4dQmwCfkVlYZ2+9j5aW5w=
Еще немного важной информации о подписи приложения:
В Android уникальным идентификатором приложения является имя пакета приложения, например ru.habrahabr.android. Но чтобы злоумышленник не смог подменить ваше установленное приложение на свое с таким же пакетом, Android выполняет проверку, на то чтобы новый .apk был подписан тем же сертификатом, что и уже установленный.
Кроме того, если у вас есть выложенное приложение в Google Play, вы не сможете обновить его, если новая версия подписана другим сертификатом! Так что советую забекапить сертификат, а так же не забыть пароль к нему. Иначе вы не сможете обновлять свои приложения.
18. Debug или Release хранилище ключей — хранилище из которого jarsigner возьмет ключи для подписи приложения. Если вы собираете Debug версию (для запуска на эмуляторе или подключенном устройстве), то .apk подписывается debug ключем, в Windows он находится в папке пользователя/.android/.
Кстати, приложение подписанное debug ключом нельзя установить без подключенного отладчика. Так что, если хотите отправить .apk друзьям на тестирование — подпишите его Release ключем
19. Подписанный .apk — .apk файл вашего приложения, в который добавлена информация о подписи (см. пункт 17).
20. zipalign — утилита, которая оптимизирует ваш .apk для более быстрого запуска и меньшего потребления ОЗУ при работе приложения. Она выравнивает содержимое .apk для более эффективной разархивации (подробнее здесь: http://developer.android.com/tools/help/zipalign.html).
Важное замечание: приложение надо сначала подписать, а затем применить zipalign, т.к. подпись — это добавление папки META-INF в архив, а это изменение архива, следовательно нарушение его оптимизации. То есть, если вы сначала примените zipalign, а потом измените архив — смысла в zipalign не будет. Насчет нарушения контрольных сумм, которые рассчитала утилита jarsign, бояться не стоит, т.к. zipalign делает оптимизации по выравниванию данных в архиве, все это происходит на уровне zip, сами данные не изменяются.
Хозяйке на заметку: во время сборки debug версии проекта zipalign не вызывается, скорее всего, чтобы вы не ждали выполнения еще и этой операции (спасибо и на этом).
21. Подписанный (и, возможно, выравненный) .apk — вожделенный .apk вашего приложения. Конец.
Я думаю, что теперь понятно, почему сборка и запуск Android приложения происходит так долго 🙂 Так что, советую поставить SSD, ну и процессор побыстрее и сэкономить себе нервы и время.
Немного полезного оффтопа:
1. Всегда используйте обфускацию вашего кода. Декомпилировать java приложение очень легко. Даже несмотря на то, что в .apk используется dex bytecode — его сначала транслируют обратно в java bytecode, а затем к нему применят обычные java декомпиляторы. Потратьте пару часов на выбор и настройку обфускатора, иначе можете просто выложить исходники проекта на гитхаб, секономите людям время, а может еще и пулл реквесты получите 🙂
2. Вы знали, что Android инстанциирует для каждого запущенного приложения отдельный экземпляр Dalvik VM? Это сделано для того, чтобы исключить ситуации, когда одно приложение валит Dalvik VM, а за ним тянет все другие запущенные приложения. Яркий пример подобного вмешательства — Facebook, они через reflection изменяют параметры Dalvik VM (не стоит так делать). Если бы Android использовал один инстанс Dalvik — это изменение затронуло бы все запущенные приложения.
3. Dalvik VM не является JVM, т.к. во-первых он не понимает java bytecode, а во-вторых не реализует спецификации для JVM, т.к. использует свой байт код. Так что, советую называть Dalvik VM именно Dalvik VM.
Надеюсь, вы не зря потратили свое время и узнали что-то новое.
Чем компиляция отличается от сборки
Не могу понять в чём разница в Start Debugging (Start Without Debugging) и Build (Rebuild), кроме того, что в первом случае проект запускается.
такая же разница, как и между «собрать машину» и «поехать на машине». Настолько плохо с английским.
Цитата MDmitry @ 16.03.11, 04:05
Для чего нужен Build (Rebuild)?
Для того, чтобы собрать (пересобрать) проект.
Цитата MDmitry @ 16.03.11, 04:05
Нужно ли каждый раз Build (Rebuild) перед Start Debugging (Start Without Debugging)
Ребилд — радикальная штука, и каждый раз его делать точно не нужно, достаточно просто build. Кроме того, при попытке стартануть (с дебагом или без) модифицированного но не собранного проекта будет выдано предупреждение (если оно не отключено), что мол «у тебя тут не собраны изменения — собрать/забить/отмена?». Короче, лучше делай.
Цитата MDmitry @ 16.03.11, 04:05
так как удаляю полностью папку с библиотекой из проекта, без которой он запуститься в принципе не может, если перед Start Debugging не собрать проект, то он и не замечает отсутствия целой библиотеки.
фигасе Ну надо — так надо, чо теперь. Ты удаляешь проект библиотеки из солюшена и запускаешь приложение без сборки? Результат правильный: приложение собрано корректно, а то, что ты «удалил» библиотеку на него никак не повлияло, потому что физически бинарник остался на месте и непересобранное приложение до него имеет доступ. Многословно и непонятно? Короче так: фактически твои действия идентичны копированию всех собранных бинарников в какое-то место (в другую папку) и удалению проекта библиотеки/удалению всех исходников библиотеки/удалению студии/сносу винды/прилёту инопланетян — бинарники остались в неизменном согласованном работоспособном состоянии. Чо б им не запуститься.
Сообщ. #4 , 16.03.11, 10:20
Unregistered
Цитата MDmitry @ 16.03.11, 04:05
1. Не могу понять в чём разница в Start Debugging (Start Without Debugging) и Build (Rebuild), кроме того, что в первом случае проект запускается.
Start Debugging это сборка и потом запуск того что собралось в режиме отладки. IDE запустит собранный процесс в режиме отладки и в случае сборки его с Debug Information может использовать такие средства отладки как например breakpoint установленный в исходном коде, в окне IDE.
Start Without Debugging Это просто сборка и запуск того что получилось. Тот же пример, в выставленых breakpoint ах, приложение не остановится.
Build сборка на основании эвристики IDE, того, что надо собирать, и того что уже собрано. Если что то происходит с файлами проекта без ведома IDE, то данная эвристика может оказатся не правильной. Возможно просто быть не верной в той или иной ситуации.
Rebuild полная сборка
Цитата MDmitry @ 16.03.11, 04:05
2. Для чего нужен Build (Rebuild)?
собрать целевой конфигурейшен тип проекта, например экзешник
Цитата MDmitry @ 16.03.11, 04:05
3. Нужно ли каждый раз Build (Rebuild) перед Start Debugging (Start Without Debugging),
вопрос не корректный, это разные возможности. Если вы поймете, что делает каждая, то этого вопроса не должно стоять.
Компилятор
Компилятор — это программа, которая переводит текст, написанный на языке программирования, в машинные коды. С помощью компиляторов компьютеры могут понимать разные языки программирования, в том числе высокоуровневые, то есть близкие к человеку и далекие от «железа».
«IT-специалист с нуля» наш лучший курс для старта в IT
Процесс работы компилятора с кодом называется компиляцией, или сборкой. По сути, компилятор — комплексный «переводчик», который собирает, или компилирует, программу в исполняемый файл. Исполняемый файл — это набор инструкций для компьютера, который тот понимает и может выполнить.
Языки программирования, для перевода которых используются компиляторы, называются компилируемыми.
Для чего нужен компилятор
Изначально компьютер не понимает смысл написанного на любом языке программирования. Язык компьютера — машинные коды, нули и единицы, в которых зашифрована информация и команды. Писать на машинных кодах программы практически невозможно: даже простейшее действие будет отнимать много часов работы программиста. Поэтому появились языки программирования, более понятные для людей, и специальные программы, которые переводят эти языки в машинные коды. Эти программы и есть компиляторы.
Без компилятора любой код на компилируемом языке программирования будет для компьютера просто текстом — он не распознает команды и не сможет их выполнить. Поэтому компилятор нужен, чтобы программы могли выполняться. Без него ничего не будет работать.
Еще одна задача компилятора — собрать все модули, например подключенные библиотеки, в единый файл. Нужно, чтобы исполняемый файл содержал в себе все необходимое для нормальной работы программы и полного выполнения инструкций.
Профессия / 8 месяцев
IT-специалист с нуля
Попробуйте 9 профессий за 2 месяца и выберите подходящую вам
Компилятор и интерпретатор: в чем разница
Компиляция — не единственный подход к «переводу» человекопонятного языка программирования на машинный. Еще есть интерпретаторы и байт-код, но там технологии совсем другие.
Интерпретатор — это тоже программа, которая «переводит» текст на высокоуровневом языке программирования, но делает это иначе. Она не собирает весь код в один исполняемый файл для последующего запуска, а исполняет код сразу, построчно. Это чуть медленнее, но иногда удобнее. Языки, использующие интерпретаторы, называются интерпретируемыми.
Байт-код — «промежуточное звено» между подходами компиляции и интерпретации. Программа преобразуется в особый код, который запускается под специальной виртуальной машиной. Языков, которые работают так, относительно немного, самый известный и яркий пример — Java.
В каких языках используются компиляторы
Среди популярных сегодня языков компилируемыми являются Swift и Go, а также C / C++ и Objective-C. Другие примеры — Visual Basic, Haskell, Pascal / Delphi, Rust, а также Lisp, Prolog и прочие менее известные языки. Разумеется, компилируемым является и язык ассемблера — очень низкоуровневый и написанный напрямую на машинных кодах.
Отдельно можно выделить языки, которые трансформируются в байт-код — это тоже своего рода компиляция. К ним относятся Java, Scala и Kotlin, а также C# и языки платформы .NET.
Курс для новичков «IT-специалист
с нуля» – разберемся, какая профессия вам подходит, и поможем вам ее освоить
На каких языках пишут компиляторы
Другие языки. Писать компилятор на машинном коде тяжело и долго, порой практически невозможно. Поэтому их пишут на уже существующих языках: получается, что большинство языков написано на других.
Например, один из компиляторов языка Go частично написан на C++, самый первый компилятор C++ — на ассемблере, а уже ассемблер — на машинных кодах.
Тот же язык. Написать компилятор для языка программирования можно на других версиях того же языка — такой подход разрешен и активно используется в разработке. Это нужно, чтобы компиляторы были более гибкими и «умными» и могли поддерживать больше возможностей, — ассемблер довольно примитивен и не решает всех задач.
Выглядит это так:
- первый, более простой компилятор пишется на ассемблере;
- второй пишется уже на нужном языке и компилируется первым компилятором;
- переведенный в машинные коды второй компилятор компилирует свои же исходники — получается более новая и мощная версия его же.
Например, большинство современных компиляторов для C / C++ написано на C / C++. Такие компиляторы называют самокомпилируемыми.
Почему у одного языка может быть несколько компиляторов
У большинства языков программирования несколько компиляторов. Их еще называют реализациями. Изначальную реализацию пишет создатель языка, потом со временем появляются альтернативные. Зачем это делается? Цели могут быть разными:
- написать более современный и функциональный компилятор, обновить язык;
- оптимизировать язык и сделать его эффективнее;
- создать свободную реализацию, которую сможет дополнять сообщество;
- исправить ошибки, которые есть в существующих реализациях;
- перенести язык на другую платформу, и так далее.
Подходы к оптимизации, портированию и выполнению других целей у всех групп разработчиков свои. Поэтому разные компиляторы одного и того же языка могут различаться скоростью, особенностями архитектуры, назначением и другими параметрами. Синтаксис языка при этом остается таким же, но есть особые ситуации, когда одна и та же строчка может выполняться по-разному в зависимости от компилятора.
Какими бывают компиляторы
Компиляторы очень многообразны. Есть такие, которые имеют узкую специализацию, например запускаются только под процессоры определенного семейства и оптимизированы под них. Есть и более широкие — так называемые кросс-компиляторы, которые могут поддерживать несколько операционных систем.
Один компилятор может «знать» несколько языков программирования. Яркий пример такого решения — GCC, или GNU Compiler Collection, кросс-компилятор для нескольких операционных систем и языков, полностью бесплатный и свободный. На нем написано программное обеспечение GNU.
Существуют и так называемые компиляторы компиляторов. Они генерируют компиляторы для языка на основе его формального описания.
Курс для новичков «IT-специалист
с нуля» – разберемся, какая профессия вам подходит, и поможем вам ее освоить
Как устроены и работают компиляторы
Простыми словами, они «читают» пришедшую к ним на вход программу и переводят ее команды в соответствующие им наборы машинных кодов. Детали уже сложнее и различаются в зависимости от реализации. Например, есть модульные гибкие компиляторы, написанные на высокоуровневых языках, есть отладочные компиляторы, способные устранять часть синтаксических ошибок, и так далее.
Сама компиляция может быть:
- построчной — в машинный код по очереди переводится каждая строка, что похоже на интерпретацию, но отличается технически;
- пакетной — код разбивается на блоки, или пакеты, и компилируется поблочно;
- условной — особенности компиляции зависят от условий, которые прописаны в исходном коде компилируемой программы.
Сначала компилятор разбирает, что написано, потом анализирует команды, а потом генерирует машинные коды. Он не запускает программу, запуск — это отдельное действие.
Преимущества компилируемых языков
- Компилируемые языки обычно быстрее, чем интерпретируемые, и их легче оптимизировать.
- Итоговый размер кода у компилируемых языков, как правило, меньше, чем у интерпретируемых.
- В компилируемых языках намного шире возможность контролировать аппаратные ресурсы. Это не значит, что они все низкоуровневые, но обратное — верно: практически все низкоуровневые языки — компилируемые.
- Когда процессоры становятся мощнее, именно компилируемые языки могут в должной мере задействовать их преимущества.
- Код после компилятора лучше оптимизируется под конкретные устройства, архитектуру «железа», эффективно задействует память и не тратит лишних ресурсов.
- Компилируемые языки обычно мощные и высокопроизводительные, поэтому на них пишут игры и другие серьезно нагруженные приложения.
Недостатки компилируемых языков
- В отличие от интерпретируемых языков, компилируемые не выполняют код сразу — его сначала нужно собрать, а это лишний шаг и лишнее время.
- Код сложнее в отладке: приходится заново компилировать его при каждом, даже небольшом изменении. Сам процесс поиска и устранения ошибок бывает довольно неочевидным.
- Машинный код жестко связан с архитектурой платформы и различается в зависимости от системы. Поэтому компилируемые языки — по умолчанию не кроссплатформенные. Для переноса языка на другую операционную систему понадобится писать новый компилятор. Правда, есть исключения в виде универсальных кросс-компиляторов, работающих под разными платформами, но они подходят не для всего.
- Для новичков проблема еще и в том, что компилируемые языки часто сложнее, чем интерпретируемые. Изучать их с нуля может быть тяжело, хотя и тут есть исключения.
Как пользоваться компилятором
Начинающий разработчик редко взаимодействует с компилятором напрямую. Он скачивает язык программирования, в том числе его компилятор, а потом работает в редакторе кода или IDE. Среда разработки сама запускает компилятор каждый раз, когда пользователь кликает на кнопку сборки или выполнения программы. Для этого его не нужно вызывать вручную. Иногда среда может сама включать в себя несколько компиляторов и выбирать подходящий в каждом случае.
Поэтому трогать компилятор на ранних этапах не имеет смысла — просто стоит помнить, что он есть, чтобы лучше разбираться в происходящем. Но он может пригодиться, если вы захотите скомпилировать что-то без среды разработки, например прямо в командной строке. Тогда его придется вызвать с помощью специальной команды — она своя для каждого решения.
У любого ПО есть документация, так что, если вы хотите узнать больше о компиляторе, которым пользуетесь, можете прочитать ее.
Узнайте больше об устройстве и работе языков программирования на курсах — получите новую профессию и станьте востребованным IT-специалистом.
IT-специалист с нуля
Наш лучший курс для старта в IT. За 2 месяца вы пробуете себя в девяти разных профессиях: мобильной и веб-разработке, тестировании, аналитике и даже Data Science — выберите подходящую и сразу освойте ее.
Статьи по теме:
- Функциональные языки программирования
- Objective-C
- Синтаксис