Как построить make зависимость, когда целевое имя не является именем файла - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь написать очень простой Makefile, который я не могу заставить работать так, как я ожидаю.

target_a : file.txt
       echo "this is target_a"
       touch 0_$@
target_b : 0_target_a
       echo "executing target_b"
       touch 0_$@

Всякий раз, когда я запускаю make taget_b, выдается ошибка:

make: *** No rule to make target '0_target_a', needed by 'target_b'.  Stop.

Я могу просто изменить touch 0_$@ на touch $@. Но я действительно хочу решение для touch 0_$@ (свободный выбор имени файла).

со страницы руководства GNU ftp: //ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_2.html

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

Я хочу знать, как построить зависимость Make, если целевым именем является:

Действие

Ответы [ 2 ]

0 голосов
/ 18 января 2019

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

0_target_a: file.txt
        echo "this is target_a"
        touch $@

target_b: 0_target_a
        echo "executing target_b"
        touch 0_$@

т.е. определение правила для цели 0_target_a и обновление touch соответственно даст вам поведение, которое вы хотели, так как make теперь понимает правило, связывающее цель и файл 0_target_a, и знает, когда его не нужно переделывать как зависимость target_b. Теперь, если вы все еще хотите иметь автономный target_a, который бы генерировал файл 0_target_a, вы можете определить его следующим образом:

target_a: 0_target_a

Поскольку мы знаем, что эта цель на самом деле не создает сам файл, мы можем приложить немного усилий, чтобы найти его результат (target_a), а также предотвратить конфликты, если такой файл будет создан, объявив его фальшивым.

На самом деле вы можете захотеть дать вашему target_b такое же лечение, как и в противном случае (опять же, make не обладает достаточной информацией, чтобы понять связь между target_b и 0_target_b) make target_b всегда переделывается даже если файл уже создан.

Весь файл make будет выглядеть так:

.PHONY: target_a target_b
target_a: 0_target_a
target_b: 0_target_b

0_target_a: file.txt
    echo "this is target_a"
    touch $@

0_target_b: 0_target_a
    echo "executing target_b"
    touch $@

Если это повторяющаяся тема по всему файлу, вы также можете выразить отношение во второй и третьей строке, задав правило статического шаблона:

target_a target_b: %:  0_%

Это определяет правило, согласно которому любая цель (первый «%» без чего-либо еще) имеет обязательное условие префикса 0_, за которым следует имя цели (0_%, 0_ плюс ствол, который в данном случае является целью название полностью соответствует предыдущему %). и делает это правило применимым к целям target_a и target_a. Это правило не имеет рецепта и, следовательно, описывает только целевые / обязательные отношения между ними.

Другими словами, это означает то же самое, что и строки 2 и 3 полного примера.

0 голосов
/ 18 января 2019

Зависимость target_b должна быть самой действительной целью или файлом, который уже существует

target_a : file.txt
       echo "this is target_a"
       touch 0_$@
target_b : target_a
       echo "executing target_b"
       touch 0_$@

Если вы хотите создать псевдоним файла 0_target_a для действия target_a, вы можете добавить промежуточное правило:

0_target_a : file.txt
       echo "creating 0_target_a"
       touch 0_$@

target_a : 0_target_a

target_b : target_a
       echo "executing target_b"
       touch 0_$@
...