The question as written
In your Makefile.am, you could do something like this:
foo.c: foo.in
FOOPLACE=`./thescript`; $(FOOPLACE) -c -o $@ $<
That has the benefit of not requiring a GNU-ism in what is meant to be portable Makefile code.
The right and hard way
I have prepared a dummy package that uses a tool called mkfoo
. It can use the internal copy or the copy on the host's system.
Let's look first at configure.ac
:
AC_PREREQ([2.67])
AC_INIT([parent], [0], [jack@jackkelly.name])
AM_INIT_AUTOMAKE([foreign])
AC_ARG_WITH([mkfoo],
[AS_HELP_STRING([--with-mkfoo],
[Path to mkfoo, "external", "internal", or "check" @<:@check@:>@])],
[MKFOO=$withval],
[with_mkfoo=check])
AS_IF([test "$with_mkfoo" = check -o "$with_mkfoo" = external],
[AC_PATH_PROG([MKFOO], [mkfoo], [no])])
AS_IF([test "$with_mkfoo" = external -a "$MKFOO" = no],
[AC_MSG_ERROR([External mkfoo demanded, but not found.])])
dnl We conditionally set MKFOO in Makefile.am
AM_SUBST_NOTMAKE([MKFOO])
AM_CONDITIONAL([USE_INTERNAL_MKFOO],
[test "$with_mkfoo" = internal -o "$MKFOO" = no])
AM_COND_IF([USE_INTERNAL_MKFOO], [AC_CONFIG_SUBDIRS([mkfoo])])
AC_CONFIG_FILES([Makefile src/Makefile])
AC_OUTPUT
There are a few things going on here:
- The default behaviour is "check for mkfoo, if it's not there, build and use the bundled copy". Note also that it supports
--with-mkfoo=PATH
(user may have a copy installed in an odd place), --with-mkfoo=internal
(needed for distcheck, where we want to test everything) and --with-mkfoo=external
(a kindness to package maintainers, who don't like bundled subprojects).
AM_SUBST_NOTMAKE([MKFOO])
stops automake
from generating a line of the form MKFOO = @MKFOO@
in Makefile.in
. We need to do that assignment conditionally.
- We set up an automake conditional because we need to do different stuff for internal/external
mkfoo
inside Makefile.am
- We configure the
mkfoo
directory conditionally.
Now, the toplevel Makefile.am
:
if USE_INTERNAL_MKFOO
SUBDIRS = mkfoo
DIST_SUBDIRS = mkfoo
else
SUBDIRS =
DIST_SUBDIRS =
endif
SUBDIRS += src
DIST_SUBDIRS += src
## Need to make sure the internal tools work during distcheck.
DISTCHECK_CONFIGURE_FLAGS = --with-mkfoo=internal
dist-hook:
if ! USE_INTERNAL_MKFOO
cp -fpR $(srcdir)/mkfoo $(distdir)
endif
What's going on here:
- Conditionally recurse into
mkfoo
, and do it before src
, which needs $MKFOO
.
- Because there are times
mkfoo
is not even configured, it might not have a Makefile
. That means we've broken make dist
(and by extension, make distcheck
). So we have to set DIST_SUBDIRS
conditionally as well, and if we don't have mkfoo
configured ensuring that it's distributed becomes our responsibility.
- When we
make distcheck
we want to use the internal copy because it's better to exercise everything in the source tarball.
Now, src/Makefile.am
:
if USE_INTERNAL_MKFOO
MKFOO = $(abs_top_builddir)/mkfoo/mkfoo
else
MKFOO = @MKFOO@
endif
bin_SCRIPTS = foo
CLEANFILES = foo
EXTRA_DIST = foo.in
foo: foo.in
$(MKFOO) < $< > $@
There is nothing shocking here except the conditional assignment of MKFOO
.
src/foo.in
:
I am foo.in!
Now for the subpackage. mkfoo/configure.ac
:
AC_PREREQ([2.67])
AC_INIT([mkfoo], [0], [jack@jackkelly.name])
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
As you can see, nothing special. What about mkfoo/Makefile.am
?
bin_PROGRAMS = mkfoo
mkfoo/mkfoo.c
:
#include <stdio.h>
int main(int argc, char *argv[]) {
puts("Internal mkfoo.");
return 0;
}
Just a dummy test program.