11

makefile内のmetafileというファイルを読みたい。

メタファイルは次のようになります:
file1
file2
file3

makefile内のこのメタファイルを1行ずつ読み取り、内部に記載されているファイルが存在するかどうかを確認し、存在するファイルの名前のみを出力する必要があります。

私は成功せずにいくつかのことを試みました。お気に入り:

FILE=`cat metafile`
for line in $(FILE); if [ -e $${line} ]; then echo $${line} fi; done;
4

1 に答える 1

17

ターゲットに任意のシェルスクリプトを配置できます。他の理由で他のターゲットのデータも必要でない限り、ファイルの内容をMakefile変数に保持することは私には意味がありません。(そうであれば、とにかくバックティックを使用することはできません。)

target:
        @while read -r file; do \
            test -e "$$file" && echo "$$file"; \
        done <metafile

価値のあることとして、ループは、バックティックを使用したループwhileよりも、シェルスクリプト内のファイルの行をループするための、より安全で慣用的な方法です。for

@Makeがシェルスクリプトコマンドをエコーし​​ないようにします。何らかの理由でそれらを見る必要がある場合は、それを取り出してください。実際、特にデバッグ中は、これを使用しないことをお勧めします。レシピが正しく機能することを確認したら、サイレントに実行するために使用make -sします。make

Makefileでこれを行うためのより慣用的な方法は、ターゲットをこれらのファイルに依存させ、Make独自のロジックを使用することです。

target: file1 file2 file3
        @echo $(filter-out $?,$^)

これはGNUMake構文です。他のMakeフレーバーに移植できるようにしたい場合は、さらに複雑になる可能性があります(結局、シェルスクリプトが望ましい場合があります)。すべてを1行にエコーしますが、別の行が必要な場合は、簡単に修正できます。

小さな補助Makefileスニペットを作成し、依存関係を含めるだけです。

target: target.d
target.d: metafile
        sed 's/^/target: /' $< >$@
include target.d

target:これにより、依存関係の小さなリストが作成されるため、依存関係に明示的にリストする必要はありません。file1 file2 file3したがって、上記のレシピの代わりに、依存関係は生成さtarget.dれたものに存在します。

target: file1
target: file2
target: file3

への依存関係を除外する必要がありますtarget.d(または宣言しないでおく必要があります。GNUMakeが対応する必要があると思います)。

于 2012-11-28T21:12:30.877 に答える