Linux make install is up to date

Как исправить ошибку «make: ‘all’ is up to date» при выполнении команды make в Linux?

Я переименовал свой файл makefile в расширение mk. Я также заменил пробел на табуляцию между «all» и «main» и исправил ошибку «make: ничего не нужно делать для« all »».

CC=gcc PTHREAD=-lpthread CCFLAGS=-w all: main main: $(CC) $(CCFLAGS) -o main main.c LibBMP.c skeleton.c extractor.c $(PTHREAD) clean: rm main test: ./main ../examples/sample.bmp @echo cat output.txt @echo cat final.txt 

Я бы сказал, что ожидаемый результат — открытие файла output.txt.

@dublejin: зачем открываться? make выполняет all , который зависит только от main , который не имеет ничего общего с output.txt .

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

3 ответа

Ничего не нужно делать с ошибкой «все».

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

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

CC=gcc PTHREAD=-lpthread CCFLAGS=-w all: main main: main.c LibBMP.c skeleton.c extractor.c $(CC) $(CCFLAGS) -o main main.c LibBMP.c skeleton.c extractor.c $(PTHREAD) clean: rm main test: main ./main ../examples/sample.bmp @echo cat output.txt @echo cat final.txt 

Это выглядит необычно. Нет переменной с именем CCFLAGS .

Обычно ваш рецепт выглядит примерно так:

CFLAGS = -g -w CCFLAGS = -I. $(CFLAGS) main: $(CC) $(CPPFLAGS) $(CCFLAGS) . 

Использование CFLAGS и CCFLAGS делает две вещи. Во-первых, он предоставляет значение по умолчанию для CFLAGS . Во-вторых, он позволяет пользователю переопределить CFLAGS , предоставляя необходимые параметры через CCFLAGS .

Целевое имя может противоречить имени вашего выходного файла.

Попробуйте добавить это в Makefile:

.PHONY сообщает Make , что цели не связаны с файлами

Если вы хотите, чтобы часть cat output.txt запускалась, вы должны вызвать цель test , например:

Если вы просто выполните make , тогда будет получена цель all , потому что она идет первой в make-файле.

Источник

Что такое Makefile и как начать его использовать

Что такое Makefile и как начать его использовать

В жизни многих разработчиков найдётся история про первый рабочий день с новым проектом. После клонирования основного репозитория проекта наступает этап, когда приходится вводить множество команд с определёнными флагами и в заданной последовательности. Без описания команд, в большинстве случаев, невозможно понять что происходит, например:

# Bash touch ~/.bash_history ufw allow 3035/tcp || echo 'cant configure ufw' ufw allow http || echo 'cant configure ufw' docker run \ -v /root/:/root/ \ -v /etc:/etc \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/tmp:/var/tmp \ -v /tmp:/tmp \ -v $PWD:/app \ --network host \ -w /app \ --env-file .env \ ansible ansible-playbook ansible/development.yml -i ansible/development --limit =localhost -vv grep -qxF 'fs.inotify.max_user_watches=524288' /etc/sysctl.conf || echo fs.inotify.max_user_watches =524288 | tee -a /etc/sysctl.conf || echo 'cant set max_user_watches' && sysctl -p sudo systemctl daemon-reload && sudo systemctl restart docker 

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

Читайте также:  Linux rdp server vnc

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

# Bash make setup make start make test 

Что такое make и Makefile

Makefile — это файл, который хранится вместе с кодом в репозитории. Его обычно помещают в корень проекта. Он выступает и как документация, и как исполняемый код. Мейкфайл скрывает за собой детали реализации и раскладывает «по полочкам» команды, а утилита make запускает их из того мейкфайла, который находится в текущей директории.

Изначально make предназначалась для автоматизации сборки исполняемых программ и библиотек из исходного кода. Она поставлялась по умолчанию в большинство *nix дистрибутивов, что и привело к её широкому распространению и повсеместному использованию. Позже оказалось что данный инструмент удобно использовать и при разработке любых других проектов, потому что процесс в большинстве своём сводится к тем же задачам — автоматизация и сборка приложений.

Применение мейка в проектах стало стандартом для многих разработчиков, включая крупные проекты. Примеры мейкфайла можно найти у таких проектов, как Kubernetes, Babel, Ansible и, конечно же, повсеместно на Хекслете.

Синтаксис Makefile

make запускает цели из Makefile, которые состоят из команд:

# Makefile цель1: # имя цели, поддерживается kebab-case и snake_case команда1 # для отступа используется табуляция, это важная деталь команда2 # команды будут выполняться последовательно и только в случае успеха предыдущей 

Но недостаточно просто начать использовать мейкфайл в проекте. Чтобы получить эффект от его внедрения, понадобится поработать над разделением команд на цели, а целям дать семантически подходящие имена. Поначалу, перенос команд в Makefile может привести к свалке всех команд в одну цель с «размытым» названием:

# Makefile up: # разворачивание и запуск cp -n .env.example .env touch database/database.sqlite composer install npm install php artisan key:generate php artisan migrate --seed heroku local -f Procfile.dev # запуск проекта 

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

# Makefile env-prepare: # создать .env-файл для секретов cp -n .env.example .env sqlite-prepare: # подготовить локальную БД touch database/database.sqlite install: # установить зависимости composer install npm install key: # сгенерировать ключи php artisan key:generate db-prepare: # загрузить данные в БД php artisan migrate --seed start: # запустить приложение heroku local -f Procfile.dev 

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

# Makefile цель1: цель2 # такой синтаксис указывает на зависимость задач — цель1 зависит от цель2 команда2 # команда2 выполнится только в случае успеха команды из цель2 цель2: команда1 

Задачи будут выполняться только в указанной последовательности и только в случае успеха предыдущей задачи. Значит, можно добавить цель setup , чтобы объединить в себе все необходимые действия:

# Makefile setup: env-prepare sqlite-prepare install key db-prepare # можно ссылаться на цели, описанные ниже env-prepare: cp -n .env.example .env sqlite-prepare: touch database/database.sqlite install: composer install npm install key: php artisan key:generate db-prepare: php artisan migrate --seed start: heroku local -f Procfile.dev 

Теперь развернуть и запустить проект достаточно двумя командами:

# Bash make setup # выполнит последовательно: env-prepare sqlite-prepare install key db-prepare make start 

Благодаря проделанной работе Makefile, команды проекта вместе с флагами сведены в Makefile. Он обеспечивает правильный порядок выполнения и не важно, какие при этом задействованы языки и технологии.

Читайте также:  Linux blocking read file

Продвинутое использование

Фальшивая цель

Использование make в проекте однажды может привести к появлению ошибки make: is up to date. , хотя всё написано правильно. Зачастую, её появление связано с наличием каталога или файла, совпадающего с именем цели. Например:

# Makefile test: # цель в мейкфайле php artisan test 
# Bash $ ls Makefile test # в файловой системе находится каталог с именем, как у цели в мейкфайле $ make test # попытка запустить тесты make: `test` is up to date. 

Как уже говорилось ранее, изначально make предназначалась для сборок из исходного кода. Поэтому она ищет каталог или файл с указанным именем, и пытается собрать из него проект. Чтобы изменить это поведение, необходимо в конце мейкфайла добавить .PHONY указатель на цель:

# Makefile test: php artisan test .PHONY: test 
# Bash $ make test ✓ All tests passed ! 

Последовательный запуск команд и игнорирование ошибок

Запуск команд можно производить по одной: make setup , make start , make test или указывать цепочкой через пробел: make setup start test . Последний способ работает как зависимость между задачами, но без описания её в мейкфайле. Сложности могут возникнуть, если одна из команд возвращает ошибку, которую нужно игнорировать. В примерах ранее такой командой было создание .env-файла при разворачивании проекта:

# Makefile env-prepare: cp -n .env.example .env # если файл уже создан, то повторный запуск этой команды вернёт ошибку 

Самый простой ( но не единственный) способ «заглушить» ошибку — это сделать логическое ИЛИ прямо в мейкфайле:

# Makefile env-prepare: cp -n .env.example .env || true # теперь любой исход выполнения команды будет считаться успешным 

Добавлять такие хаки стоит с осторожностью, чтобы не «выстрелить себе в ногу» в более сложных случаях.

Читайте также:  Whatsapp desktop linux rpm

Переменные

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

# Makefile say: echo "Hello, $(HELLO)!" 
# Bash $ make say HELLO=World echo "Hello, World!" Hello, World ! $ make say HELLO=Kitty echo "Hello, Kitty!" Hello, Kitty ! 

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

# Makefile HELLO ?=World # знак вопроса указывает, что переменная опциональна. Значение после присвоения можно не указывать. say: echo "Hello, $(HELLO)!" 
# Bash $ make say echo "Hello, World!" Hello, World ! $ make say HELLO=Kitty echo "Hello, Kitty!" Hello, Kitty ! 

Некоторые переменные в Makefile имеют названия отличные от системных. Например, $PWD называется $CURDIR в мейкфайле:

# Makefile project-env-generate: docker run --rm -e RUNNER_PLAYBOOK =ansible/development.yml \ -v $(CURDIR)/ansible/development :/runner/inventory \ # $(CURDIR) - то же самое, что $PWD в терминале -v $(CURDIR) :/runner/project \ ansible/ansible-runner 

Заключение

В рамках данного гайда было рассказано об основных возможностях Makefile и утилиты make . Более плотное знакомство с данным инструментом откроет множество других его полезных возможностей: условия, циклы, подключение файлов. В компаниях, где имеется множество проектов, написанных разными командами в разное время, мейкфайл станет отличным подспорьем в стандартизации типовых команд: setup start test deploy . .

Возможность описывать в мейкфале последовательно многострочные команды позволяет использовать его как «универсальный клей» между менеджерами языков и другими утилитами. Широкая распространённость этого инструмента и общая простота позволяют внедрить его в свой проект достаточно легко, без необходимости доработок. Но мейкфайл может быть по-настоящему большим и сложным, это можно увидеть на примере реальных проектов:

Дополнительные материалы

Мейкфайлы, использованные при составлении гайда:

Источник

Оцените статью
Adblock
detector