web-dev-qa-db-ja.com

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)'

それはどういう意味ですか、一時ファイルを使用せずに2つの出力を比較する方法はありますか?

11
Johannes

_/bin/sh_はシステム上でbashになる可能性がありますが、shとして呼び出されると、bashはPOSIXモードで実行されます(_POSIXLY_CORRECT_が定義されている場合と同様) 、または_--posix_)で開始されました。

このモードでは、プロセス置換は存在しません。

ソリューション:

_all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2
_

代替:

_all:
    bash -c "diff <(command1) <(command2)"
_

または、Makefile変数Shellを_/bin/bash_として定義します。

_Shell=/bin/bash
_

移植性が必要な場合は、最初のソリューションを使用してください。 bashへの依存に問題がない場合は、2番目を選択します。さらに、GNU以外のmake実装について気にする必要がない場合は、3番目の実装を使用します。


Shellの設定について:POSIX標準では、Makefileの実行可能ファイルはsystem() Cライブラリ関数を使用してmakeで呼び出す必要があると述べています。この関数はShell環境変数の使用を保証していません(実際、標準では使用しないことをお勧めします)。規格は、Makefile変数Shellを設定しても、環境変数Shellに影響を与えてはならない、と言っています。 。ただし、私が知っているmakeのほとんどの実装では、Makefile変数Shellを使用してコマンドを実行します。

makeユーティリティの根拠 での提案は、_bash -c_を使用することです。

歴史的なMAKESHELL機能、および他のmake実装によって提供される関連機能は省略されました。一部の実装では、makeコマンドの実行に使用されるシェルをユーザーがオーバーライドできるようにするために使用されます。これは混乱を招きました。ポータブルmakeの場合、シェルはmakefileライターが選択する必要があります。さらに、Makefileライターは、代替シェルを使用するように要求することはできませんが、Makefileを移植可能と見なします。代替シェルを指定するためのメカニズムを標準化することは可能ですが、既存の実装はそのようなメカニズムに同意しておらず、メイクファイル作成者はターゲットのルールでシェル名を指定することですでに代替シェルを呼び出すことができます。例えば:

_python -c "foo"_

20
Kusalananda