- Основы компиляции программ из исходного кода в Linux
- Типичный пример
- Файлы INSTALL или README
- Установка программы с GitHub
- Autogen.sh
- Решение проблем
- Отсутствующие библиотеки
- Заключение
- GNU Make: управляйте процессом сборки своего программного обеспечения
- Что же должно случиться?
- Отладка Make-файлов
- Золотые правила разработки Make-файлов
- Различные полезные параметры утилиты make
- Внутри Make-файла
Основы компиляции программ из исходного кода в Linux
Оригинал: Basics Of Compiling Software From Source Code In Linux
Автор: LinuxAndUbuntu
Дата публикации: 16 мая 2018 года
Перевод: А. Кривошей
Дата перевода: июнь 2018 г.
Время от времени вам может понадобиться скомпилировать программу из исходного кода. Это включает компиляцию кода C или C++ во что-то, что мы можем запустить в Linux. В зависимости от программного обеспечения, которое вы хотите скомпилировать, часто делать это необязательно, так как ваш дистрибутив, скорее всего, уже будет иметь двоичный пакет программы в репозиториях программного обеспечения. Фактически, вы должны выбрать бинарные пакеты или компиляцию из исходного кода. Однако, если когда-либо вам нужно будет скомпилировать исходный код, это руководство даст вам некоторые основные знания данного процесса.
Типичный пример
Возьмем программу, написанную на C или C++. Загрузка исходного кода часто связана с загрузкой и распаковкой пакета или клонированием репозитория git. Типичным является выполнение этих трех команд:
Первая команда запускает скрипт configure, который анализирует библиотеки, установленные в вашей системе. Если требуемая для компиляции библиотека не установлена, он сообщит об этом, и вам нужно будет установить ее. Вам понадобится не только библиотека, но и файлы разработчика. Файлы с исходным кодом используют функции, имеющиеся в этих библиотеках.
После выполнения команды configure у вас должен быть создан файл Makefile. При запуске make, эта утилита будет читать Makefile в текущем каталоге и запустит компилятор (gcc для C или g ++ для C++) для компиляции программного обеспечения.
Третья команда не является строго необходимой, но рекомендуется для обеспечения общесистемного доступа к вашей программе, чтобы запускать исполняемый файл в терминале из любого места. Эта команда говорит «make» запустить инструкции по установке программы в систему.
Файлы INSTALL или README
Могут иметься дополнительные инструкции, которые должны быть выполнены до начала компиляции. Чтение этого файла (как правило, INSTALL) также поможет узнать, какие библиотеки разработчиков, возможно, потребуется установить в первую очередь. Такие пакеты будут содержать суффикс «-dev», чтобы показать, что они относятся к разработке и должны быть установлены для компиляции. Сценарий configure также может потребовать дополнительных параметров. README содержат любую другую информацию.
Вы даже можете обнаружить, что ни одна из трех команд не запускается. Вместо этого может использоваться другой вариант make, например qmake (для проектов Qt) или cmake.
Установка программы с GitHub
Начнем с установки текстового редактора wxMEdit, найденного на GitHub. Здесь я демонстрирую, как установить программу путем компиляции из исходного кода. Это типичный пример. Если вы посетите репозиторий GitHub, вы увидите, что файл readme содержит сведения о приложении. Никаких инструкций по компиляции нет, поэтому применяется стандартная последовательность с одной разницей: autogen.sh.
Сначала мы переходим в каталог, где хотим хранить репозиторий, и клонируем его:
Autogen.sh
Если вы найдете этот файл в исходном коде, вы должны запустить его перед “./configure”, так как он выполнит задачи, которые позволят вам успешно скомпилировать программное обеспечение. Если он отработал успешно, вы можете запустить “./configure”, “make”, а затем «sudo make install» и это все, что вам нужно запустить (в данном случае ничего больше).
В выводе make не должно быть ошибок.
Решение проблем
Если вы делаете это регулярно, вы должны столкнуться с определенными проблемами при компиляции из исходного кода.
Отсутствующие библиотеки
Помните, недостаточно установленных бинарных библиотек; также должны быть установлены исходные файлы или заголовки для разработчиков . Сценарий configure вместе с документацией обычно предупреждает вас о любых библиотеках (заголовках), которые необходимо установить для успешной компиляции. Убедитесь, что они установлены в вашей системе.
Заключение
Компиляция программного обеспечения может быть довольно простой или довольно болезненной. К счастью, многие дистрибутивы Linux предоставляют двоичные пакеты, готовые к установке, поэтому компиляция из исходного кода обычно не требуется. Лучше придерживаться бинарных пакетов, предоставляемых репозиториями, если они доступны.
Другие статьи о компиляции программ из исходного кода на нашем сайте:
Источник
GNU Make: управляйте процессом сборки своего программного обеспечения
Оригинал: GNU Make: Manage Your Software Builds
Автор: Mihalis Tsoukalos
Дата публикации: 14 декабря 2016 г.
Перевод: А.Панин
Дата перевода: 30 января 2017 г.
Компилируете программное обеспечение из исходного кода? Если это так, вам просто необходимо разобраться с Make-файлами.
Для чего это нужно?
- Вы сэкономите время, автоматизировав процесс сборки своих программных проектов с помощью Make.
- После создания корректного Make-файла для своего программного проекта, вы едва ли сможете допустить ошибки в процессе его сборки.
Make является мощной системой для автоматизации процесса сборки программного обеспечения, разработанной Стюартом Фельдманом из Bell Labs в апреле 1976 года. GNU Make является стандартной реализацией Make, используемой в Linux и Mac OS X с множеством улучшений, которая, в том числе, необходима для компиляции ядра Linux. Ее основной задачей является автоматическое выявление модифицированных файлов исходного кода сложных приложений и исполнение команд, направленных на их повторную компиляцию.
Для конфигурации make используются так называемые Make-файлы, которые позволяют сохранить группы команд для их последующего исполнения. Давайте рассмотрим содержимое Make-файла более подробно. Но перед этим вы должны принять к сведению тот факт, что GNU Make трактует отступы различных форматах по-разному, то есть, в представлении данного инструмента символ табуляции отличается от 4 или 8 последовательных символов пробела, следовательно, вам придется отнестись к форматированию рассматриваемых файлов с особым вниманием. Это особенно важно, так как каждая строка Make-файла с новой командой должна начинаться с символа табуляции.
Make-файлы могут управлять процессом компиляции программного обеспечения благодаря наличию зависимостей, целей и правил. Правила сообщают GNU Make о том, когда, почему и как нужно исполнять заданные последовательности команд для генерации результирующих файлов на основе файлов исходного кода. Целями являются файлы, которые должны генерироваться с участием GNU Make, причем их имена располагаются слева от символов двоеточий в описаниях правил. Чаще всего каждое из правил имеет по одной цели; однако, в рамках одного правила допускается использование сразу нескольких целей. Зависимости располагаются справа от символов двоеточий в описаниях правил и указывают на то, какие файлы или другие цели могут инициировать исполнение команд, описанных в рамках правила, по причине модификаций.
Я создал простой пример проекта, состоящий из четырех файлов исходного кода на языке C++ (вы можете загрузить исходный код проекта по ссылке www.linuxvoice.com/make23.tar.gz ). Этот архив содержит исходный код всех примеров, которые будут рассматриваться в данной статье. Файлы первого проекта расположены в директории simple . А это содержимое Make-файла этого проекта:
Впоследствии вы можете переместиться в данную директорию и просто выполнить в ней команду make .
Что же должно случиться?
Теперь вы готовы к исполнению команды make . В случае исполнения команды make program вы должны увидеть аналогичный вывод:
Приведенный в конце вывод утилиты ls позволяет убедиться в том, что все работает в точности так, как ожидалось и был получен желаемый результат.
В случае исполнения команды make clean , позволяющей удалить сгенерированные файлы, должен быть получен аналогичный вывод:
Вам не стоит беспокоиться по поводу сообщений об ошибках — они выводятся лишь потому, что некоторые из указанных файлов не были сгенерированы и в данный момент отсутствуют.
Реализация функции main() находится в файле исходного кода file1.cpp ; исходя из этого, последними компилируемыми файлами должны быть файлы file1.cpp и file1.h . Рассматриваемый проект является настолько простым, что каждый файл с расширением .cpp , за исключением файла file1.cpp , содержит реализацию лишь одного класса, описанного в рамках соответствующего файла с расширением .h , которая используется в рамках файла file1.cpp . Это обстоятельство обуславливает наличие зависимостей, которые описываются в рамках Make-файла.
Важная информация: утилита Make не исследует содержимое файлов проекта для принятия решения о том, стоит ли осуществлять их повторную компиляцию — она всего лишь проверяет метки времени модификации этих файлов.
Страница руководства утилиты make является источником полезной информации
Отладка Make-файлов
Make-файл может содержать синтаксические или логические ошибки, препятствующие его корректному функционированию. Наиболее полезным в плане отладки Make-файлов параметром утилиты make является параметр -n , который позволяет утилите просто выводить предназначенные для исполнения команды, но не исполнять их. Еще одним полезным параметром является параметр -d , который позволяет утилите выводить большой объем отладочной информации в процессе обычной обработки файла (хотя эта информация и может показаться интересной, она не всегда является полезной).
Последним полезным параметром для отладки Make-файлов является параметр -p , который позволяет утилите make выводить содержимое базы данных, а именно, все правила и значения переменных, извлеченные из Make-файла, перед выполнением необходимых пользователю действий. Если вы хотите получить содержимое базы данных без обработки каких-либо правил и файлов, вам придется воспользоваться следующей командой:
Это наглядная иллюстрация процесса обработки Make-файла, благодаря которой изящность технического решения, положенного в основу утилиты make, становится вполне очевидной
Золотые правила разработки Make-файлов
При разработке нового Make-файла в первую очередь следует описать все макросы (переменные), которые должны содержать полные пути ко всем используемым бинарным файлам системных команд. Это объясняется тем, что вы должны четко знать, какие команды исполняются в процессе сборки проекта, а не полагаться на наличие путей к директориям с необходимыми бинарными файлами системных команд в значении переменной окружения PATH .
Лучше всего начать работу с создания небольшого корректно работающего Make-файла и постепенно добавлять в него новые правила и зависимости. После добавления каждой инструкции вы должны тестировать корректность работы Make-файла, а не продолжать его модификацию. Таким образом вы будете точно знать, какая модификация Make-файла повлекла за собой появление ошибки. Пожалуйста помните о том, что команды из состава правила будут исполняться лишь при модификации целевых файлов, а не всех файлов с исходным кодом проекта.
Не пытайтесь использовать утилиту GNU Make в рамках крупного проекта, если вы все еще изучаете ее возможности; попробуйте внедрить ее в проекты меньшего масштаба перед тем, как начинать работу с более сложными проектами. И наконец, уясните, что переменные полезны и могут существенно сэкономить ваше время, поэтому вам определенно стоит использовать их всегда, когда это возможно.
А это пример практического использования сложного Make-файла в рамках программного проекта на языке C
Различные полезные параметры утилиты make
Если вам понадобится использовать Make-файл с именем, отличающимся от makefile или Makefile , вы можете воспользоваться параметром -f , передав после него имя этого файла. Параметры —file=ИМЯ_ФАЙЛА и —makefile=ИМЯ_ФАЙЛА полностью эквивалентны параметру -f . Параметр -k сообщает утилите make о необходимости осуществления сборки проекта так долго, как это возможно вне зависимости от обнаруженных ошибок. Параметр -t позволяет изменить метки времени модификации файлов вместо выполнения команд для сборки проекта; данный режим работы предназначен для симуляции полной пересборки проекта, что соответствующим образом отразится на результате последующего запуска утилиты make . Параметр —trace позволяет получить информацию о том, почему заданная цель требует пересборки проекта и какие команды будут выполнены в ходе этой операции. Параметр —trace также может использоваться для отладки файлов GNU Make.
Вы можете без каких-либо сложностей прочитать или изменить значение существующей переменной окружения, объявив ее в рамках своего Make-файла. Если вы захотите отключить данный механизм, вы можете просто вызвать утилиту make , передав ей параметр -e .
Пример вывода утилиты GNU Make с параметрами -n, -p и -d, которые используются главным образом для целей отладки Make-файлов
Внутри Make-файла
В первой строке рассматриваемого Make-файла описывается переменная RM , значением которой является полный путь к бинарному файлу утилиты rm , которая используется для удаления файлов. Для того, чтобы получить значение переменной RM и использовать его в рамках вашего Make-файла, вам придется использовать нотацию $(RM) . Мы поговорим о переменных более подробно в следующем разделе.
В строке 3 описывается цель program , имеющая пять зависимостей, причем тремя ее зависимостями являются другие цели ( file2.o , file3.o и file4.o ), а остальными двумя — файл исходного кода на языке C++ и соответствующий заголовочный файл. Цель program имеет лишь одну ассоциированную команду, которая приведена в строке 4. Однако, как становится очевидно при рассмотрении цели clean (также из приведенного выше Make-файла), с любой целью может ассоциироваться более одной команды. В строках с 6 по 10 приведены инструкции по созданию объектных файлов на основе трех классов из файлов с исходным кодом на языке С++ с именами file2.cpp , file3.cpp и file4.cpp соответственно. Последнее правило предназначено для удаления всех временных файлов — использование цели clean является обычной практикой для Make-файлов, так как подобная цель, осуществляющая удаление всех временных файлов без какой-либо модификации основных файлов проекта, позволяет осуществлять полную пересборку проекта.
Параметр -с компилятора из набора GCC используется главным образом для обработки файлов, которые не содержат реализации функции main() , так как он сообщает компилятору C++ из состава GCC о том, что нужно осуществлять лишь предварительную обработку, компиляцию и ассемблирование исходного кода. Параметр -o , используемый в рамках цели program сообщает g++ и gcc о необходимости сохранения результирующего бинарного файла под именем . Если вы попытаетесь задействуете цель, соответствующую файлам в актуальном состоянии, вы получите аналогичный вывод:
Давайте рассмотрим более сложный пример проекта на языке C. Файлы этого проекта находятся в директории advanced архива, доступного по ссылке www.linuxvoice.com/make23.tar.gz . Make-файл позволяет скомпилировать исходный код проекта и сгенерировать исполняемый файл таким же образом, как и в предыдущем проекте, причем в данном случае также осуществляется копирование сгенерированного исполняемого файла в другую директорию с помощью цели install . Директория /tmp используется в качестве примера для того, чтобы вам не приходилось захламлять системные директории при тестировании примера, на самом же деле бинарные файлы обычно сохраняются в директории /usr/local/bin .
В первой части Make-файла описывается множество переменных, которые будут использоваться далее в файле и могут быть разделены на два вида. Некоторые переменные используются для хранения путей к бинарным файлам команд (это позволяет переносить Make-файлы на другие операционные системы). Например:
Другие переменные используются для формирования имен новых файлов на основе различных параметров, таких, как дата и путь к резервной копии файла. Например:
Несложно заметить, что имеется возможность комбинирования множества переменных в рамках одной инструкции для генерации уникальных имен файлов и директорий.
Рассматриваемый Make-файл содержит переменную, хранящую номер версии вашей программы. Значение этой переменной может изменяться либо с помощью параметра командной строки, либо путем редактирования самого Make-файла. Если вы желаете использовать значение переменной, отличное от объявленного в Make-файле (в данном случае это переменная VERSION), вы можете осуществить аналогичный вызов GNU Make:
Однако, данная возможность должна использоваться с особой осторожностью особенно при работе с номерами версий или другими важными параметрами сборки проектов, так как вы в конце концов можете запутаться в версиях своей программы и потерять важные изменения кода.
Переменные GNU Make также называются макросами. Следующее правило является реализацией цели make all :
Это простая цель, которая позволяет создать программный продукт на основе его исходного кода путем передачи управления другому правилу ( executable ). Все программы проекта GNU должны в обязательном порядке поддерживать цель all .
Следующее правило реализует команду make clean , позволяющую удалить все файлы, которые были сгенерированы при предыдущих сборках проекта:
Это очень простое правило, удаляющее все файлы, сгенерированные при предыдущих сборках проекта. Символ @ сообщает GNU Make о том, что в процессе исполнения команды ее вывод не должен отображаться с помощью терминала.
Правило install просто копирует скомпилированные файлы в нужное место. Его реализация выглядит следующим образом:
Цель target должна зависеть от цели executable , так как при отсутствии исполняемого файла вы не сможете установить его в систему!
Для копирования файла в директорию, расположенную за пределами домашней директории, обычно требуются особые привилегии. Директория /tmp является исключением из данного правила; однако, директория /tmp обычно очищается после перезагрузки системы. Если вам нужно установить бинарный файл в директорию /usr/local/bin , которая обычно используется для хранения исполняемых файлов, вам придется выполнить команду make install либо от лица пользователя root, либо с помощью утилиты sudo .
Следующие команды реализуют команду make backup , генерируя архив с резервной копией файлов проекта, уникально идентифицируемый с помощью времени и даты создания:
Хранение резервной копии файлов проекта за пределами его директории является разумной практикой. В приведенном выше Make-файле файл архива сохраняется в директории /tmp , но вы можете использовать вместо нее любую другую директорию.
Другой переменной, практически всегда используемой в процессе компиляции кода на языках C и C++, является переменная CFLAGS , которая хранит флаги, используемые в процессе компиляции. Например, вы можете активировать режим вывода всех предупреждений компилятора и включить информацию о символах в результирующий бинарный файл для упрощения процесса отладки с помощью следующих флагов:
Вы можете изменить значение переменной CFLAGS для активации поддержки отладчиков, механизмов оптимизации кода или генерации машинного кода для отличной архитектуры центрального процессора.
Для того, чтобы избавить разработчиков от создания огромного количества аналогичных правил в make была добавлена поддержка шаблонов. Например, символ % соответствует любой последовательности символов. Этот механизм может пригодится, к примеру, в том случае, если вам понадобится скомпилировать все файлы с исходным кодом на языке C и сохранить объектный код в файлах с соответствующими именами:
В данном случае вам также следует обратить внимание на типичный пример использования переменной CFLAGS . Вы должны самостоятельно принять решение о том, обоснованно ли написание отдельных правил для генерации объектных файлов в ручном режиме или проще воспользоваться соответствующим шаблоном. Вообще говоря, подход с использованием шаблонов является предпочтительным тогда, когда приходится обрабатывать большое количество файлов. Конечно же, в случае использования шаблона вам придется также изменить вашу реализацию команды make clean на аналогичную приведенной ниже:
Следующая цель позволяет вывести список значений всех переменных Make-файла:
Список значений будет достаточно длинным, так как в него также будут включены все значения переменных командной оболочки. Но, несмотря на это, данная цель является достаточно полезной для отладки Make-файла.
Вы можете сделать вывод данной цели чуть более простым с помощью фильтра, ограничивающего объем выводимых данных. Например, если вам нужно получить список значений всех переменных с именами, начинающимися с буквы A, вы можете использовать следующую версию цели, задействующую механизм шаблонов и регулярное выражение:
Несложно заметить, что Make-файл становится достаточно сложным для чтения после добавления целей, правил, зависимостей и переменных, практически таким же, как файл с исходным кодом проекта. По этой причине вы должны стараться структурировать его содержимое и при необходимости добавлять в него комментарии, которые должны начинаться с символа решетки.
Make масштабируется практически до любого уровня сложности проекта. Даже исходный код ядра Linux содержит Make-файлы
Несмотря на то, что основным предназначением утилиты make является автоматизация процесса сборки программных проектов, администраторы Unux-систем, а также их обычные пользователи могут использовать ее и для своих целей. Вы можете использовать данную утилиту для создания резервных копий файлов конфигурации после их обновления, установки новых версий сценариев командной оболочки, генерации новых таблиц поиска Postfix с последующим перезапуском соответствующей службы, создания заданной структуры директорий для каждого из новых пользователей системы, генерации документации и выполнения других подобных действий — ее возможности безграничны; конечно же, вы также можете выработать новые методики использования утилиты GNU Make.
Источник