GNU Makefile if problems

Adding functionality into a makefile can be a very frustrating process. I was recently trying to add a check for modified files before compiling.  Here’s how the rule looked:

ifneq ( $(shell git ls-files -m | wc -l), 0 )
    @echo Detected modifed files.
    @exit 2 ;

Basically, if any files were found changed the error would be printed. However, this would never work. I verified that git ls-files -m | wc -l returned 0 but the code would always execute. I eventually found the solution in the GNU Make documentation. From the page

Conditional directives are parsed immediately. This means, for example, that automatic variables cannot be used in conditional directives, as automatic variables are not set until the recipe for that rule is invoked. If you need to use automatic variables in a conditional directive you must move the condition into the recipe and use shell conditional syntax instead.

So essentially the shell command was never run when the ifneq was being parsed. I assume the strings were being compared which would explain always failing the equal test. The correct way to implement this test is then:

    @if [ $(shell git ls-files -m | wc -l) -ne 0 ] ; \
    then \
        echo Detected modifed files. \
        exit 2 ; \


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: