そこで、Advanced Auto-Dependency Generation の論文に従いました --
メイクファイル:
SRCS := main.c foo.c
main: main.o foo.o
%.o: %.c
$(CC) -MMD -MG -MT '$@ $*.d' -c $< -o $@
cp $*.d $*.tmp
sed -e 's;#.*;;' -e 's;^[^:]*: *;;' -e 's; *\\$$;;' \
-e '/^$$/d' -e 's;$$; :;' < $*.tmp >> $*.d
rm $*.tmp
clean::
-rm *.o *.d main
-include $(SRCS:.c=.d)
main.c :
#include "foo.h"
int main(int argc, char** argv) {
foo() ;
return 0 ;
}
foo.h :
#ifndef __FOO_H__
#define __FOO_H__
void foo() ;
#endif
--そして、それは魅力のように機能します。
しかしfoo.h
、生成されたファイルになると -
メイクファイル:
...
HDRS := foo.h
$(HDRS):
mk_header.sh $*
clean::
-rm $(HDRS)
...
mk_header.sh:
#!/bin/bash
UP=$(tr "[:lower:]" "[:upper:]" <<< $1)
cat <<EOF > $1.h
#ifndef __${UP}_H__
#define __${UP}_H__
void $1() ;
#endif
EOF
初めて実行するmake
はmain.d
まだ生成されていないためfoo.h
、前提条件とは見なされず、生成されていません。
$ ls
foo.c main.c Makefile mk_header.sh*
$ make
cc -MMD -MG -MT 'main.o main.d' -c main.c -o main.o
cp main.d main.tmp
sed -e 's;#.*;;' -e 's;^[^:]*: *;;' -e 's; *\\$;;' \
-e '/^$/d' -e 's;$; :;' < main.tmp >> main.d
rm main.tmp
cc -MMD -MG -MT 'foo.o foo.d' -c foo.c -o foo.o
cp foo.d foo.tmp
sed -e 's;#.*;;' -e 's;^[^:]*: *;;' -e 's; *\\$;;' \
-e '/^$/d' -e 's;$; :;' < foo.tmp >> foo.d
rm foo.tmp
cc main.o foo.o -o main
$ ls
foo.c foo.d foo.o
main* main.c main.d main.o
Makefile mk_header.sh*
の 2 回目の呼び出しでのみmake
、foo.h
が生成され、その結果、別のビルドがカスケードされます。
$ make
./mk_header.sh foo
cc -MMD -MG -MT 'main.o main.d' -c main.c -o main.o
cp main.d main.tmp
sed -e 's;#.*;;' -e 's;^[^:]*: *;;' -e 's; *\\$;;' \
-e '/^$/d' -e 's;$; :;' < main.tmp >> main.d
rm main.tmp
cc main.o foo.o -o main
$ ls
foo.c foo.d foo.h foo.o
main* main.c main.d main.o
Makefile mk_header.sh*
そして、その後になって初めて、次のことにmake
気付きます。
$ make
make: `main' is up to date.
私の質問は次のとおりです。フラグメントを含めるときにメイクツリー全体を再評価する必要がないことによって実現されるパフォーマンスの向上を排除することなく、生成されたヘッダーファイルを可能にするために、上記の論文で提案されたレシピを拡張する方法はありますか?*.d