Mahashi
Mahashi

Reputation: 119

Makefile directory rule dependency rebuild

I got Makefile like this

all: sub-dir my-rule

sub-dir:
    $(MAKE) -C $@

my-rule: sub-dir
    g++ main.cpp

.PHONY sub-dir

So basically I want to wait for sub-dir to finish before building my-rule but my-rule is rebuilt everytime - even if there where no changes in sub-dir.

How can I make it to wait for sub-dir and rebuild my-rule only when there were changes in sub-dir?

Upvotes: 1

Views: 1698

Answers (1)

MadScientist
MadScientist

Reputation: 100926

When you write a rule like:

my-rule: sub-dir

the target (my-rule) will be rebuilt if the prerequisite (sub-dir) is newer. Make doesn't care whether the target or prerequisite are files are directories, only what their last modified time is.

Your makefile has many issues. The simplest one is that you never create a target my-rule, so as far as make is concerned that target is always out of date (non-existent == out of date).

You have to write your rule like this so that the recipe updates the target:

my-rule: sub-dir
        g++ main.cpp -o $@

Of course change my-rule if that's not the program you want to create.

Second, directory modification times are updated when the directory changes. The directory changes when something in that directory is renamed, added, or removed. So if you invoke the sub-make and the sub-make renames, adds, or removes something in that directory then the my-rule target will be out of date. If nothing is renamed, added, or removed, then my-rule will NOT be out of date.

In general you almost never want to list a directory as a prerequisite. Instead, you should list the targets that the sub-make creates as the prerequisite, like this (supposing the sub-make creates libfoo.):

sub-dir/libfoo.a: FORCE
        $(MAKE) -C $(@D)
FORCE:

my-rule: sub-dir/libfoo.a
        ...

The FORCE rule is there to force the sub-make to be invoked even if sub-dir/libfoo.a already exists.

Upvotes: 4

Related Questions