How do I check if file exists in Makefile so I can delete it?

In the clean section of my Makefile I am trying to check if the file exists before deleting permanently. I use this code but I receive errors.

What's wrong with it?

 if [ -a myApp ]
 then
     rm myApp
 fi

I get this error message

 if [ -a myApp ]
 /bin/sh: Syntax error: end of file unexpected (expecting "then")
 make: *** [clean] Error 2

The second top answer mentions ifeq, however, it fails to mention that these must be on the same level as the name of the target, e.g., to download a file only if it doesn't currently exist, the following code could be used:

download:
ifeq (,$(wildcard ./glob.c))
    curl … -o glob.c
endif

You didn't specify what compiler(s) you are using, but if you have access to gcc/g++ you can use the -MM option. What I do is create a file with the extension of .d for every .c or .cpp file, and then "include" the .d files. I use something like this in my Makefile:

It's strange to see so many people using shell scripting for this. I was looking for a way to use native makefile syntax, because I'm writing this outside of any target. You can use the wildcard function to check if file exists:

 ifeq ($(UNAME),Darwin)
     SHELL := /opt/local/bin/bash
     OS_X  := true
 else ifneq (,$(wildcard /etc/redhat-release))
     OS_RHEL := true
 else
     OS_DEB  := true
     SHELL := /bin/bash
 endif 

Update:

I found a way which is really working for me:

ifneq ("$(wildcard $(PATH_TO_FILE))","")
    FILE_EXISTS = 1
else
    FILE_EXISTS = 0
endif

In GNU/Make if the target is not declared .PHONEY and doesn't have any dependencies, the rule will be invoked if a file matching that target does not exist. The code above will trigger the false command only when /opt/local/bin/gsort does not exist, will return a non 0 value, and make will fail.

The problem is when you split your command over multiple lines. So, you can either use the \ at the end of lines for continuation as above or you can get everything on one line with the && operator in bash.

Then you can use a test command to test if the file does exist, e.g.:

test -f myApp && echo File does exist

-f file True if file exists and is a regular file.

-s file True if file exists and has a size greater than zero.

or does not:

test -f myApp || echo File does not exist
test ! -f myApp && echo File does not exist

The test is equivalent to [ command.

[ -f myApp ] && rm myApp   # remove myApp if it exists

and it would work as in your original example.

See: help [ or help test for further syntax.

for better programming it should first check it that the file exists or not i have written below mentioned code : clean: ifeq ($(findstring text11.o,$(wildcard %.o)), text11.o) rm text11.o else echo "no file named text11" endif ifeq ($(findstring functext.o, $(wildcard %.o)), functext.o) rm functext.o else echo "no file named functext" endif

It may need a backslash on the end of the line for continuation (although perhaps that depends on the version of make):

if [ -a myApp ] ; \
then \
     rm myApp ; \
fi;

Check if File Exists#. When checking if a file exists, the most commonly used FILE operators are -e and -f. The first one will check whether a file exists regardless of the type, while the second one will return true only if the FILE is a regular file (not a directory or a device).

Or just put it on one line, as make likes it:

if [ -a myApp ]; then rm myApp; fi;

Check that at least one file exists in the directory. There are some files with suffix dates like abc_20032019.dat abc_17032019.dat If at least one file exists then perform some operation else exit from execution. Korn shell ---------------------------------- array= ($inputdir/abc*.dat) If ] ] then echo " file exits" else echo " file does 2.

Check that at least one file exists in the directory. There are some files with suffix dates like abc_20032019.dat abc_17032019.dat If at least one file exists then perform some operation else exit from execution. Korn shell ---------------------------------- array= ($inputdir/abc*.dat) If ] ] then echo " file exits" else echo " file does 2.

Test If File Exists And It Is … In the examples above with the -f operator we only check whether a file exists and it is a regular file. Here are some other useful options that can help to check whether a “file” exists and has specific permissions or it is a symbolic link, socket or a directory:

Find answers to using if file exists in makefile from the expert community at Experts Exchange

Comments
  • Is myApp a variable or an actual filename?
  • myApp is for myApplication i.e. the filename by the build process.
  • If you just want to avoid make stopping if the file does not exist, rm -rf myApp could be an alternative. Or preceding the command with a dash (-rm myApp) to make make ignore the error from rm (it will however print an ugly message).
  • Your problem was that make treats each line in a rule as a separate command and sends them individually to the shell. It's like running just `if [ -a myApp ]' on its own. If you get this error you either need a solution which joins the lines into one (using ) or which ends up with each line independent of the other. There are now several of these below.
  • did not work until I added backslash `` after if fi
  • This answer will be a bit weird; the file check happens when the makefile is processed but the action will happen later when the target is built by make. If you delete the file in the meantime then the file won't be created. I have put in an edit to make it clearer.
  • Thanks much! This point was not clear from reading the manual.
  • tried this, but I just keep getting Makefile:133: *** unterminated call to function `wildcard': missing `)'. Stop.
  • Great use of wildcard, so it can be done with makefile itself. Neat :)
  • Helps to also understand what $(wildcard pattern) actually does. See link.
  • More concise: FILE_EXISTS := $(or $(and $(wildcard $(PATH_TO_FILE)),1),0)