мета-данные страницы
  •  

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
soft:make [2025/03/17 16:45] – создано radi0devsoft:make [2025/11/09 12:07] (текущий) – внешнее изменение A User Not Logged in
Строка 1: Строка 1:
 +====== make ======
 +
  
-Нужно для: [[cmake]] 
 (https://www.opennet.ru/docs/RUS/gnumake/) (https://www.opennet.ru/docs/RUS/gnumake/)
  
-___ 
  
-NTB: Сборка = компиляция + линковка.+NTB: //Сборка// //компиляция// //линковка//
  
-Если запустить  `make то программа попытается найти файл с именем по умолчание `Makefileв текущем каталоге и выполнить инструкции из него. Если в текущем каталоге есть несколько мейкфайлов, то можно указать на нужный вот таким образом:  `make -f MyMakefile`+Если запустить  ''make''  то программа попытается найти файл с именем по умолчание ''Makefile'' в текущем каталоге и выполнить инструкции из него. Если в текущем каталоге есть несколько мейкфайлов, то можно указать на нужный вот таким образом:  ''make -f MyMakefile'' 
 + 
 +Работу ''make'' можно представить себе так: ''{Из чего делаем? (реквизиты)} ---> [Как делаем? (команды)] ---> {Что делаем? (цели)}'' 
 + 
 +===== Синтаксис Makefile ===== 
 + 
 +==== Общая структура ====
  
-Работу `make` можно представить себе так: 
-``` 
-{Из чего делаем? (реквизиты)} ---> [Как делаем? (команды)] ---> {Что делаем? (цели)} 
-``` 
-## Общая структура 
 MakeFile состоит из набора правил, которые в свою очередь описываются: MakeFile состоит из набора правил, которые в свою очередь описываются:
-1) целями (то, что данное правило делает);   +  * целями (то, что данное правило делает);   
-2) реквизитами (то, что необходимо для выполнения правила и получения целей);   +  реквизитами (то, что необходимо для выполнения правила и получения целей);   
-3) командами (выполняющими данные преобразования). +  командами (выполняющими данные преобразования). 
-В общем виде синтаксис makefile можно представить так:   + 
-```+В общем виде синтаксис makefile можно представить так:  
 +<code>
 # Индентация осуществляется исключительно при помощи символов табуляции, # Индентация осуществляется исключительно при помощи символов табуляции,
 # каждой команде должен предшествовать отступ # каждой команде должен предшествовать отступ
Строка 26: Строка 28:
  ...  ...
  <команда #n>  <команда #n>
-```+</code> 
 + 
 +==== Инкрементная компиляция ====
  
-___ 
-## Инкрементная компиляция 
 Если файлов в проекте много, при каждой сборке весь проект компилируется полностью, а это долго. Решение - разделить компиляцию на два этапа: трансляция и линковка. Если файлов в проекте много, при каждой сборке весь проект компилируется полностью, а это долго. Решение - разделить компиляцию на два этапа: трансляция и линковка.
  
 Теперь, когда внесены изменения в один из исходников, достаточно произвести его трансляцию, а затем произвести линковку всех объектных файлов. Такой подход называется **инкрементной компиляцией**. Для ее поддержки make сопоставляет время изменения целей и их реквизитов (используя данные файловой системы), благодаря чему самостоятельно решает какие правила следует выполнить, а какие можно просто проигнорировать: Теперь, когда внесены изменения в один из исходников, достаточно произвести его трансляцию, а затем произвести линковку всех объектных файлов. Такой подход называется **инкрементной компиляцией**. Для ее поддержки make сопоставляет время изменения целей и их реквизитов (используя данные файловой системы), благодаря чему самостоятельно решает какие правила следует выполнить, а какие можно просто проигнорировать:
  
-```makefile+<code makefile>
 main.o: main.c main.o: main.c
  gcc -c -o main.o main.c  gcc -c -o main.o main.c
Строка 41: Строка 43:
 hello: main.o hello.o hello: main.o hello.o
  gcc -o hello main.o hello.o  gcc -o hello main.o hello.o
-``` +</code> 
-При первом запуске `makeпопытается сразу получить цель `hello`, но для неё нужны `main.oи `hello.o`, а их нет, так что `makeищет правила для них и выполняет. Как только все реквизиты будут получены, make вернется к выполнению отложенной цели. (Отсюда следует, что make выполняет правила рекурсивно.)+ 
 +При первом запуске ''make'' попытается сразу получить цель ''hello'', но для неё нужны ''main.o'' и ''hello.o'', а их нет, так что ''make'' ищет правила для них и выполняет. Как только все реквизиты будут получены, make вернется к выполнению отложенной цели. (Отсюда следует, что make выполняет правила рекурсивно.) 
 + 
 +==== Фиктивные цели ==== 
 + 
 +"фиктивные" (phony) цели позволяют осуществлять с помощью ''make'' не только сборку программы. Вот краткий список стандартных целей: 
 +''all'' — является стандартной целью по умолчанию. При вызове ''make'' ее можно явно не указывать. 
 +''clean'' — очистить каталог от всех файлов полученных в результате компиляции. 
 +''install'' — произвести инсталляцию 
 +''uninstall'' — и деинсталляцию соответственно.
  
-___ 
-## Фиктивные цели 
-"фиктивные" (phony) цели позволяют осуществлять с помощью `make` не только сборку программы. Вот краткий список стандартных целей: 
-- `all` — является стандартной целью по умолчанию. При вызове `make` ее можно явно не указывать. 
-- `clean` — очистить каталог от всех файлов полученных в результате компиляции. 
-- `install` — произвести инсталляцию 
-- `uninstall` — и деинсталляцию соответственно. 
 Для того чтобы make не искал файлы с такими именами, их следует определить в Makefile, при помощи директивы .PHONY Для того чтобы make не искал файлы с такими именами, их следует определить в Makefile, при помощи директивы .PHONY
-```makefile+<code makefile>
 .PHONY: all clean install uninstall .PHONY: all clean install uninstall
  
Строка 69: Строка 73:
 uninstall: # деинсталяция uninstall: # деинсталяция
  rm -rf /usr/local/bin/hello  rm -rf /usr/local/bin/hello
-``` +</code> 
-ВАЖНО: `cleanнеобходим, что бы принудительно пересобрать проект с нуля, так как если реквизит `helloуже существует, `makeего переделывать не будет. Однако, в данном случаи достаточно руками удалить `helloи запустить сборку, что бы не пересобрать все объектники.+ 
 +ВАЖНО: ''clean'' необходим, что бы принудительно пересобрать проект с нуля, так как если реквизит ''hello'' уже существует, ''make'' его переделывать не будет. Однако, в данном случаи достаточно руками удалить ''hello'' и запустить сборку, что бы не пересобрать все объектники. 
 + 
 +==== Использование переменных и комментариев ====
  
-___ 
-## Использование переменных и комментариев 
 Переменные - удобный способ учесть возможность того, что проект будут собирать другим компилятором или с другими опциями. Переменные - удобный способ учесть возможность того, что проект будут собирать другим компилятором или с другими опциями.
-```makefile+<code makefile>
 CC=g++ # Это комментарий, который говорит, что переменная CC указывает компилятор, используемый для сборки CC=g++ # Это комментарий, который говорит, что переменная CC указывает компилятор, используемый для сборки
 CFLAGS=-c -Wall # Это еще один комментарий. Он поясняет, что в переменной CFLAGS лежат флаги, которые передаются компилятору CFLAGS=-c -Wall # Это еще один комментарий. Он поясняет, что в переменной CFLAGS лежат флаги, которые передаются компилятору
Строка 84: Строка 89:
 main.o: main.cpp main.o: main.cpp
  $(CC) $(CFLAGS) main.cpp  $(CC) $(CFLAGS) main.cpp
-```+</code> 
 По умолчанию make станет выполнять самое первое правило, если цель выполнения не была явно указана при вызове: По умолчанию make станет выполнять самое первое правило, если цель выполнения не была явно указана при вызове:
-```shell+<code bash>
 $ make <цель> $ make <цель>
-``` +</code> 
-## Автоматические переменные + 
-- `$@Имя цели обрабатываемого правила +==== Автоматические переменные ==== 
-- `$<Имя первой зависимости обрабатываемого правила +  * ''$@'' Имя цели обрабатываемого правила\\ 
-- `$^Список всех зависимостей обрабатываемого правила+  * ''$<'' Имя первой зависимости обрабатываемого правила\\ 
 +  * ''$^'' Список всех зависимостей обрабатываемого правила 
 + 
 +подробнее [[https://rus-linux.net/nlib.php?name=/MyLDP/algol/gnu_make/gnu_make_3-79_russian_manual.html#SEC101|тут]] 
 + 
 +===== Примеры ===== 
 + 
 +==== Демонстрация удобства использования MakeFile ====
  
-подробнее [тут](https://rus-linux.net/nlib.php?name=/MyLDP/algol/gnu_make/gnu_make_3-79_russian_manual.html#SEC101) 
-___ 
-## Примеры (разработка) 
-#### Демонстрация удобства использования MakeFile 
 Пример компиляции руками: Пример компиляции руками:
-```shell+<code bash>
 # main.cpp - главный файл # main.cpp - главный файл
 # functions.h - прототипы всех ф-ий # functions.h - прототипы всех ф-ий
Строка 105: Строка 114:
 # hello.cpp -  # hello.cpp - 
 g++ main.cpp hello.cpp factorial.cpp -o prog g++ main.cpp hello.cpp factorial.cpp -o prog
-```+</code> 
 Долго каждый раз писать. Да и при разрастании проекта можно запутаться. Автоматизируем. Для нашего примера мейкфайл будет выглядеть так: Долго каждый раз писать. Да и при разрастании проекта можно запутаться. Автоматизируем. Для нашего примера мейкфайл будет выглядеть так:
-```makefile+<code makefile>
 all: all:
  g++ main.cpp hello.cpp factorial.cpp -o hello  g++ main.cpp hello.cpp factorial.cpp -o hello
-```+</code> 
 Использовать несколько целей в одном мейкфайле полезно для больших проектов. Это связано с тем, что при изменении одного файла не понадобится пересобирать весь проект, а можно будет обойтись пересборкой только измененной части. Пример: Использовать несколько целей в одном мейкфайле полезно для больших проектов. Это связано с тем, что при изменении одного файла не понадобится пересобирать весь проект, а можно будет обойтись пересборкой только измененной части. Пример:
-```makefile+<code makefile>
 all: hello all: hello
  
Строка 126: Строка 137:
 clean: clean:
  rm -rf *.o hello  rm -rf *.o hello
-``` +</code>
-Теперь у цели `all` есть только зависимость, но нет команды. В этом случае make при вызове последовательно выполнит все указанные в файле зависимости этой цели.   +
-Еще добавилась новая цель `clean`. Она традиционно используется для быстрой очистки всех результатов сборки проекта. Очистка запускается так: `make -f Makefile-2 clean`+
  
-#### Универсальный MakeFile +Теперь у цели ''all'' есть только зависимость, но нет команды. В этом случае make при вызове последовательно выполнит все указанные в файле зависимости этой цели.   
-```makefile+ 
 +Еще добавилась новая цель ''clean''. Она традиционно используется для быстрой очистки всех результатов сборки проекта. Очистка запускается так: ''make -f Makefile-2 clean'' 
 + 
 +==== Универсальный MakeFile ==== 
 + 
 +<code makefile>
 CC=g++ CC=g++
 CFLAGS=-c -Wall CFLAGS=-c -Wall
Строка 146: Строка 160:
 .cpp.o: .cpp.o:
  $(CC) $(CFLAGS) $< -o $@  $(CC) $(CFLAGS) $< -o $@
-```+</code>
  
-___ +==== Удобство для пользователя ====
- +
-## Примеры (использование)+
  
 установка при помощи исходников (любые, программы и библиотеки). Допустим, наш целевой пакет называется "hello". установка при помощи исходников (любые, программы и библиотеки). Допустим, наш целевой пакет называется "hello".
-1) Получаем код:+ 
 +''1)'' Получаем код: 
 можно клонировать репозиторий: можно клонировать репозиторий:
-```shell+<code bash>
 git clone hello git clone hello
 cd hello cd hello
-```+</code> 
 ИЛИ используем тарболл: ИЛИ используем тарболл:
-```shell+<code bash>
 tar -xf hello-1.0.tar.xz tar -xf hello-1.0.tar.xz
-```+</code> 
 + 
 +''2)'' Сборка:
  
-2) Сборка: 
 если хотим использовать голый make: если хотим использовать голый make:
-```shell+<code bash>
 make PREFIX=/префикс-который-вы-хотите make PREFIX=/префикс-который-вы-хотите
-```+</code> 
 если используем autotools: если используем autotools:
-```shell+<code bash>
 ./configure --prefix=/префикс-который-вы-хотите ./configure --prefix=/префикс-который-вы-хотите
 make make
-```+</code> 
 если используем cmake: если используем cmake:
-```shell+<code bash>
 cmake -DCMAKE_INSTALL_PREFIX=/префикс-который-вы-хотите . cmake -DCMAKE_INSTALL_PREFIX=/префикс-который-вы-хотите .
 make make
-```+</code> 
 Откуда точка в конце? Дело в том, что cmake'у нужно передавать путь к сорцам. А поскольку у нас не out of tree build, мы собираем здесь же. Сорцы находятся там же, где находимся мы. Поэтому точка, т. е. текущий каталог. Откуда точка в конце? Дело в том, что cmake'у нужно передавать путь к сорцам. А поскольку у нас не out of tree build, мы собираем здесь же. Сорцы находятся там же, где находимся мы. Поэтому точка, т. е. текущий каталог.
  
-3) Установка:+''3)'' Установка: 
 Используя make: Используя make:
-```shell+<code bash>
 make PREFIX=/префикс-который-вы-хотите install make PREFIX=/префикс-который-вы-хотите install
-```+</code> 
 Используя autotools или cmake: Используя autotools или cmake:
-```shell+<code bash>
 make install make install
-```+</code>
  
 Cборка всегда осуществляется с обычными правами, а вот установка осуществляется с теми правами, которые нужны, чтобы записать в prefix. Cборка всегда осуществляется с обычными правами, а вот установка осуществляется с теми правами, которые нужны, чтобы записать в prefix.