Sven
Sven

Reputation: 273

Makefile: do operation on files with specific extension from a variable

I'm working on a Makefile which needs to be able to do the following:

From a user given variable, SRVS, containing file names, e.g.,

SRVS=Test1.java,test2.c,test3.c,test4.java,test5.c

produce a list of all files with a certain extension to be used by a foreach loop. This list should not contain the extension anymore. Currently, I can parse and get all the files into a usable list, but am unable to do so for an extension. What I have:

    $(foreach SRV, $(shell echo $(SRVS) | tr ',' ' '), \
         CLASSPATH=$(SELF)/default_runtime javac $(UJ_DIR)/services/java/$(SRV).java && \
         find $(UJ_DIR)/services/java/ -iname "$(SRV).class" -type f >> $(SELF)/files && \
) true

Which will take a list of SRVS and produce list usable by foreach and the code therein. For instance, the above example would result in "test1 test2 test3 test4 test5" to be used by the foreach loop

I'd like now to specify the extension, for instance .c, so that the above example would result in "test2 test3 test5". Can you help me out?

Upvotes: 2

Views: 1410

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 29202

First, you do not need to call shell (this is uselessly slow) because there are make built-in functions that do what you want. If, in the definition of variable SRVS you really cannot separate your file names with spaces (the standard make word separator) instead of commas, subst can do it for you. But there is a little trick because the comma is itself the arguments separator of make functions:

comma := ,
SRVS1 := $(subst $(comma), ,$(SRVS))

Next, filter is the make function that allows to select files by extension:

SRVS2 := $(filter %.c,$(SRVS1))

And finally, basename removes the suffix:

SRVS3 := $(basename $(SRVS2))

Demo:

$ cat Makefile
SRVS=Test1.java,test2.c,test3.c,test4.java,test5.c

comma := ,
SRVS1 := $(subst $(comma), ,$(SRVS))
SRVS2 := $(filter %.c,$(SRVS1))
SRVS3 := $(basename $(SRVS2))

all:
    $(info SRVS1 = $(SRVS1))
    $(info SRVS2 = $(SRVS2))
    $(info SRVS3 = $(SRVS3))

$ make -q
SRVS1 = Test1.java test2.c test3.c test4.java test5.c
SRVS2 = test2.c test3.c test5.c
SRVS3 = test2 test3 test5

Or, all at once:

$ cat Makefile
TAGS := $(basename $(filter %.c,$(subst $(comma), ,$(SRVS))))

all:
    $(info TAGS = $(TAGS))
$ make -q
TAGS = test2 test3 test5

Upvotes: 3

Related Questions