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-файл збільшиться ще на один рядок:
Таким чином, один цільовий файл може вказуватися з кількома цілями. При цьому повний список залежностей для файлу буде складений зі списків залежностей всіх цілей, в яких він бере участь, створення файлу буде проводитися лише один раз.