Как проверить, не существует ли каталог в Makefile? если [ ! -d ... ] всегда возвращает истину

Я хочу добавить пару строк, чтобы процесс 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.
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
2 953
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

$(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

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

Chan Kim 14.12.2020 06:57

Ваше первое предложение дает мне: 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. возможно, поместить выход внутрь, если ~ фи не работает? Извините, а можете сами? (если есть свободное время)

Chan Kim 14.12.2020 07:18

Внутри рецепта, очевидно, это можно упростить до [ -d "$(DIR1") ] (обратите внимание также на Когда заключать в кавычки переменную оболочки)

tripleee 14.12.2020 07:20

Рено, и ваше второе предложение дает мне : make: 'dir1' обновлен.

Chan Kim 14.12.2020 07:23

Рено, третий метод точно работает. Я думаю, что if [ -d .. ] предназначен только для bash, а не для Makefile. (Где-то я видел на SO, что это похоже и на Makefile.. Хм..) Спасибо!

Chan Kim 14.12.2020 07:28

@ChanKim Извините за хвост ) в конце echo... в моем первом предложении. Это была опечатка, которую я только что исправил.

Renaud Pacalet 14.12.2020 09:31

@ChanKim Со вторым решением, которое я предлагаю, если $(DIR1) существует, вы получите make: 'dir1' is up to date, потому что make говорит вам, что для dir1 ничего не поделаешь. Это нормально. Только если он не существует, вы получите ошибку.

Renaud Pacalet 14.12.2020 09:34

@ChanKim Третье решение использует стандартную встроенную оболочку test ([ -d ... ]) и работает с оболочкой по умолчанию, используемой make (оболочкой Bourne). Он должен работать с любым вариантом оболочки bourne (ksh, bash, zsh...)

Renaud Pacalet 14.12.2020 09:35

@tripleee Да, вы правы насчет цитат, конечно. Я исправил это, спасибо. Но предложенное вами упрощение ([ -d "$(DIR1") ]) не будет печатать сообщение об ошибке. Так что это должно быть [ -d "$(DIR1") ] || echo ... в любом случае. Но тогда рецепт не подвел бы, и нам нужно было бы добавить что-то еще. Не уверен, что это легче понять для начинающих. Предложу как альтернативу.

Renaud Pacalet 14.12.2020 09:42

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

tripleee 14.12.2020 09:45

Другие вопросы по теме