Can a makefile have a directory as a target?

Viewed 36214

I am trying to say "the download of the git repository will only work if the directory yank/ exists. If the directory yank/ does not exist then make it"

yank/gist.el/gist.el : yank
    cd yank ; git clone http://github.com/defunkt/gist.el.git 

yank:
    mkdir yank

I am using makepp - http://makepp.sf.net and am getting the error:

[metaperl@andLinux ~/edan/pkg/gist.el] makepp
makepp: Loading makefile `/home/metaperl/edan/pkg/gist.el/Makeppfile'
makepp: Entering directory `/home/metaperl/edan/pkg/gist.el'
mkdir yank
mkdir: cannot create directory `yank': File exists
makepp: error: Failed to build target `/home/metaperl/edan/pkg/gist.el/yank' [1]
makepp: 0 files updated, 0 phony targets built and 1 target failed
[metaperl@andLinux ~/edan/pkg/gist.el] 

But why would it try to make the yank directory if it exists? The "source" has already ben created...

4 Answers

Yes, a Makefile can have a directory as target.

However, you shouldn't. When a file is added or removed from a directory, its mtime is updated. This can cause weird behaviour by causing multiple targets depending on a single directory to become implicitly rebuilt by one another. So as a rule of thumb, you should avoid using directories as targets and/or dependencies..

all: d/a d/b

d/a d/b: d
  rm -f $@
  touch $@

d:
  mkdir $@

The output from running this multiple times looks like...

$ make
mkdir d
rm -f d/a
touch d/a
rm -f d/b
touch d/b

$ make
rm -f d/a
touch d/a

$ make
rm -f d/b
touch d/b

$ make
rm -f d/a
touch d/a
Related