8

Is it possible to specify a directory as a dependency in a Makefile rule? Actually I have a Makefile in a directory and another directory containing all the source files.

.
.
|_ Makefile
|_ src
    |_a.c
    |_a.h

Now I want that whenever I make any change in the src directory i.e. in either of a.c or a.h , a particular rule in my Makefile get called on issuing make command. Something like

Makefile
.
.
.
build: src
    <commands>

clean:
    <commands>
Ravi Gupta
  • 6,258
  • 17
  • 56
  • 79

2 Answers2

7

While it is possible to have a directory as a dependency, there are a few things to be aware of. Consider this:

directory:
        @mkdir -p directory

directory/file : directory
        commands-to-make-the-file

This will do what you think. However, it executes the commands-to-make-the-file whenever file is older than directory, which may not be what you want.

You need to consider the scenarios where the timestamp of directory gets updated. That happens whenever files are added into or removed from the directory but it doesn't happen when an existing file is modified.

So, some unrelated action that updates the directory will cause the file to become out of date, perhaps needlessly so, which will trigger the commands to re-make it.

starfry
  • 9,273
  • 7
  • 66
  • 96
  • This is exactly my problem. Is there any workaround for that? What I actually need is: if `directory` do not exists, create it before building `file`. I could just put `mkdir -p directory` before `commands-to-make-the-file`, but this is the same as targeting `directory` whenever `file` goes out of date... Works exactly as I need, but is ugly =( – matheuscscp Mar 16 '16 at 20:06
  • 1
    @matheuscscp the Makefile documentation exactly addresses that case: https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html – Adam Bliss Jan 25 '18 at 15:30
  • As @AdamBliss mentioned, what you want is perfectly possible with a [order-only-prerequisite](https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html#Prerequisite-Types), but if we read the original question, I don't think this is what it is about at all. Google seems to lead people looking for how to depend on a directory here though. – conny Aug 23 '21 at 07:28
2

It is possible to have a directory as a dependency, in the sense that if it does not exist it will be rebuilt. It's even possible to arrange a rule that will execute when anything in the directory changes, but it's tricky. And in this case it's almost certainly overkill.

If your intent is ordinary, the usual method will suffice:

OBJ_FILES = foo.o bar.o baz.o
# There are ways to be more succinct, but for now we'll keep it simple.

build: $(OBJ_FILES)
    <commands...>

%.o: src/%.c src/%.h
    <commands for building something.o>

clean: # This should not require prerequisites
    <commands...>
Beta
  • 96,650
  • 16
  • 149
  • 150
  • Generally, as your answer already makes clear: the requirement of *a directory as a dependency* is not well-specified. Sometimes (but very rarely) you want to rebuild whenever the directory itself has an update modification time, sometimes when any existing file in the directory changes, sometimes when any file of a certain type changes, sometimes you also want to rebuild when files of a certain type are added, deleted, or renamed, sometimes you want to recursively include the contents of subdirectories.rather expensive. – reinierpost Oct 06 '10 at 10:07