Итак, я последовал за документом Advanced Auto-Dependency Generation -
Makefile:
SRCS := main.c foo.c
main: main.o foo.o
%.o: %.c
$(CC) -MMD -MG -MT '[email protected] $*.d' -c $< -o [email protected]
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
становится сгенерированным файлом -
Makefile:
...
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.
Итак, мой вопрос: Есть ли способ продлить рецепт, предложенный выше, чтобы разрешить сгенерированные файлы заголовков, без снижения производительности, достигнутой благодаря не переучитывать весь make дерево при включении фрагментов *.d
?