Замена процессов в GNU Makefiles

Замена процессов в GNU Makefiles

В командной строке bash можно выполнить diff, используя псевдофайлы:

diff <(echo test) <(echo test)

Добавление этого в Makefile в исходном виде не удается:

all:
        diff <(echo test) <(echo test)

Ошибка (подсказка: /bin/sh указывает на /bin/bash в этой системе):

/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'

Что это значит, и есть ли способ сравнить два вывода без использования временных файлов?

решение1

/bin/shможет быть bashв вашей системе, но при вызове как shбудет bashработать в режиме POSIX (как если бы POSIXLY_CORRECTбыл определен или запущен с помощью --posix).

В этом режиме замены процессов не существует.

Решения:

  1. Используйте явные временные файлы:

    all:
        command1 >tmpfile
        command2 | diff tmpfile -
        rm -f tmpfile
    
  2. Используйте bash -cвстроенный скрипт:

    all:
        bash -c 'diff <(command1) <(command2)'
    
  3. Определите переменную Makefile SHELLследующим образом /bin/bash(или укажите путь к ней bashв вашей системе):

    SHELL=/bin/bash
    

Если вам нужна переносимость, используйте первое решение. Если вас устраивает зависимость от bash, выберите второе. Если вам, кроме того, не нужно беспокоиться о makeреализациях, отличных от GNU, используйте третье.


Относительно настройки SHELL: Стандарт POSIX гласит, что исполняемые файлы в Makefiles должны вызываться с помощью system()функции библиотеки C с помощью make. Эта функция не гарантирует использование SHELLпеременной окружения (фактически, это не рекомендуется стандартом). Стандарт также идет на некоторые уступки, чтобы сказать, что настройка переменной Makefile SHELLне должна влиять напеременная окружения SHELLmake. Однако в большинстве известных мне реализаций SHELLдля выполнения команд будет использоваться переменная Makefile.

Предложение вОбоснование makeполезностизаключается в использовании bash -c:

Историческая MAKESHELLфункция и связанные с ней функции, предоставляемые другими makeреализациями, были опущены. В некоторых реализациях она используется для того, чтобы позволить пользователю переопределить оболочку, используемую для запуска makeкоманд. Это сбивало с толку; для переносимого makeоболочка должна быть выбрана автором makefile. Кроме того, автор makefile не может требовать использования альтернативной оболочки и при этом считать makefile переносимым. Хотя можно было бы стандартизировать механизм указания альтернативной оболочки, существующие реализации не согласны с таким механизмом, и авторы makefile уже могут вызывать альтернативную оболочку, указывая имя оболочки в правиле для цели; например:

python -c "foo"

Связанный контент