make


make (укр. зробити) — утиліта для автоматичної побудови програм. Дії, що повинна виконати make, описують в спеціальних файлах, які називаються Makefile.




Зміст





  • 1 Основні відомості


  • 2 Походження


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


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


  • 5 Make-файл

    • 5.1 Приклад


    • 5.2 Змінні



  • 6 Зноски


  • 7 Посилання




Основні відомості |


Make вказує послідовність дій, які повинні бути виконані заради побудови програми. В основному ця послідовність складається з викликів команд компілятора, компонувальника та файлової системи.


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



Походження |


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


make була створена Стюартом Фельдманом[en] в 1977 році в Bell Labs.


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



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


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


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

  • GNU make — входить в більшість дистрибутивів GNU/Linux і часто використовується у поєднанні з GNU build system.

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



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


make [-f make-файл] [ціль] ...

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


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



Make-файл |


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


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


ціль1 ціль2 ...: реквізит1 реквізит2 ...
Команда1
Команда2
...

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


Правило повідомляє 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. При збірці вручну потрібно дати такі команди:


cc -c main.c defines.h
cc -c lib.c defines.h
cc -o program main.o lib.o

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


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


  • Збирає з цієї інформації правильну послідовність команд для отримання необхідних кінцевих файлів;

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

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


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


program: main.o lib.o
cc -o program main.o lib.o
main.o lib.o: defines.h

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



Змінні |


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


змінна = значення

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


OBJ = main.o lib.o
program: $(OBJ)
cc -o program $(OBJ)
$(OBJ): defines.h

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


foo = $(bar)
bar = $(ugh)
ugh = Що?
all:
echo $(foo)

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


lib.o: lib.h

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



Зноски |



  1. make. The Open Group[en] Base Specifications Issue 7, 2016 Edition. Процитовано 2017-10-24. 


Посилання |


  • BSD Make man page

  • GNU Make

  • The GNU make manual

  • FreeBSD make manual page

  • OPUS Makefile Tutorial

  • GTK Hello World tutorial including HOWTO create Makefiles

  • Recursive Make Considered Harmful

  • What is wrong with make?

  • What’s Wrong With GNU make?


  • Advanced Auto-Dependency Generation.


Popular posts from this blog

1928 у кіно

Захаров Федір Захарович

Ель Греко