8151
Комментарий:
|
8495
|
Удаления помечены так. | Добавления помечены так. |
Строка 57: | Строка 57: |
* Сборка цели считается ''неуспешной'', если команда завершилась с ненулевым статусом (так делают компиляторы при ошибках) | |
Строка 95: | Строка 96: |
* Затем ''выводы'' соответствующих запусков сравниваются (например, с помощью `cmp file1 file2`) | * Затем ''выводы'' соответствующих запусков сравниваются (например, с помощью `cmp file1 file2`, который вернёт ненулевой статус ошибки, если файлы не одинаковы) |
Многофайловая сборка
Сначала про настройку окружения
.dircolors; grep; man; PS1
vim: цветовые схемы, *~-файлы, vimbackup
- (есть пакет в ALT)
zsh/bash: раскраска командной строки, алиасы
велосипедный парк ~/bin
что ещё?
Сборка из нескольких файлов
- Зачем много файлов?
- Быстрее компилировать не все
- Проще ориентироваться
- Си: пространства имён!
- Скомпилировать сразу все файлы?
- (пере)компиляция только изменённых
Компиляция до .o
(повтор: сложность компоновки вручную с помощью ld)
Make
Проблемы многофайловой сборки: вручную муторно, сценарий делает много лишнего
- Перекомпиляция только обновлённых исходников
- Построение графа зависимостей и подграфа пересборки
- Пример:
- Проект:
- Исходники — файлы на Си
- Из них компилируются объектники
- Из некоторых объектников собираются библиотеки
- Из некоторых объектников и библиотек собираются бинарники
Мы изменили один файл на си
- Что нуждается в пересборке?
- Проект:
- Удаление мусора и генератов
В том числе того, что разработчик считает генератом
- В примере выше:
- Бинарники, библиотеки и объектники — это генраты
- Однако иногда бинарники и библиотеки удалять не надо!
- Скриптование / code reuse / общая настройка приёмов сборки
- в т. ч. уникальных для проекта
- Например, все бинарники надо собирать с такими-то библиотеками, при компиляции испольозвать такие-то ключи и т. п.
ТАБУЛЯЦИИ!
Gnu make
(есть много, но этот популярнее всех остальных, вместе взятых)
- Цели и рецепты
«Как создать некий файл из других файлов» (например, prog.o из prog.c)
«некий файл» — цель (target, $@)
«другие файлы» — исходники (prerequisites, $^)
- «как создать» — рецепт (recipe, список команд, выделенных табуляцией)
Вариант с шаблоном: «как создать файл определённого типа из других файлов другого определённого типа» (например .o из .c)
- Командный интерпретатор ОС в качестве языка сценариев (как правило, shell)
Сборка цели считается неуспешной, если команда завершилась с ненулевым статусом (так делают компиляторы при ошибках)
- ⇒ недостаток: нужен shell под системы, в которых его нет (Windows)
- Переменные
- Специальные переменные
Подстановка / подстановка с заменой $(foo:.o=.c) / ... (ещё куча всякого $( … ))
Отложенная (=) и немедленная (::= или :=, это одно и то же) подстановка (например, в присваивании) (тут)
Много правил по умолчанию, make -p
- условные операторы / функции
- … чёрт в ступе …
- … и не только …
Литература по GNU Make
Очень старый учебник по старому Make (зато подробный и с объяснениями)
Managing Projects with GNU Make, 3rd Edition (гуглится☺)
Книга Владимира Игнатова Эффективное использование GNU Make
Пример
См. FrBrGeorge/MakefileExample
Другие низкоуровневые системы сборки
Ориентированные на ЯП и особенности сред программирования Apache_Ant/Apache_Maven (Java), Cabal (Haskell), ASDF (Lisp/CLisp), Boost.Build…
∃ Более высокий уровень — инструменты генерации сборочных сценариев (+окружение, +варианты сборки, +параметризация, +…), об этом после
Д/З
- Прочитать и прощёлкать
по возможности учебник по Make (про интеграцию с античной системой контроля версий SCCS лучше не читать☺). Есть ли отличия в поведении от GNU Make?
В репозитории с Д/З сделать (вложенный) подкаталог 03_Multifile и поместить туда код из Пример применения make
- Убедиться, что он работает. Исправить ошибки, если они есть)
Доделать Makefile так, чтобы
Собирались две библиотеки: liboutput_static.a и liboutput.so из файлов fun.o и const.o
Собиралось три бинарника: prog (из .o-фйалов), prog-a (из prog.o и liboutput_static.a) и prog-so (из prog.o и liboutput.so)
Имелась цель test:, для достижения которой
- каждый из трёх бинарников запускается
без параметров (обратите внимание на перенаправление stderr),
- с одним каким-нибудь параметром
- и с тремя параметрами (для каждого бинарника параметры одинаковые).
Затем выводы соответствующих запусков сравниваются (например, с помощью cmp file1 file2, который вернёт ненулевой статус ошибки, если файлы не одинаковы)
- каждый из трёх бинарников запускается
И чтобы все генераты удалялись по make clean!