Jacob Ritchie
Jacob Ritchie

Reputation: 1401

GNU Make - Set a flag if multiple files exist

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?

Upvotes: 1

Views: 1044

Answers (4)

Pan Ruochen
Pan Ruochen

Reputation: 2080

This should work

ifeq ($(OUTLIB_CACHE_LIST),$(wildcard $(OUTLIB_CACHE_LIST)))
# do something
endif

Upvotes: 0

stefanct
stefanct

Reputation: 2964

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),)

Upvotes: 2

Pan Ruochen
Pan Ruochen

Reputation: 2080

Simply define OUTLIB_CACHE_EXISTS as follows

OUTLIB_CACHE_EXISTS := $(shell if ls $(OUTLIB_CACHE_LIST) >/dev/null 2>&1; then echo "1"; fi)

Upvotes: 1

Toby Speight
Toby Speight

Reputation: 30911

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...

Upvotes: 2

Related Questions