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

Save data to MySQL database using ExtJS and PHP [closed]2019 Community Moderator ElectionHow can I prevent SQL injection in PHP?Which MySQL data type to use for storing boolean valuesPHP: Delete an element from an arrayHow do I connect to a MySQL Database in Python?Should I use the datetime or timestamp data type in MySQL?How to get a list of MySQL user accountsHow Do You Parse and Process HTML/XML in PHP?Reference — What does this symbol mean in PHP?How does PHP 'foreach' actually work?Why shouldn't I use mysql_* functions in PHP?

Compiling GNU Global with universal-ctags support Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Tags for Emacs: Relationship between etags, ebrowse, cscope, GNU Global and exuberant ctagsVim and Ctags tips and trickscscope or ctags why choose one over the other?scons and ctagsctags cannot open option file “.ctags”Adding tag scopes in universal-ctagsShould I use Universal-ctags?Universal ctags on WindowsHow do I install GNU Global with universal ctags support using Homebrew?Universal ctags with emacsHow to highlight ctags generated by Universal Ctags in Vim?

Add ONERROR event to image from jsp tldHow to add an image to a JPanel?Saving image from PHP URLHTML img scalingCheck if an image is loaded (no errors) with jQueryHow to force an <img> to take up width, even if the image is not loadedHow do I populate hidden form field with a value set in Spring ControllerStyling Raw elements Generated from JSP tagds with Jquery MobileLimit resizing of images with explicitly set width and height attributeserror TLD use in a jsp fileJsp tld files cannot be resolved