문제

I currently try to write a Makefile that build properly a project which contains a git submodule. This submodule have its own set of makefiles and produce several targets at once, including some libraries.

This Makefile should have the following properties.

  • Don't rebuild twice the submodule even with parallel build.
  • Update the submodule targets when the submodule code has changed (maybe because I navigated through the revisions of the main repository).
  • Re-link the main project when the submodule library have changed.
  • Don't copy-paste the Makefiles of the submodule in the top-level project (i.e. keep the Makefiles recursive).

Just to set the ideas, here is something that seems to work.

FOO_SUBDIR := $(CURDIR)/foo
LDFLAGS := -L$(FOO_SUBDIR)

FOO_LIBSFILES := $(FOO_SUBDIR)/libfoo.a $(FOO_SUBDIR)/libgnufoo.a
FOO_LDLIBS := -lfoo -lgnufoo


.PHONY: all
all: main

# There are theoretically 3 main binaries
main: main.c $(FOO_LIBSFILES)
    gcc -o $@ $< $(LDFLAGS) $(FOO_LDLIBS)

$(FOO_LIBSFILES): libfoo
    @# Do nothing

.PHONY: libfoo
libfoo:
    $(MAKE) -C $(FOO_SUBDIR)

It seems to work sice I added the empty recipe, but I don't understand why.

The idea is to always rely on the submodule's Makefile to rebuild (or not) libfoo.a and libgnufoo.a, and let the main Makefile decide whether main need to be rebuilt. Without the empty recipe it doesn't work. When a foo/foo.c is modified, then libfoo.a is rebuilt, but make doesn't rebuild main.

I have the feeling that the empty recipe force make to check the date of the target files. But I can't find documentation about this behavior.

Is this the right way to go? Any pitfall I should be aware of? Any less obscure way to do this? Or any documentation about this behavior?

Thanks in advance.

도움이 되었습니까?

해결책

Your solution is correct in general - in your toplevel makefile you've added targets that works the subproject. It is the only proper way to work with a standalone (sub-)project, via its own makefile.

The specific problem you are asking about has to do with not terminating the libfoo dependent rule, and GNU make requires a rule to have commands, even if it is a no-op. Do this instead:

$(FOO_LIBSFILES): libfoo ; 

This is effectively the same no-op, but more idiomatic.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top