Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to add a dependency to another Makefile?

Tags:

makefile

I'm not asking if it is possible to call Makefile from another Makefile.

Suppose I have a rule for generating an executable which looks like this:

my-prog: some.o local.o dependencies.o

Note that I'm exploiting built-in rules here.

Now suppose I start using a third-party library. I'd like to keep this built-in syntax and just add the external rule to the dependency list:

my-prog: some.o local.o dependencies.o somelib/libsomelib.a

But that won't work:

No rule to make target 'somelib/libsomelib.a', needed by 'my-prog'.

I know that I can solve this issue by calling explicitly the other Makefile:

my-prog: some.o local.o dependencies.o
    $(MAKE) -C somelib/ libsomelib.a
    $(CC) $(LDFLAGS) -o $@ $^ somelib/libsomelib.a

But that's what I'm trying to avoid. Any ideas?

like image 695
cYrus Avatar asked Jan 11 '15 11:01

cYrus


1 Answers

In select cases it might be possible to just include the other Makefile, but in those cases they could likely have been written as one in the first place, so...failing that, the best you can do to make the dependency tracking work is to extend the recursive make approach -- your own makefile can't track the dependencies of somelib/libsomelib.a, so you will have to ask the other Makefile to do it for you every time. I'm afraid there's no way around that.

You can, however, enable yourself to keep using the implicit rules and shift the dependency tracking of foreign libs to the other makefile. I'm thinking along the lines of phony targets for these foreign builds like so:

somelib/libsomelib.a:
  $(MAKE) -C somelib/ libsomelib.a

# This target needs to be phony so it is run every time because only the other
# makefile can determine that there's nothing to be done.
.PHONY: somelib/libsomelib.a

# then you can use it as a dependency just like locally built targets
my-prog: some.o local.o dependencies.o somelib/libsomelib.a

This can be extended to multiple foreign targets like this:

# list foreign targets here
FOREIGN_TARGETS = \
  somelib/libsomelib.a \
  foo/libfoo.a \
  bar/libbar.a

$(FOREIGN_TARGETS):
        # split the target into directory and file path. This assumes that all
        # targets directory/filename are built with $(MAKE) -C directory filename
        $(MAKE) -C $(dir $@) $(notdir $@)

.PHONY: $(FOREIGN_TARGETS)
like image 122
Wintermute Avatar answered Nov 28 '22 10:11

Wintermute