Test whether a directory exists inside a makefile Test whether a directory exists inside a makefile bash bash

Test whether a directory exists inside a makefile


Make commands, if a shell command, must be in one line, or be on multiple lines using a backslash for line extension. So, this approach will work:

foo.bak: foo.bar    echo "foo"    if [ -d "~/Dropbox" ]; then echo "Dir exists"; fi

Or

foo.bak: foo.bar    echo "foo"    if [ -d "~/Dropbox" ]; then \        echo "Dir exists"; \    fi


This approach functions with minimal echos:

.PHONY: allall:ifneq ($(wildcard ~/Dropbox/.*),)        @echo "Found ~/Dropbox."else        @echo "Did not find ~/Dropbox."endif


Act upon the absence of a directory

If you only need to know if a directory does not exist and want to act upon that by for example creating it, you can use ordinary Makefile targets:

directory = ~/Dropboxall: | $(directory)    @echo "Continuation regardless of existence of ~/Dropbox"$(directory):    @echo "Folder $(directory) does not exist"    mkdir -p $@.PHONY: all

Remarks:

  • The | indicates that make shouldn't care about the timestamp (it's an order-only-prerequisite).
  • Rather than write mkdir -p $@, you can write false to exit, or solve your case differently.

If you also need to run a particular series of instructions upon the existence of a directory, you cannot use the above. In other words, it is equivalent to:

if [ ! -d "~/Dropbox" ]; then    echo "The ~/Dropbox folder does not exist"fi

There is no else statement.

Act upon the presence of a directory

If you want the opposite if-statement this is also possible:

directory = $(wildcard ~/Dropbox)all: | $(directory)    @echo "Continuation regardless of existence of ~/Dropbox"$(directory):    @echo "Folder $(directory) exists".PHONY: all $(directory)

This is equivalent to:

if [ -d "~/Dropbox" ]; then    echo "The ~/Dropbox folder does exist"fi

Again, there is no else statement.

Act upon both the presence and the absence of a directory

This becomes a bit more cumbersome, but in the end gives you nice targets for both cases:

directory = ~/Dropboxdir_target = $(directory)-$(wildcard $(directory))dir_present = $(directory)-$(directory)dir_absent = $(directory)-all: | $(dir_target)    @echo "Continuation regardless of existence of ~/Dropbox"$(dir_present):    @echo "Folder $(directory) exists"$(dir_absent):    @echo "Folder $(directory) does not exist".PHONY: all

This is equivalent to:

if [ -d "~/Dropbox" ]; then    echo "The ~/Dropbox folder does exist"else    echo "The ~/Dropbox folder does not exist"fi

Naturally, the wildcard expansion might be slower than an if-else-statement. However, the third case is probably quite rare and is just added for completeness.