В make-файле имя каталога - это фальшивая цель или "настоящая" цель?

Согласно тому, что я прочитал о make-файлах, фальшивой целью является любая цель, которая не соответствует реальному имени файла. Моя интуиция говорит, что каталог в качестве цели будет рассматриваться так же, как файл.

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

$(EXEC_WITH_PATH): ${OBJ_DIR} $(DPEND) $(OBJS)
    @echo "--------------------------------------------";
    @echo "$(THIS_DIR)  $(MACHINE)";
    @echo "Linking Shared Library";
    @echo "ar -rc $(EXEC_WITH_PATH) INSERT::{OBJS}";
    ar -rc $(EXEC_WITH_PATH)  $(OBJS);
    @echo "--------------------------------------------";


# Make dirs for object code and links
${OBJ_DIR} :
        @if [ ! -d ${OBJ_DIR} ]; then \
                mkdir ${OBJ_DIR};    \
        fi;

Так что в этом случае ${OBJ_DIR}, имя каталога, фальшивая цель или нет?

2 ответа

Решение

Изменить: Это относится только к GNU make - справедливое предположение, учитывая тег "linux".

Ваша цель - настоящая цель, а не ФОНИ. Проблема в том, что выходной каталог обновляется, когда вы помещаете в него цели, так что он всегда новее, чем ваша цель. Это означает, что ваша цель всегда будет построена, потому что она устарела относительно своих зависимостей.

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

Вы указываете это так:

$(EXEC_WITH_PATH): $(DPEND) $(OBJS) | ${OBJ_DIR}
...

Что-нибудь после вертикальной черты является обязательным условием только для заказа.

Теперь вы можете сделать вашу цель OBJ_DIR проще:

${OBJ_DIR} :
        mkdir -p ${OBJ_DIR}

Примечание: я использовал ${OBJ_DIR} синтаксис вместо $(OBJ_DIR) потому что это то, что вы использовали. Предварительные условия только для заказа не зависят от этого синтаксиса.

Это настоящая цель.

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

Разумные ложные цели включают all а также clean - они не соответствуют реальным файлам, но действиям, которые вы хотите сделать с помощью make-файла. Вот как объяснить это, чтобы сделать:

.PHONY: all clean install test

Каталоги являются законными целями правил make-файлов. Вы не должны делать эти фальшивые.

mydir:
     mkdir mydir

Цель.PHONY, конечно, фальшивая.

Документацию GNU можно найти здесь.

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