Make - це

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

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

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

Сучасні версії

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

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

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

Використання

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

make відкриває 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-файл збільшиться ще на один рядок:

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