Search code examples
loopsmakefilellvmllvm-clang

using loop in GNU makefile


Can anyone help me figure out why am I not be bale to pass different versions of .ll files to LLVM_OPT here? Is there a way in makefile to extract each basename of those $(SRC) to pass to opt?

So the scenario is compiling *.c with clang and then applying opt with $(CCC_OPT) to each individual *.ll to transform them to $file_Opt.ll. At last, clang generate the backend a.out by linking all $file_Opt.ll.

BENCHMARK = $(shell basename `pwd`)
SRC := $(wildcard *.c) 
HEADERS := $(wildcard *.h)

# Actions
.PHONY: all  clean vclean
all: 
    $(ZCC) $(HEADERS) $(INCPATHS) $(SRC)  
    $(foreach var,$(SRC), $(CC_OPTS) $(CCC_OPTS) -S -o $(var)_llvmOpt.ll $(var).ll;)
    $(LCC) -v  *_llvmOpt.ll -lm
clean:
    rm -f a.out *.o *.a *.s *.i *.I

vclean:
    rm -f a.out *.o *.a *.s *.i *.I *.ll

output:

opt: loop-wrap.c.ll: error: Could not open input file: No such file or directory
make: *** [all] Error 1

Solution

  • Two choices for removing the .c suffix from the filename.

    You can use the Text Function patsubst directly:

    $(foreach var,$(patsubst %.c,%,$(SRC)),$(CC_OPTS) $(CCC_OPTS) -S -o $(var)_llvmOpt.ll $(var).ll;)
    

    Or through a Substitution Reference.

    $(foreach var,$(SRC:.c=),$(CC_OPTS) $(CCC_OPTS) -S -o $(var)_llvmOpt.ll $(var).ll;)
    

    Or, and this is arguably more correct, you could also use the Functions for File Names function basename for this:

    $(foreach var,$(basename $(SRC)),$(CC_OPTS) $(CCC_OPTS) -S -o $(var)_llvmOpt.ll $(var).ll;)