Makefile: ファイルの存在チェックが一貫していません

Makefile: ファイルの存在チェックが一貫していません
check: gen
#       ls -ltr file_name*
ifeq ($(shell test -s file_name && echo -n yes),yes)
        Do something with file_name and file_name1
else
       Do something else with file_name1
endif

# Will generate file_name and file_name1. Depending on the implementation , file_name can be empty sometimes.
gen: 
        <some command to generate file_name and file_name1>

clean:
        -rm -rf file_name*

make checkなしでを実行するとmake clean、 はmake check常に「Hello exists」を返します。

を実行しmake cleanてから を実行してもmake check、「Hello exists」は返されません。

注: どちらの場合も、ls -ltrin はgen空でないファイル print を返します。

答え1

ifeq ($(shell test -e file_name && echo -n yes),yes)

は、コマンドが実行されるときではなく、Make が Makefile を読み取るときに評価されます。したがって、file_nameMakefile が読み込まれるときに が存在する場合、checkターゲットは を実行しecho "Hello exists"、そうでない場合は を実行しません。

Makefile は、できる限りファイルの観点から記述する必要があります。この場合、と がcheck必要なので、それを指定する必要があります。file_namefile_name1

check: file_name file_name1
        <run your checks>

file_name file_name1:
        <some command to generate file_name and file_name1>

clean:
        rm -f file_name file_name1

チェック自体は、ファイルのテストを含め、シェルで実行できる任意のコマンドで実行できますが、Makefileの処理中に変化する基準に基づいてMakefileの一部を条件付きにすることはできません(少なくとも、簡単にはできません)。あなたの場合は、次のようにすることができます。

check: file_name file_name1
        test -s file_name && <do something with both files>
        ! test -s file_name && <do something with only file_name1>

または、より明示的には、単一のシェル呼び出しで実行する必要があるため、エスケープを使用します。

check: file_name file_name1
        if [ -s file_name ]; then \
            <do something with both files> \
        else \
            <do something with file_name1> \
        fi

関連情報