Search code examples
cmakefileautotoolscheck-framework

Automake, GNU make, check, and (ignored) pattern rules


I have the following Makefile.am which is supposed to create foo.hdb and foo.cdb from foo.h (via the Python script):

TESTS = check_foo

check_PROGRAMS = check_foo

check_foo_SOURCES = check_foo.c $(top_builddir)/src/isti.h \
    foo.cdb foo.h foo.hdb
check_foo_CFLAGS = @CHECK_CFLAGS@ $(all_includes) -I../../clib/src/
check_foo_LDADD = $(top_builddir)/src/libcorm.la @CHECK_LIBS@ -lsqlite3

%.hdb %.cdb: %.h
    PYTHONPATH=$(top_builddir)/cgen/src python $(top_builddir)/cgen/src/isti/cgen/run.py $<

clean-local:
    rm -f *.hdb *.cdb

However, although make foo.hdb and make foo.cdb work (call the Python code and generates the foo.hdb and foo.cdb files from foo.h), make clean check (or the two separately) does not (missing foo.hdb - no such file) - the pattern rule is not called to generate foo.hdb from foo.h.

In other words: the pattern rule is not being called for the files listed in check_foo_SOURCES.

How can I make this work? The rest of the autotools infrastructure is working fine. From looking at the Makefile I suspect the issue is with how autotools expands the check sources.

This is all on Linux with Gnu make. Here is the Makefile.

[Updated slightly to reflect the help from MadScientist].

Later update

The following Makefile (just make, not autotools) works fine, so the issue seems to be related to autotools and check support.

all: check_foo

CFLAGS=-I../../clib/src
LDFLAGS=-L../../clib/src/.libs

check_foo: check_foo.c foo.h corm_foo.h corm_foo.c
    gcc $(CFLAGS) $(LDFLAGS) $^ -o $@ -lcorm -lsqlite3

corm_%.h corm_%.c: %.h
    PYTHONPATH=../../cgen/src python ../../cgen/src/isti/cgen/run.py $<

clean:
    rm -f corm_*.h corm_*.c
    rm -f *.o

(Note that I've switched from xxx.hdb to corm_xxx.h, etc, so that file extensions remain OK).

More Details

Since it seems to be related to the CHECK macros, this is configure.ac:

AC_INIT([corm], [0.1], [[email protected]])
AC_CONFIG_MACRO_DIR([m4])
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4]) 
AM_INIT_AUTOMAKE([-Wall foreign -Werror])
AC_PROG_CC_C99
AM_PROG_CC_C_O
LT_INIT
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile clib/Makefile clib/src/Makefile clib/tests/Makefile clib/docs/Makefile cgen/Makefile cgen/docs/Makefile example/Makefile example/src/Makefile])
AC_CHECK_PROGS([DOXYGEN], [doxygen], AC_MSG_WARN([Doxygen not found - continuing without Doxygen support]))
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([clib/docs/Doxyfile cgen/docs/Doxyfile])])

SOLUTION

OK, so summarizing the various things below, there were two important issues (once I had fixed file extensions - see the "plain" makefile and fceller's answer), either one of which was sufficient to make things work:

  1. (The handling of) Header files is complicated. Because of auto-dependencies, programatically generated header files break things. The solution is to use BUILT_SOURCES

  2. But (the handling of) .c files is not complicated. So putting the corm_foo.c in front of check_foo.c would trigger the generation of that file. Since that also generates corm_foo.h, everything works (because check_foo.c now can include corm_foo.h).

Also, fceller has some good general points about tidy makefiles and explains why the "plain" makefile works.


Solution

  • You need to tell automake that foo.hdb is a source file that is to be constructed. Add the following to Makefile.am:

    BUILT_SOURCES = foo.hdb