реальный путь не работает с вновь созданными файлами

#makefile #gnu-make

#makefile #gnu-make

Вопрос:

 test :
    touch test
    echo $(realpath test)
    echo $(shell realpath test)
    rm test
 

Когда я запускаю make , $(realpath test) возвращает пустую строку, тогда $(shell realpath test) как возвращает ожидаемый результат. Почему это так? Я пробовал использовать .ONESHELL , но это не имеет значения.

Ответ №1:

Во-первых, оболочка realpath и функция GNU make realpath отличаются. Оболочка realpath вернет путь, даже если файл не существует:

 /home/me$ rm -f blahblah
/home/me$ realpath blahblah
/home/me/blahblah
 

Но GNU make realpath вернет пустую строку, если файл не существует.

Итак, почему файл не существует? Потому что make развернет все строки рецепта перед запуском любой строки рецепта.

Это означает, что функции make, такие как $(realpath ...) и $(shell ...) , сначала разворачиваются, перед запуском первой строки recipe ( touch test ) … и поэтому во время их расширения test файл не существует.

В общем случае вы никогда не захотите использовать $(shell ...) функцию make в рецепте, и вы не можете использовать конструкции make для «взаимодействия» с операциями, которые происходят внутри вашего рецепта. Для этого вы должны использовать функции оболочки:

 test :
        touch test;
        echo $(realpath test)
        rm test