Linux make очистить сборку

Обновлено: 07.07.2024

как make clean удаляет все файлы, созданные makefile, я хотел бы сделать то же самое с CMake. Слишком часто я вручную просматриваю каталоги, удаляя файлы, такие как cmake_install.cmake и CMakeCache.txt и CMakeFiles папки.

есть ли такая команда, как cmake clean чтобы удалить все эти файлы автоматически? В идеале это должно следовать рекурсивной структуре, определенной в текущем каталоге .

нет cmake clean .

обычно я создаю проект в одной папке, например "build". Так что если я хочу make clean , Я могу rm -rf build .

папка "build "в том же каталоге, что и корневые "CMakeLists".txt " обычно является хорошим выбором. Чтобы построить свой проект, вы просто даете cmake расположение CMakeLists.txt в качестве аргумента. Например: cd <location-of-cmakelists>/build && cmake .. . (Из @ComicSansMS)

некоторые деревья сборки, созданные с помощью GNU autotools, имеют " make distclean" цель, которая очищает сборку, а также удаляет Makefiles и другие части сгенерированной системы сборки. CMake не генерирует " make distclean " цель, потому что CMakeLists.txt-файлы могут запускать скрипты и произвольные команды; CMake не имеет возможности отслеживать, какие именно файлы генерируются как часть запуска CMake. Обеспечивая distclean цель даст пользователям ложное впечатление, что он будет работать, как ожидалось. (CMake создает цель" make clean " для удаления сгенерированных файлов компилятором и компоновщиком.)

цель "сделать distclean" только необходимо, если пользователь выполняет сборку in-source. С CMake поддерживает сборки в исходном коде, но мы настоятельно рекомендуем пользователям принять это понятие из сборки вне источника. Использование дерева сборки, отдельного от исходное дерево предотвратит CMake от создание любых файлов в дерево исходных текстов. Поскольку CMake не изменяет дерево источника, существует нет необходимости в цели distclean. Можно начать строить удаление дерева сборки или создание отдельного дерева сборки.

я гуглил его в течение получаса, и единственной полезной вещью, которую я придумал, был вызов find утилиты:

кроме того, не забудьте вызвать make clean (или любой генератор CMake, который вы используете) до что.

в эти дни Git везде, вы можете забыть CMake и использовать git clean -d -f -x , который удалит все файлы, не находящиеся под контролем источника.

вы можете использовать что-то вроде:

обычно я создаю команду "make clean-all", добавляя вызов "make clean" к предыдущему примеру:

Не пытайтесь добавить" чистую " цель в качестве зависимости:

потому что "чистый" не является реальной целью в CMake, и это не работает.

более того, вы не должны использовать этот "clean-cmake-files" как зависимость от чего-либо:

потому что, если вы это сделаете, все CMake файлы будут удалены перед очисткой - все завершено, и make выдаст вам ошибку поиска "CMakeFiles/clean-all.каталог/строительство.делать." Следовательно, вы не можете использовать команду clean-all перед "anything" в любом контексте:

Это тоже не работает.

просто издав rm CMakeCache.txt работает и для меня.

Я согласен, что сборка вне источника является лучшим ответом. Но для тех случаев, когда вы просто должны сделать сборку в исходном коде, я написал доступный скрипт Python здесь, где:

  1. запускает "make clean"
  2. удаляет определенные файлы CMake, созданные в каталоге верхнего уровня, такие как CMakeCache.txt
  3. для каждого подкаталога, который содержит каталог CMakeFiles, он удаляет CMakeFiles, Makefile, cmake_install.с CMake.
  4. удаляет все пустые подкаталоги.

решение, которое я нашел недавно, заключается в объединении концепции сборки вне источника с оболочкой Makefile.

в моих CMakeLists верхнего уровня.txt-файл, я включаю следующее, чтобы предотвратить сборки в исходном коде:

затем я создаю файл Makefile верхнего уровня и включаю следующее:

цель по умолчанию all выполните команду make , и ссылается на элемент ./build/Makefile .

первым делом цель ./build/Makefile тут - создать build каталог с помощью $(MKDIR) , которая является переменной для mkdir -p . Каталог build где мы выполним нашу сборку вне источника. Приводим аргумент -p обеспечить mkdir не кричит на нас за попытку создать каталог, который может уже существовать.

второе дело цель ./build/Makefile не менять каталоги и вызвать cmake .

обратно в all target, мы вызываем $(MAKE) -C build , где $(MAKE) - это переменная Makefile, автоматически генерируемая для make . make -C изменяет каталог, прежде чем что-либо делать. Поэтому, используя $(MAKE) -C build эквивалентно doing cd build; make .

подводя итог, называя эту оболочку Makefile с make all или make эквивалентно doing:

цель distclean вызывает cmake .. , потом make -C build clean и, наконец, удаляет все содержимое . Я верю, что это именно то, что вы просили в вашем вопросе.

последняя часть файла Makefile оценивает, является ли пользовательская цель distclean . Если нет, он изменит каталоги на build перед вызовом. Это очень мощный, потому что пользователь может ввести, например, make clean , и Makefile преобразует это в эквивалент cd build; make clean .

в заключение, эта оболочка Makefile в сочетании с обязательной конфигурацией CMake сборки вне источника делает это так что пользователь не должен взаимодействовать с командой cmake . Это решение также предоставляет элегантный метод для удаления всех выходных файлов CMake из .

P. S. В файле Makefile, мы используем префикс @ для подавления вывода команды оболочки и префикса @- игнорировать ошибки из командной оболочки. При использовании rm в рамках distclean target, команда вернет ошибку, если файлы не существуют (они, возможно, уже были удалены использование командной строки с rm -rf build , или они были не в первую очередь). Эта ошибка возврата заставит наш Makefile выйти. Мы используем префикс @- чтобы предотвратить это. Это приемлемо, если файл уже удален; мы хотим, чтобы наш Makefile продолжал работать и удалить остальные.

еще одна вещь, чтобы отметить: этот Makefile может не работать, если вы используете переменное количество переменных CMake для создания вашего проекта, например, cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar" . Этот Makefile предполагает, что вы вызываете CMake в согласованный способ, либо набрав cmake .. или путем предоставления cmake согласованное количество аргументов (которые вы можете включить в свой Makefile).

наконец, должное. Эта оболочка Makefile была адаптирована из Makefile, предоставленного Шаблон Проекта Приложения C++.

может быть, это немного устарело, но так как это первый хит, Когда вы google cmake clean , Я добавлю это:

так как вы можете начать сборку в каталоге сборки с указанной целью с

cmake --build . --target xyz

вы можете, конечно, запустить

cmake --build . --target clean

запустить clean target в сгенерированных файлах сборки.

в случае, когда вы передаете -D параметры в CMake при создании файлов сборки и не хотят удалять всю сборку / каталог:

просто удалите CMakeFiles / каталог внутри каталога сборки.

это приводит к повторному запуску CMake,и системные файлы сборки восстанавливаются. Ваша сборка также начнется с нуля.

конечно, исходные сборки-это метод перехода к файлам создания Unix, но если вы используете другой генератор, такой как Eclipse CDT, он предпочитает, чтобы вы строили in-source. В этом случае вам нужно будет очистить файлы CMake вручную. Попробуйте это:

или если вы включили globstar с shopt -s globstar , попробуйте этот менее отвратительный подход вместо этого:

Если у вас есть пользовательские определения и вы хотите сохранить их перед очисткой, выполните следующие действия в каталоге сборки:

затем создайте новый каталог сборки (или удалите старый каталог сборки и создайте его заново) и, наконец, запустите cmake с аргументами, которые вы получите со скриптом выше.

Если вы запустите

он будет регенерировать файлы CMake. Что необходимо при добавлении нового файла в исходную папку, выбранную *.cc, например.

хотя это не" чистый " как таковой, он "очищает" файлы CMake путем регенерации кэшей.

для таких целей я использую следующий сценарий оболочки:

Если вы используете Windows, используйте Cygwin для этого сценария.

для упрощения очистки при использовании сборки" вне источника " (т. е. вы строите в build directory), я использую следующий скрипт:

каждый раз, когда вам нужно очистить, вы должны исходить этот скрипт из

у меня есть это в моем rc-файле оболочки ( .bashrc , .zshrc ):

вы должны использовать только для сборки вне источника. Скажем, у вас есть каталог с именем build/ для этой цели. Тогда вам просто нужно бежать t-cmake-clean изнутри его.

Я ответ zsxwing успешно решить следующие задачи:

У меня есть источник, который я строю на нескольких хостах(на плате Raspberry Pi Linux, на виртуальной машине VMware Linux и т. д.)

У меня есть скрипт Bash, который создает временные каталоги на основе имени хоста машины следующим образом:

создайте временный каталог сборки, например, build_cmake . Следовательно, все ваши файлы сборки будут находиться внутри этой папки.

Меня всегда привлекал минимализм. Идея о том, что одна вещь должна выполнять одну функцию, но при этом выполнять ее как можно лучше, вылилась в создание UNIX. И хотя UNIX давно уже нельзя назвать простой системой, да и минимализм в ней узреть не так то просто, ее можно считать наглядным примером количество- качественной трансформации множества простых и понятных вещей в одну весьма непростую и не прозрачную. В своем развитии make прошел примерно такой же путь: простота и ясность, с ростом масштабов, превратилась в жуткого монстра (вспомните свои ощущения, когда впервые открыли мэйкфайл).

Мое упорное игнорирование make в течении долгого времени, было обусловлено удобством используемых IDE, и нежеланием разбираться в этом 'пережитке прошлого' (по сути — ленью). Однако, все эти надоедливые кнопочки, менюшки ит.п. атрибуты всевозможных студий, заставили меня искать альтернативу тому методу работы, который я практиковал до сих пор. Нет, я не стал гуру make, но полученных мною знаний вполне достаточно для моих небольших проектов. Данная статья предназначена для тех, кто так же как и я еще совсем недавно, желают вырваться из уютного оконного рабства в аскетичный, но свободный мир шелла.

Make- основные сведения

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

1) целями (то, что данное правило делает);
2) реквизитами (то, что необходимо для выполнения правила и получения целей);
3) командами (выполняющими данные преобразования).

В общем виде синтаксис makefile можно представить так:

То есть, правило make это ответы на три вопроса:


Несложно заметить что процессы трансляции и компиляции очень красиво ложатся на эту схему:

Простейший Makefile

Предположим, у нас имеется программа, состоящая всего из одного файла:


Для его компиляции достаточно очень простого мэйкфайла:


Данный Makefile состоит из одного правила, которое в свою очередь состоит из цели — «hello», реквизита — «main.c», и команды — «gcc -o hello main.c». Теперь, для компиляции достаточно дать команду make в рабочем каталоге. По умолчанию make станет выполнять самое первое правило, если цель выполнения не была явно указана при вызове:

Компиляция из множества исходников

Предположим, что у нас имеется программа, состоящая из 2 файлов:
main.c

Makefile, выполняющий компиляцию этой программы может выглядеть так:


Он вполне работоспособен, однако имеет один значительный недостаток: какой — раскроем далее.

Инкрементная компиляция

Представим, что наша программа состоит из десятка- другого исходных файлов. Мы вносим изменения в один из них, и хотим ее пересобрать. Использование подхода описанного в предыдущем примере приведет к тому, что все без исключения исходные файлы будут снова скомпилированы, что негативно скажется на времени перекомпиляции. Решение — разделить компиляцию на два этапа: этап трансляции и этап линковки.

Теперь, после изменения одного из исходных файлов, достаточно произвести его трансляцию и линковку всех объектных файлов. При этом мы пропускаем этап трансляции не затронутых изменениями реквизитов, что сокращает время компиляции в целом. Такой подход называется инкрементной компиляцией. Для ее поддержки make сопоставляет время изменения целей и их реквизитов (используя данные файловой системы), благодаря чему самостоятельно решает какие правила следует выполнить, а какие можно просто проигнорировать:


Попробуйте собрать этот проект. Для его сборки необходимо явно указать цель, т.е. дать команду make hello.
После- измените любой из исходных файлов и соберите его снова. Обратите внимание на то, что во время второй компиляции, транслироваться будет только измененный файл.

После запуска make попытается сразу получить цель hello, но для ее создания необходимы файлы main.o и hello.o, которых пока еще нет. Поэтому выполнение правила будет отложено и make станет искать правила, описывающие получение недостающих реквизитов. Как только все реквизиты будут получены, make вернется к выполнению отложенной цели. Отсюда следует, что make выполняет правила рекурсивно.

Фиктивные цели

На самом деле, в качестве make целей могут выступать не только реальные файлы. Все, кому приходилось собирать программы из исходных кодов должны быть знакомы с двумя стандартными в мире UNIX командами:


Командой make производят компиляцию программы, командой make install — установку. Такой подход весьма удобен, поскольку все необходимое для сборки и развертывания приложения в целевой системе включено в один файл (забудем на время о скрипте configure). Обратите внимание на то, что в первом случае мы не указываем цель, а во втором целью является вовсе не создание файла install, а процесс установки приложения в систему. Проделывать такие фокусы нам позволяют так называемые фиктивные (phony) цели. Вот краткий список стандартных целей:

  • all — является стандартной целью по умолчанию. При вызове make ее можно явно не указывать.
  • clean — очистить каталог от всех файлов полученных в результате компиляции.
  • install — произвести инсталляцию
  • uninstall — и деинсталляцию соответственно.


Теперь мы можем собрать нашу программу, произвести ее инсталлцию/деинсталляцию, а так же очистить рабочий каталог, используя для этого стандартные make цели.

Обратите внимание на то, что в цели all не указаны команды; все что ей нужно — получить реквизит hello. Зная о рекурсивной природе make, не сложно предположить как будет работать этот скрипт. Так же следует обратить особое внимание на то, что если файл hello уже имеется (остался после предыдущей компиляции) и его реквизиты не были изменены, то команда make ничего не станет пересобирать. Это классические грабли make. Так например, изменив заголовочный файл, случайно не включенный в список реквизитов, можно получить долгие часы головной боли. Поэтому, чтобы гарантированно полностью пересобрать проект, нужно предварительно очистить рабочий каталог:


Для выполнения целей install/uninstall вам потребуются использовать sudo.

Переменные

Все те, кто знакомы с правилом DRY (Don't repeat yourself), наверняка уже заметили неладное, а именно — наш Makefile содержит большое число повторяющихся фрагментов, что может привести к путанице при последующих попытках его расширить или изменить. В императивных языках для этих целей у нас имеются переменные и константы; make тоже располагает подобными средствами. Переменные в make представляют собой именованные строки и определяются очень просто:


Существует негласное правило, согласно которому следует именовать переменные в верхнем регистре, например:


Так мы определили список исходных файлов. Для использования значения переменной ее следует разименовать при помощи конструкции $(<VAR_NAME>); например так:


Ниже представлен мэйкфайл, использующий две переменные: TARGET — для определения имени целевой программы и PREFIX — для определения пути установки программы в систему.


Это уже посимпатичней. Думаю, теперь вышеприведенный пример для вас в особых комментариях не нуждается.

Автоматические переменные

Автоматические переменные предназначены для упрощения мейкфайлов, но на мой взгляд негативно сказываются на их читабельности. Как бы то ни было, я приведу здесь несколько наиболее часто используемых переменных, а что с ними делать (и делать ли вообще) решать вам:

  • $@ Имя цели обрабатываемого правила
  • $< Имя первой зависимости обрабатываемого правила
  • $^ Список всех зависимостей обрабатываемого правила

Заключение

В этой статье я попытался подробно объяснить основы написания и работы мэйкфайлов. Надеюсь, что она поможет вам приобрести понимание сути make и в кратчайшие сроки освоить этот провереный временем инструмент.

Утилита make предназначена для автоматизации сборки проектов. Если какие-либо файлы проекта могут быть сгенерированы из других файлов, утилита позволяет выполнить процесс построения наиболее оптимальным способом, по возможности минимизируя количество обрабатываемых файлов.

Исторически утилита предназначалась для сборки проектов на языке C в операционной системе Unix, однако может быть использоваться для работы с любыми проектами. Первая версия системы была создана в 1977 году.

На сегодняшний день наиболее распространены три варианта утилиты, объединенные общими принципами работы, но отличающиеся синтаксисом языка и возможностями:

GNU make — самый распространенный и функциональный вариант BSD make (pmake) — используется в проектах BSD, по функциональности примерно соответствует GNU make nmake (Microsoft make) — работает под Windows, малофункционален, только базовые принципы make.

Мы работаем с GNU make. На BSD системах (в частности, FreeBSD, он может быть доступен как gmake, на Linux — просто make).

Основные принципы

Утилита make работает по правилам (rules), записанным в специальном конфигурационном файле. Правила определяют цели (targets), завимости между целями и набор команд для выполнения каждой цели.

Цели могут соответствовать определенным файлам. Кроме того, цели могут не соответствовать ни одному файлу и использоваться для группировки других целей или определенной последовательности команд. Такие цели называются phony targets.

Каждая цель может зависеть от выполнения других целей. Выполнение цели требует предварительного выполнения других целей, от которых она зависит.

В случае зависимости между целями, соответствующими файлам, цель выполняется только в том случае, если файлы, от которых она зависит, новее, чем файл, соответствующий цели. Это позволяет перегенерировать только файлы, зависящие от измененных файлов, и не выполнять потенциально долгий процесс пересборки всех файлов проекта.

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

Запуск make

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

будет использовать файл Makefile , находящийся в текущем каталоге.

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

Явное указание цели выполняется инструкцией DEFAULT_GOAL в Makefile :

вызовет обработку цели clean файла Makefile , находящегося в текущем каталоге.

Можно указать сразу несколько целей.

Выполнение целей может быть настроено с использованием переменных (о которых ниже). При запуске make можно указать значения переменных:

Значение переменной PREFIX будет доступно в правилах Makefile и может быть использовано при сборке.

Команда поддерживает также ряд дополнительных опций, из которых наиболее важные следующие:

-C — переходит в указанный каталог перед выполнением, может быть, например, использована для запуска make из внешнего каталога по отношению к каталогу проекта -B — отключает проверку времени зависимых целей и принудительно выполняет их полностью

Базовый синтаксис make

Основная конструкция, используемая в файлах make , выглядит следующим образом:

command1 , command2 — команды, выполняемые для достижения цели target

Этот фрагмент определяет, что файл style.css зависит от файла src/less/app.less и для его сборки необходимо выполнить команду lessc src/less/app.less > style.css . Перегенерация файла style.css будет выполняться только в случае,если файл src/less/app.less новее, чем файл style.css (до тех пор, пока при запуске make не будет указан ключ -B ).

Перед каждой командой внутри описания цели должен присутствовать символ табуляции. В принципе, это настраивается, но лучше использовать общепринятые соглашения. Если вместо табуляции используются пробелы, make работать не будет.

В качестве команд обработки целей используются команды shell. Текст команды выводится, для того, чтобы он не выводился, команду необходимо начать с символа @ .

Каждая команда запускается в отдельном интерпретаторе shell, таким образом, команды не связаны друг с другом. Иначе говоря, одна строка команды — один shell. Это поведение может быть переопределено с помощью специальной цели .ONESHELL .

Если команду (или список зависимостей) необходимо записать в несколько строк, используют символ переноса \ .

PHONY targets

Цели, не соответствующие файлам, и предназначенные для выполнения набора команд или группировки завимостей, декларируются следующим образом:

Деклараций .PHONY может быть несколько, обычно определяют одну и прописывают туда все соответствующие цели.

В нашем примере вызов make clean приведет к выполнению цели clean , которая безусловно выполнит удаление временных файлов.

В случае, если у phony target есть зависимость в виде другой phony target, то зависимость выполняется перед зависящей целью. Таким образом, мы получаем механизм, напоминающий подпрограммы. Например, мы можем определить цель all , собирающую все файлы проекта, и отдельные цели css , js и php , собирающие отдельной css -файлы, js -файлы и обрабатывающие php файлы.

Соответственно, в Makefile мы можем написать:

В результате мы можем использовать make all для пересборки всех файлов и, скажем, make css для пересборки только CSS -файлов.

Переменные

В make-файле можно использовать переменные, хотя правильнее сказать, что можно использовать макросы.

Переменные определяются присваиванием в makefile или могут быть переданы извне.

Переменные — это макроопределения, причем вычисление переменной всегда выполняется в самый последний момент перед подстановкой. Макросы могут использовать везде в тексте makefile.

Подстановка выполняется конструкцией $(VAR) в отличие от shell, где используется $VAR .

Если в shell команде используется shell-переменная, необходимо квотить знак $ , дублируя его, например:

Помимо макропеременных существуют и более традиционные, в которых значение устанавливается сразу. Для работы с ними используется оператор := . В наших условиях достаточно использовать обычные переменные.

Часто требуется определить переменную только в том случае, если она еще не была определена. Для этого используется оператор ?= :

Соответственно, если мы вызовем

будет использована кодировка UTF8 , а в случае

будет использована CP1251 .

Если переменная содержит несколько строк, можно использовать синтаксис define :

Автоматические переменные

Make поддерживает набор автоматических переменных, облегчающих написание правил. Например, переменная $@ соответствую текущей цели (то, что слева от : ), а переменная $^ — списку зависимостей (то, что справа от : ). Таким образом, например, можно написать:

В результате www/js/script.js будет результатом объединения трех js-файлов.

Полный список таких переменных приведен в документации, для нас наиболее интересны:

С полным списком можно ознакомиться в документации: Automatic Variables.

Условное выполнение

В Makefile можно использовать условные выражения. Опять же, мы говорим о макрообработке make, соответственно, условные выражения работают на уровне makefile, а не на уровне команд. Обычно условные выражения используются для определения тех или иных целей в зависимости от значения переменных. Например:

В качестве условий можно проверять определенность переменной, а также ее значение:

Полностью с возможностями условных выражений можно ознакомиться в документации: Conditional syntax.

Шаблонные правила

Шаблонные правила (pattern rules) позволяют указать правило преобразования одних файлов в другие на основании зависимостей между их именами. Например, мы можем указать правило для получения объектного файла из файла на языке C:

Обратите внимание на использование переменной %< , которая в таких правилах используется для получения имени исходного файла.

Шаблоны не обязаны ограничиваться расширениями файлов. Если исходные и выходные файлы соответствуют друг другу и в их именах есть какая-либо зависимость, можно использовать pattern rule.

Включение других файлов make

Файл make может подключить другие файлы make оператором include :

Таким образом, из файлов можно строить модульную систему, часто имеет смысл выполнять include внутри условного оператора.

Функции

Make определяет большой набор функций, которые могут быть использованы в переменных (макросах). Вызов функции выполняется конструкцией:

Функции позволяют обрабатывать строки, имена файлов, организовывать циклы по набору значений, организовывать условный вызов других функций.

Несколько примеров из hive. Получаем текущее время (обратите внимание на использование := :

Включение файла container.mk только в случае, если он существует:

Добавление префиксов и суффиксов к именам файлов

Подробнее о функциях можно прочитать в документации Functions.

Собственные функции

Можно создавать собственные параметризованные функции путем определения переменных, содержащих специальные переменные $1 , $2 , . соответствующие переданным аргументам. Вызов пользовательской функции производится специальным макросом call :

Очень тупой пример:

Теперь можно написать:

Рекурсивный make

Помимо включения другого файла make, Makefile может выполнить другой файл make в виде отдельного make-процесса.

Это достаточно частая ситуация в случае модульных проектов. Например, для каждой из компонент проекта (сервер, клиент, библиотеки) предусмотрен свой Makefile , при этом есть основной Makefile , задающий набор общих настроек и вызывающий Makefile каждого подпроекта.

Вызов make из Makefile часто называют submake . Для вызова используется переменная $(MAKE) :

Значение этой переменной соответствует пути к программе make , обрабатывающей текущий файл.

Для передачи переменных в вызываемый таким образом файл их необходимо явно экспортировать:

Значение переменной PREFIX будет доступно в subsystem/Makefile .

Параллельный make

Make умеет распараллеливать выполнение правил. Для этого используется опция -j , позволяющая указать количество используемых параллельных процессов. Помимо ускорения процесса сборки эта особенность иногда позволяет реализовывать на коленке очень простые сценарии обработки, подразумевающие многозадачность. Например, можно реализовать простой, но работоспособный менеджер очередей на make, используя файлы для хранения заданий и каталоги для хранения файлов заданий на разных стадиях (ожидание, выполнение, результат).

Параллельное выполнение может быть запрещено с помощью специальной цели .NOTPARALLEL .

Специальные цели

Make поддерживает набор целей, которые могут быть использованы как модификаторы для последующих целей либо как служебные инструкции. Вот некоторые из таких специальных целей:

.DEFAULT — определяет цель, которая будет вызываться, если не найдена зависимая цель, необходимая для выполнения другой цели; .IGNORE — указывает цели, для которых необходимо игнорировать ошибки при выполнении цели; .SILENT — определяет набор целей, для которых необходимо подавлять вывод команд, выполняющих цель; .NOTPARALLEL — запрещает параллельное выполнение makefile; .ONESHELL — выполняет набор команд цели в одном процессе shell.

Варианты использования

Чаще всего о make говорят в контексте сборки программ на C/C++, в конце концов, для этого он изначально предназначался. Однако, make ­— гораздо более универсальный инструмент. Записывая makefile, мы декларативно описываем определенное состояние отношений между файлами, которое каждый запуск make будет стараться поддерживать. Декларативный характер определения состояния очень удобен, в случае использования какого-либо императивного языка (например, shell) нам приходилось бы выполнять большое количество различных проверок, получая на выходе сложный и запутанный код.

Кроме того, использование зависимостей между phony targets, позволяющии, по сути, декларативно описывать некий (ограниченный) конечный автомат, может быть полезно для написания различных административных сценариев. Используя make в качестве каркаса для выполнения различных shell-команд, мы получаем по сути некий базовый framework для shell с готовым пользовательским интерфейсом (вызов make + передача переменных), встроенными средствами отслеживания зависимостей, параллельного выполнения, макроопределениями и т.д.

Поэтому базовое знание make позволяет в ряде случаев решить проблему пусть и не самым красивым, но зато быстрым и достаточно надежным способом.

Если вы уже собирали прикладную программу из исходных кодов, то обратили внимание на стандартную последовательность команд: make; make install.

Без утилиты make не обходится создание ни одного серьезного проекта. Эта утилита управляет сборкой большого проекта, состоящего из десятков и сотен файлов. Программа make может работать не только с компилятором gcc, но и с любым компилятором для любого языка программирования, способным запускаться из командной строки.

Директивы утилиты make служат для определения зависимостей между файлами проекта и находятся в файле по имени Makefile, расположенном в каталоге сборки.

Разберемся, как пишутся make-файлы. Общий формат make-файла выглядит так:

Цель — это метка для некоторой последовательности команд (например, install) или результирующий файл, который нужно «построить» — скомпилировать или скомпоновать.

Цели должны отделяться друг от друга хотя бы одной пустой строкой. Список необходимых файлов — это перечень файлов или других целей, которые нужны для достижения данной цели; он может быть и пустым.

Последовательность команд — это команды, которые нужно выполнить для достижения цели. Последовательность команд должна отделяться от начала строки символом табуляции, иначе вы получите ошибку «missing separator» (нет разделителя).

В make-файлах вы можете использовать макроопределения:

MODFLAGS:= -O3 -Wall -DLINUX -I$(PATH)

$(CC) $(MODFLAGS) -c proga.c

Чтобы обратиться к макроопределению в команде или в другом макроопределении, нужно использовать конструкцию $(имя). Макроопределение может включать в себя другое, ранее определенное, макроопределение.

Формат запуска утилиты make:

make [-f файл] [ключи] [цель]

Ключ -f указывает файл инструкций, который нужно использовать вместо Makefile. Если этот ключ не указан, то make ищет в текущем каталоге файл Makefile и начинает собирать указанную цель. Если цель не указана, то выполняется первая встреченная в make-файле. Сборка выполняется рекурсивно: make сначала выполняет все цели, от которых зависит текущая цель. Если зависимость представляет собой файл, то make сравнивает его время последней модификации со временем целевого файла: если целевой файл старше или отсутствует, то будет выполнена указанная последовательность команд. Если целевой файл моложе, то текущая цель считается достигнутой.

Если нужно избежать пересборки какого-то из файлов проекта, то можно искусственно «омолодить» его командой touch, которая присвоит ему в качестве времени последней модификации текущее время. Если нужно, наоборот, принудительно пересобрать цель, то следует «омолодить» один из файлов, от которых она зависит.

Работа программы make заканчивается, когда достигнута цель, указанная в командной строке. Обычно это цель all, собирающая все результирующие файлы проекта. Другими распространенными целями являются install (установить собранную программу) и clean (удалить ненужные файлы, созданные в процессе сборки).

В листинге 21.2 представлен make-файл, собирающий небольшой проект из двух программ client и server, каждая из которых компилируется из одного файла исходного кода.

Листинг 21.2. Примерный make-файл

all: client server

$(CC) client.с -о client

$(CC) server.с -о server

Обычно при вызове утилиты make не нужно задавать никаких ключей. Но иногда использование ключей бывает очень кстати (таблица 21.1).

Ключи команды make Таблица 21.1

Ключ Назначение -C каталог Перейти в указанный каталог перед началом работы -d Вывод отладочной информации -e Приоритет переменным окружения. Если у нас установлена переменная окружения CC и в Makefile есть переменная с таким же именем, то будет использована переменная окружения -f файл Использовать указанный файл вместо Makefile -i Игнорировать ошибки компилятора -I каталог В указанном каталоге будет производиться поиск файлов, включаемых в Makefile -j n Запускать не более n команд одновременно -k Продолжить работу после ошибки, если это возможно -n Вывести команды, которые должны были выполниться, но не выполнять их -о файл Пропустить данный файл, даже если в Makefile указано, что он должен быть создан заново -r Не использовать встроенные правила -s Не выводить команды перед их выполнением -w Вывод текущего каталога до и после выполнения команды

Данный текст является ознакомительным фрагментом.

Продолжение на ЛитРес

Установка Make-3.79.1

Установка Make-3.79.1 Приблизительное время компиляции: 0.22 SBU Необходимое дисковое пространство: 6 MBИнсталляция MakeДля инсталляции Make выполните:./configure –prefix=/usr &amp;&amp; make &amp;&amp; make install &amp;&amp; chgrp root /usr/bin/make &amp;&amp; chmod 755 /usr/bin/makeПояснения командПо умолчанию, /usr/bin/make принадлежит к той

15.4. Утилита make : автоматизация процедур

15.4. Утилита make: автоматизация процедур Сами по себе исходные коды программ не делают приложения. Также важен способ их компоновки и упаковки для распространения. Операционная система Unix предоставляет инструментальное средство для частичной автоматизации данных

15.4.2. Утилита make в разработке не на C/C++

15.4.2. Утилита make в разработке не на C/C++ Программа make может оказаться полезной не только для программ на C/C++. Языки сценариев, подобные описанным в главе 14, могут не требовать традиционных этапов компиляции и компоновки, однако часто существуют другие виды зависимостей, с

15.4.3. Правила make

15.4.3. Правила make Некоторые из наиболее интенсивно используемых правил в типичных make-файлах вообще не выражают зависимостей. Они позволяют связать небольшие процедуры, которые разработчик хочет механизировать, например, создание дистрибутивного пакета или удаление всех

15.4.4.2. I make

15.4.4.2. Imake Утилита Imake была написана в попытке автоматизировать создание make-файлов для системы X Window. Она надстраивается на makedepend для решения как проблемы вывода зависимостей, так и проблемы переносимости.Imake-система эффективно заменяет традиционные make-файлы 1make-файлами,

15.8.1. Emacs и make

15.4. Утилита make : автоматизация процедур

15.4. Утилита make: автоматизация процедур Сами по себе исходные коды программ не делают приложения. Также важен способ их компоновки и упаковки для распространения. Операционная система Unix предоставляет инструментальное средство для частичной автоматизации данных

15.4.1. Базовая теория make

15.4.1. Базовая теория make При разработке программ на языках С или С++ важной частью для построения приложения является семейство команд компиляции и компоновки, необходимых для получения из файлов исходного кода работающих бинарных файлов. Ввод данных команд — длительная и

15.4.2. Утилита make в разработке не на C/C++

15.4.2. Утилита make в разработке не на C/C++ Программа make может оказаться полезной не только для программ на C/C++. Языки сценариев, подобные описанным в главе 14, могут не требовать традиционных этапов компиляции и компоновки, однако часто существуют другие виды зависимостей, с

15.4.3. Правила make

15.4.3. Правила make Некоторые из наиболее интенсивно используемых правил в типичных make-файлах вообще не выражают зависимостей. Они позволяют связать небольшие процедуры, которые разработчик хочет механизировать, например, создание дистрибутивного пакета или удаление всех

15.8.1. Emacs и make

1.14. Получение GNU make

1.14. Получение GNU make ПроблемаВы хотите получить и установить утилиту GNU make, используемую для сборки библиотек и исполняемых файлов из исходного кода.РешениеРешение зависит от вашей операционной системы.WindowsХотя в некоторых источниках можно получить готовые бинарные

Читайте также: