Не знаю, какую неудачу вы видите, но я боюсь, что для вас это не самый лучший способ. Файлы .o
и исполняемый файл ($(OUTPUT)
) являются отдельными правилами. Если последнее не помогает, первое уже не рассматривается. См. документацию :
.DELETE_ON_ERROR:
Если .DELETE_ON_ERROR
упоминается как цель в любом месте в make-файле, тогда make
удалит цель правила, если оно изменилось, и его рецепт завершится с ненулевым статусом выхода, так же, как и при получении сигнала. См. Ошибки в рецептах .
Другими словами, если ваша цель, создающая двоичный объект, потерпела неудачу после того, как .o
сама цель была обновлена, make удалил измененный файл. Но если ваш исполняемый файл не связывался, он не вернется и не удалит объектные файлы.
Не уверен, что это было бы неплохо, но если бы вам действительно это было нужно, вы, вероятно, могли бы добиться этого путем рефакторинга вашего make-файла, чтобы в основном иметь прямое exec + objs из правила исходных условий с одним рецептом. Очевидный недостаток: такое правило будет означать, что изменение файла .c
приведет к перекомпиляции всех файлов (что в основном сводит на нет существенные преимущества использования make
).
РЕДАКТИРОВАТЬ: Я немного расширю комментарий, чтобы уточнить. Похоже, что вам нужно: если поврежденный файл .c
завершился неудачно, удалите старый файл .o
. Это совершенно не совсем так, как работает .DELETE_ON_ERROR
. Если файл .o
уже обновлен, а затем правило не выполнено, он удалит его ( "удалит цель правила, если оно изменилось" ), но в случае упомянутой синтаксической проблемы, компилятор потерпит неудачу, прежде чем он создаст файл .o
.
Итак, если, например, вы обновили правило (шаблон) для компиляции, чтобы оно сначала touch
es (эффективно обновляет временную метку) в файле .o
, а затем попыталось скомпилировать. После сбоя вызова компилятора и правила make сочтет, что цель поврежденного корня была обновлена, и удалит ее. В качестве альтернативы вы также можете изменить правило, чтобы сначала попытаться rm
ожидаемый файл '.o', в этом случае вам на самом деле не нужно будет использовать .DELETE_ON_ERROR
(и если в соответствующих источниках нет изменений, правило делает не привыкать, так что на самом деле это не так страшно, как кажется). В любом случае это не совсем чисто, но ведет к поведению, которое, как я понимаю, вы описываете.