Roger Leigh wrote: | In a project, I am preprocessing the C++ source and headers. That is: | foo.ccg -> foo.cc | foo.hg -> foo.h | | Some custom m4 I wrote processes the files with some simple rules: | | $(top_builddir)/build/classgen.m4f: $(top_srcdir)/build/classgen.m4 | $(M4) -P -F $@ $^
$^ is not portable. Please forgive me if you are assuming GNU Make, but as Automake strives to produce portable Makefiles and many people unconsciously break this portability when writing custom rules, I don't want someone who read the archives to blindingly copy the above... | | %.cc: %.ccg $(top_builddir)/build/classgen.m4f | $(M4) -P -R $(top_builddir)/build/classgen.m4f $< > $@ | | %.h: %.hg $(top_builddir)/build/classgen.m4f | $(M4) -P -R $(top_builddir)/build/classgen.m4f $< > $@ %-rules are not portable either; you need to use POSIX inference rules if you want some magic help from Automake (see last paragraph). | Now the complex part ;-) | | If I have, in my Makefile.am: | | lib_LTLIBRARIES = libfoo.la | | libfoo_la_pre_sources = \ | foo.ccg \ | foo.hg \ | | libfoo_la_post_sources = \ | $(addsuffix .cc,$(basename $(filter %.ccg,$(libfoo_la_pre_sources)))) \ | $(addsuffix .h,$(basename $(filter %.hg,$(libfoo_la_pre_sources)))) In POSIX words: libfoo_la_post_sources = $(libfoo_la_pre_sources:g=) | libfoo_la_SOURCES = \ | $(libfoo_la_pre_sources) \ | $(libfoo_la_post_sources) \ | bar.cc \ | bar.h \ | | If I touch foo.ccg, foo.cc is regenerated and foo.lo rebuilt. | However, if I touch foo.hg, foo.h is not rebuilt, which is causing | problems (I need to do a manual "make foo.h" every time I alter | foo.hg). One issue with this setup is that foo.h doesn't exist the first time you try to compile the *.cc files that include it, and as dependency information is not available yet make won't help. Hence you have type `make foo.h'. On the following runs, however, dependency information is there, so I'd expect foo.h to be rebuilt before anything that depends on it is compiled. It doesn't exactly correspond to you description, so maybe I'm missing something. The `Built sources' section of the manual discusses the above problem at lengths, and offer several solutions. The more common is to use BUILT_SOURCES. | How should I make this automatic? I thought the above rules | would be sufficient, but it does not appear so. Here is a suggestion. lib_LTLIBRARIES = libfoo.la libfoo_la_pre_headers = foo.hg ... libfoo_la_pre_sources = foo.ccg ... $(libfoo_la_pre_headers) libfoo_la_SOURCES = \ $(libfoo_la_pre_sources) \ bar.cc \ bar.h BUILT_SOURCES = $(libfoo_la_pre_headers:g=) # I'm assuming you don't want to distribute those: CLEANFILES = $(libfoo_la_pre_sources:g=) $(top_builddir)/build/classgen.m4f: $(top_srcdir)/build/classgen.m4 $(M4) -P -F $@ $(top_srcdir)/build/classgen.m4 # All preprocessed files need classgen.m4f to be built. $(libfoo_la_pre_sources:g=): $(top_builddir)/build/classgen.m4f .ccg.cc: $(M4) -P -R $(top_builddir)/build/classgen.m4f $< >$@ .hg.h: $(M4) -P -R $(top_builddir)/build/classgen.m4f $< >$@ When you use POSIX inference rules, automake can see that those .hg and .ccg will be turned into .h and .cc, and can produce the appropriate rules for them. (It doesn't work with %-rules -- it's difficult enough to try supporting the portable constructs.) Section `Handling new file extensions' of the manual (node `Suffixes') should probably be extended with such an example. -- Alexandre Duret-Lutz