Теорию компиляции приложений на C/C++

Исходный материал:

  • исходные тексты программы.
  • зависимости, как стандартная библиотека, так и внешние библиотеки.

На низком уровне:

  1. Для каждого c/cpp-файла необходимо создать объектный файл, в котором будет содержаться бинарный код, соотвествующий исходному коду. Т.е. выполнить шаг компиляции.
  2. Необходимо все созданные бинарные файлы объединить в один исполняемый файл. Помимо созданных бинарных файлов в исполняемый файл могут быть также включены и статически скомпилированные библиотеки. Это шаг линковки.

Для решения этих задач достаточно только комплиятора.

Однако это ещё не всё. Т.к. компилируемый код зачастую зависит от внешних библиотек.

  • Библиотека присутсвует или отсуствует.
  • Какие параметры были использованы при сборке библиотеки: т.е. есть ли в уже установленной библиотеке необходимые функции.

Здесь необходимы инструменты, которые помогут разработчику (или администратору) убедиться, что все зависимости присутствуют и имеют “правильную” конфигурацию. Такие инструменты называются системами сборки. Они, собственно контролируют весь процесс:

  • Проверку, а возможно и установку, зависимостей.
  • Выполнение всех шагов комплияции вашего приложения.
  • Установка / удаление приложения из системы.

Система сборки с первого курса - Visual Studio. У неё есть ещё инструменты командного интерфейса, которые позволяют собирать “решения”. Понятно, что этого инструмента под GNU/Linux нет.

Наикратчайший обзор систем сборки

Make

Можно сказать, что make - система шаблонного исполнения команд. Вы определяете шаблон для перевода c-файла в объектный файл: для каждого .c-файла должен быть создан o-файл. При этом путь создания файла - вызов последовательности команд, может быть просто одной команды.

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

Получается транзитивная зависимость:

  • Для создания приложения необходимы объектные файлы
  • Для создания объектных файлов необходимы исходные

И мы знаем как одни получить из других.

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

К сожалению простое использование Make не позволяет решить следующие проблемы:

  • В разных дистрибутивах пути к заголовочным файлам могут отличаться.
  • Одинаковые по сути библиотеки могут быть названы по-разному.
  • В них нельзя сделать опции “включить функциональность” или “выключить её”.

Make - низкоуровневый инструмент.

GNU Autotools

Задача данного проекта - предоставить возможность быстрой генерации Make-файлов (Makefile), при этом решить вопрос с проверкой зависимостей в целевой системе.

  1. Разработчик формулирует зависимости в формате autotools.
  2. Разработчик формулирует включаемые / отключаемые функции в формате autotools.
  3. Разработчик описывает наборы исходных кодов своего приложения относительно функций.
  4. Пользователь запускает autotools, чтобы создать Make-файл, удовлетворяющий его потребностям.

CMake

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

Компиляция с помощью Automake на примере curl

  1. Необходимо получить исходные коды приложения.

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

  1. Необходимо поставить компилятор c++, а также инструменты для сборки (Make). В Debian-подобных дистрибутивах есть мета-пакет, который включает в себя большинство базовых инструментов, которые скорее всего потребуются для сборки приложения на С++. Пакет называется build-essential.

  2. Запускаем скрипт buildconf
  3. Запускаем скрипт configure
  4. Запускаем сборку make
  5. Устанавливаем приложение с помщью make install

Куда было поставлено приложение?

У системы сборки Automake есть возможность указать “префикс”, относительно которого и будет происходить установка. Т.е. бинарные файлы пойдут по пути “префикс”/bin, библиотеки “префикс”/lib и так далее.

По умолчанию этот префикс равен /usr/local, это позволяет не смешивать бинарные файлы, которые вы поставили через систему управления пакетов и бинарные файлы, которые вы самостоятельно скомплиировали.

Что такое .so-файл?

so = аббревиатура от Shared Object, т.е. это библиотека, которая может быть исопльзована несколькими исполнямыми файлами. Слышали про dll?

ldconfig позволяет обновить кеш библиотек, которые установлены в системе.

Задача

Поставить приложение fim, которое позволит просматривать изображения прямо в терминале, из исходных кодов.

FBI Improved.

  1. Получить исходные коды.
  2. Поставить зависимости
  3. Запустить компиляцию