make

Матеріал з Вікіпедії — вільної енциклопедії.
Версія від 07:50, 30 квітня 2022, створена InternetArchiveBot (обговорення | внесок) (Виправлено джерел: 7; позначено як недійсні: 0.) #IABot (v2.0.8.7)
(різн.) ← Попередня версія | Поточна версія (різн.) | Новіша версія → (різн.)
Перейти до навігації Перейти до пошуку

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

Основні відомості[ред. | ред. код]

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. Архів оригіналу за 28 грудня 2017. Процитовано 24 жовтня 2017. 

Посилання[ред. | ред. код]