1

In my Makefile, I check if a file exists, and execute different code depending on the result of that check.

Previously, there was only one relevant file, OUTLIB_CACHE.

OUTLIB_CACHE := filename
OUTLIB_CACHE_EXITS := $(shell if [ -f $(OUTLIB_CACHE) ]; then echo "1"; fi;)
ifneq ($(OUTLIB_CACHE_EXISTS),1)    
    # do something
endif

Now I am introducing a second relevant file, storing both of the file names in a list:

OUTLIB_CACHE_LIST := filename1 filename2

I want to set the OUTLIB_CACHE_EXISTS flag to true if and only if all the files in OUTLIB_CACHE_LIST exist. What would be the best way to do this?

Jacob Ritchie
  • 1,261
  • 11
  • 22

4 Answers4

2

You could substitute each element of OUTLIB_CACHE_LIST with a command, then execute the resulting commands in a shell:

OUTLIB_CACHE_MISSING := $(shell $(patsubst %,test -e "%" || echo missing;,$(OUTLIB_CACHE_LIST)))

If all the members exist, then the output of the shell command will be empty, else it will contain one word for each missing file. You can test for emptiness:

ifneq ($(OUTLIB_CACHE_MISSING),)    
    # do something
endif

If you want to know which files are missing, you can't just replace ! with %, because patsubst only replaces the first % it finds. Instead, you could use foreach:

OUTLIB_CACHE_MISSING := $(shell $(foreach f,$(OUTLIB_CACHE_LIST),test -e "$f" || echo "$f";))

Putting this all together in a testable example:

OUTLIB_CACHE_LIST := /etc /bin
#OUTLIB_CACHE_LIST += /nonexistent

OUTLIB_CACHE_MISSING := $(shell $(foreach f,$(OUTLIB_CACHE_LIST),test -e "$f" || echo "$f";))

.PHONY: all

all:
ifneq ($(OUTLIB_CACHE_MISSING),)
    false "$(OUTLIB_CACHE_MISSING)"
else
    true "No missing files"
endif

Uncomment the second line to select the first branch of the if.


N.B. You wanted to know whether the files exist, so I've used test -e rather than -f or -r. You'll know which test is actually appropriate for your case...

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
2

There is no need to use shell functions to test for the existence of multiple files in make. I use the following construct to make make output decent error messages for a very convoluted makefile. I presume you can adopt it to your needs if need be. The original idea (probably) comes from https://stackoverflow.com/a/20566812/1905491.

$(foreach p,$(ALL_INCLUDES),$(if $(wildcard $(p)),,$(info $(p) does not exist!) $(eval err:=yes)))
$(if $(err),$(error Aborting),)
Community
  • 1
  • 1
stefanct
  • 2,503
  • 1
  • 28
  • 32
1

Simply define OUTLIB_CACHE_EXISTS as follows

OUTLIB_CACHE_EXISTS := $(shell if ls $(OUTLIB_CACHE_LIST) >/dev/null 2>&1; then echo "1"; fi)
Pan Ruochen
  • 1,990
  • 6
  • 23
  • 34
0

This should work

ifeq ($(OUTLIB_CACHE_LIST),$(wildcard $(OUTLIB_CACHE_LIST)))
# do something
endif
Pan Ruochen
  • 1,990
  • 6
  • 23
  • 34