Я хочу добавить пару строк, чтобы процесс make мог выдать ошибку, если определенный каталог (установленный переменной Makefile DIR1) не существует. Вот добавленная часть, но это ошибка, даже если каталог, установленный DIR1, существует. Например, я создал каталог с именем «dir1», но выдал ошибки. Что не так?
DIR1 = dir1
.PHONY : check_dir
$(info DIR1 = $(DIR1))
check_dir:
if [ ! -d $(DIR1) ]; then \
$(error "DIR1 does not exist! check Makefile!"); \
fi
Это результат запуска (у меня есть каталог с именем dir1
в текущем каталоге).
> ckim@chan-ubuntu:~/testmake/test1$ make
> DIR1 = dir1 Makefile:8:
> *** "DIR1 does not exist! check Makefile!". Stop.
$(error ...)
систематически расширяется make перед передачей рецепта в оболочку. Таким образом, ошибка возникает каждый раз, когда запускается этот рецепт, независимо от результата вашего оператора оболочки if
.
Используйте только конструкции оболочки:
check_dir:
if [ ! -d "$(DIR1)" ]; then \
echo "$(DIR1) does not exist! check Makefile!"; \
exit 1; \
fi
Или (немного компактнее, если не проще для понимания):
MESSAGE := $(DIR1) does not exist! check Makefile!
check_dir:
@[ -d "$(DIR1)" ] || { echo "$(MESSAGE)"; exit 1; }
Есть и другие возможности, такие как:
check_dir: $(DIR1)
$(DIR1):
$(error $(DIR1) does not exist! check Makefile!)
Но это не делает разницы между файлом с именем $(DIR1)
и каталогом.
Примечание: если вы хотите вызвать ошибку, когда make анализирует Makefile и обнаруживает, что каталог не существует, вы можете использовать функцию shell
и условие make:
OK := $(shell if [ -d $(DIR1) ]; then echo "ok"; fi)
ifeq ($(OK),)
$(error $(DIR1) does not exist! check Makefile!)
endif
Ваше первое предложение дает мне: ckim@chan-ubuntu:~/testmake/test1$ make DIR1 = dir1 if [ ! -d каталог1]; then \ echo "dir1 не существует! Проверьте Makefile!"); \ выход 1; \ fi /bin/sh: 2: Синтаксическая ошибка: ")" неожиданное (ожидание "fi") Makefile:7: рецепт для цели 'check_dir' не удалось сделать: *** [check_dir] Ошибка 2. возможно, поместить выход внутрь, если ~ фи не работает? Извините, а можете сами? (если есть свободное время)
Внутри рецепта, очевидно, это можно упростить до [ -d "$(DIR1") ]
(обратите внимание также на Когда заключать в кавычки переменную оболочки)
Рено, и ваше второе предложение дает мне : make: 'dir1' обновлен.
Рено, третий метод точно работает. Я думаю, что if [ -d .. ]
предназначен только для bash, а не для Makefile. (Где-то я видел на SO, что это похоже и на Makefile.. Хм..) Спасибо!
@ChanKim Извините за хвост )
в конце echo...
в моем первом предложении. Это была опечатка, которую я только что исправил.
@ChanKim Со вторым решением, которое я предлагаю, если $(DIR1)
существует, вы получите make: 'dir1' is up to date
, потому что make говорит вам, что для dir1
ничего не поделаешь. Это нормально. Только если он не существует, вы получите ошибку.
@ChanKim Третье решение использует стандартную встроенную оболочку test
([ -d ... ]
) и работает с оболочкой по умолчанию, используемой make (оболочкой Bourne). Он должен работать с любым вариантом оболочки bourne (ksh, bash, zsh...)
@tripleee Да, вы правы насчет цитат, конечно. Я исправил это, спасибо. Но предложенное вами упрощение ([ -d "$(DIR1") ]
) не будет печатать сообщение об ошибке. Так что это должно быть [ -d "$(DIR1") ] || echo ...
в любом случае. Но тогда рецепт не подвел бы, и нам нужно было бы добавить что-то еще. Не уверен, что это легче понять для начинающих. Предложу как альтернативу.
Что я часто делаю, так это добавляю комментарий над чеком, чтобы в расшифровке было ясно видно, что не удалось. Заставлять make
печатать дополнительную диагностику редко стоит затраченных усилий.
ой извините, что если часть не была предпосылкой. он был поднят на верхнюю строку редактором stackoverflow. я исправлю это.