Make, програми і утиліти

make - утиліта, яка автоматизує процес перетворення файлів з однієї форми в іншу. Найчастіше це компіляція вихідного коду в об'єктні файли і подальша компонування у виконувані файли або бібліотеки.

Утиліта використовує спеціальні make-файли, в яких вказані залежності файлів один від одного і правила для їх задоволення. На основі інформації про час останнього зміни кожного файлу make визначає і запускає необхідні програми.

До створення make системи збирання (компіляції) ПО Unix зазвичай складалися з shell-скриптів збірки, які супроводжували вихідний код програм.

make була створена Стюартом Фельдманом (Stuart Feldman) в 1977 році в Bell Labs.

В даний час існує безліч утиліт для відстеження залежностей, але make - одна з найбільш широко поширених, в першу чергу завдяки тому, що вона включена в Unix, починаючи з версії PWB / UNIX (англ. Programmer's Workbench), яка містила інструменти для розробки програмного забезпечення.

Існує кілька версій make. заснованих на оригінальній make або написаних з нуля, що використовують ті ж самі формати файлів і базові принципи і алгоритми, а також містять деякі поліпшення і розширення. наприклад:

  • BSD make. заснована на роботі Адама де Бура (Adam de Boor) над версією make. з можливістю паралельної збірки; в тій чи іншій формі перейшла в FreeBSD, NetBSD і OpenBSD.
  • GNU make - входить в більшість дистрибутивів Linux і часто використовується в поєднанні з GNU build system.

POSIX включає в себе стандарт основних можливостей утиліти make. з тим або іншим ступенем сумісності реалізований в різних версіях make. Як правило, прості make-файли можуть бути успішно використані різними версіями make.

Якщо опція -f не вказана, використовується ім'я за замовчуванням для make-файлу - Makefile (проте, в різних реалізаціях make крім цього можуть перевірятися і інші файли, наприклад GNUmakefile).

make відкриває make-файл, зчитує правила і виконує команди, необхідні для створення зазначеної мети.

Стандартні цілі для збірки дистрибутивів GNU:

У процесі складання додатків BSD часто застосовують:

  • depend - виконати компіляцію / вибудовування залежностей
Make-файл

Програма make виконує команди згідно з правилами, зазначеним у спеціальному файлі. Цей файл називається make-файл (makefile, мейкфайл). Як правило, make-файл описує, яким чином потрібно компілювати і компонувати програму.

make-файл складається з правил і змінних. Правила мають наступний синтаксис:

Правило являє собою набір команд, виконання яких приведе до збірки файлів-цілей з файлів-реквізиту.

Правило повідомляє make. що файли, одержувані в результаті роботи команд (цілі) є залежними від відповідних файлів-реквізиту. make не відчуває і не використовує вміст файлів-реквізиту, однак, вказівка ​​списку файлів-реквізиту потрібно тільки для того, щоб make переконалася в наявності цих файлів перед початком виконання команд і для відстеження залежностей між файлами.

Зазвичай мета являє собою ім'я файлу, який генерується в результаті роботи зазначених команд. Метою також може служити назва деякого дії, яке буде виконано в результаті виконання команд (наприклад, мета clean в make-файлах для компіляції програм зазвичай видаляє всі файли, створені в процесі компіляції).

Рядки, в яких записані команди. повинні починатися з символу табуляції.

Розглянемо нескладну програму на Сі. Нехай програма program складається з пари файлів коду - main.c і lib.c, а також з одного заголовки - defines.h, який підключений в обидва файли коду. Тому, для створення program необхідно з пар (main.c defines.h) і (lib.c defines.h) створити об'єктні файли main.o і lib.o, а потім скомпонувати їх в program. При складанні вручну потрібно дати наступні команди:

Якщо в процесі розробки програми в файл defines.h будуть внесені зміни, потрібно перекомпіляція обох файлів і лінковка, а якщо змінимо lib.c, то повторну компіляцію main.о можна не виконувати.

Таким чином, для кожного файлу, який ми повинні отримати в процесі компіляції потрібно вказати, на основі яких файлів і з допомогою якої команди він створюється. Програма make на основі цих даних виконує наступне:

  • збирає з цієї інформації правильну послідовність команд для отримання необхідних результуючих файлів;
  • і ініціює створення необхідного файлу тільки в разі, якщо такого файлу не існує, або він старше, ніж файли від яких він залежить.

Якщо при запуску make явно не вказати мету, то буде оброблятися перша мета в make-файлі, ім'я якої не починається з символу «.».

Для програми program досить написати наступний make-файл:

Варто відзначити ряд особливостей. В імені другої мети вказані два файли і для цієї ж мети не вказана команда компіляції. Крім того, ніде явно не вказана залежність об'єктних файлів від «* .c»-файлів. Справа в тому, що програма make має зумовлені правила для отримання файлів з певними розширеннями. Так, для мети-об'єктного файлу (розширення «.o») при виявленні відповідного файлу з розширенням «.c» буде викликаний компілятор «сс -з» із зазначенням в параметрах цього «.c»-файлу і всіх файлів-залежностей.

Синтаксис для визначення змінних:

Значним може бути довільна послідовність символів, включаючи пробіли та звернення до значень інших змінних. З урахуванням сказаного, можна модифікувати наш make-файл наступним чином:

Потрібно відзначити, що обчислення значення змінних відбувається лише за потреби (використовується так зване ліниве обчислення). Наприклад, при складанні мети all з наступного make-файлу на екран буде виведений рядок «Huh?».

Припустимо, що до проекту додався другий заголовки lib.h, який включається тільки в lib.c. Тоді make-файл збільшиться ще на одну сходинку:

Таким чином, один цільової файл може вказуватися в декількох цілях. При цьому повний список залежностей для файлу буде складено зі списків залежностей всіх цілей, в яких він бере участь, створення файлу буде проводитися тільки один раз.

Схожі статті