views:

57

answers:

1

For those unfamiliar with IDL (interface description language), it abstracts data description for use across platforms (java, c, c++, etc). My project has dependencies Foo.c, Foo.h, FooHelper.c, and FooHelper.h which are generated from Foo.idl. How do I run an arbitrary command when Foo.idl changes, but still include Foo.c, FooHelper.c, in the build process?

My current attempts add a rule to the Makefile.am -- the hope is that the rule is copied over to the generated Makefile.

I have tried:

Foo.idl : Foo.idl
 ${the_generate_command}

and then added Foo.idl to my_program_SOURCES but it doesn't run the_generate_command when building.

I have had success generating from the IDL with

Foo.c Foo.h FooHelper.h FooHelper.c : Foo.idl
 ${the_generate_command}

But it won't add Foo.c, FooHelper.c to the compile process, so they're never built, just generated by the_generate_command!

All the code (including the idl) is in $PROJECT_DIR/src.

+1  A: 

rq's answer is almost correct, but misses a couple of subtleties. Try this:

bin_PROGRAMS = myprogram
myprogram_SOURCES = Foo.c Foo.h FooHelper.h FooHelper.c $(OTHER_SOURCES)
BUILT_SOURCES = Foo.c Foo.h FooHelper.h FooHelper.c
EXTRA_DIST = Foo.idl
MAINTAINERCLEANFILES = Foo.c Foo.h FooHelper.h FooHelper.c

Foo.c: Foo.idl
    $(THE_GENERATE_COMMAND)

Foo.h FooHelper.h FooHelper.c: Foo.c
    @if test -f $@; then \
        touch $@; \
    else \
## Recover from the removal of $@
        rm -rf $<; \
        $(MAKE) $(AM_MAKEFLAGS) $<; \
    fi

The additional rules to "generate" Foo.h, FooHelper.h and FooHelper.c from Foo.c ensure that parallel builds won't try and run $(THE_GENERATE_COMMAND) twice. It is an idiom detailed in the Automake manual which will work for parallel builds. There is still a little fragility here: if the user removes (say) FooHelper.h and FooHelper.c and starts a parallel make, it may run the $(MAKE) $(AM_MAKEFLAGS) $< recovery part of the rule multiple times in parallel. As the manual says, this race can only going to happen if the user manually mutilates the build tree, and even then it's nothing a make clean; make cannot fix.

The BUILT_SOURCES line ensures that Foo.c, Foo.h, FooHelper.h and FooHelper.c are built before trying to build myprogram (see this section of the Automake manual to see why just adding them to myprog_SOURCES is insufficient). The EXTRA_DIST variable ensures that the .idl file will be captured by make dist (reference).

MAINTAINERCLEANFILES specifies additional files to delete when running make maintainer-clean; this is to comply with the GNU Makefile Standards. See also the variable's description in the Automake manual.

Jack Kelly