Home > Mobile >  Adding a loop inside an if statement in a Makefile
Adding a loop inside an if statement in a Makefile

Time:06-27

I'm trying to write a command which builds either a file that I pass as a flag, or all files.

I have this for now:

SOURCES := $(shell find ./src -name '*.c')

FILE?="all"

# Compile source files into object files
compile:
ifeq ($(FILE), "all")
    for file_dir in $(SOURCES); do \
        $(CC) $(CFLAGS) -o $($$file_dir:.c=.o) -c $$file_dir \
    done;
else 
    $(CC) $(CFLAGS) -o ./out/$(FILE).o -c ./src/$(FILE).c   
endif

But since I've added the loop, I get this error:

$ make compile

for file_dir in ./src/board.c ./src/main.c; do \
        gcc "-Wall" -o  -c $file_dir \
    done;
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [compile] Error 2

CodePudding user response:

I agree with the comments above: this is a bad way to write a makefile. If you just want to compile every file every time, write a shell script.

But, to explain the error you see:

You have your semicolon in the wrong place:

for file_dir in $(SOURCES); do \
    $(CC) $(CFLAGS) -o $($$file_dir:.c=.o) -c $$file_dir \
done;

The semicolon needs to be after the compile command, not after the done. Without a semicolon after the compile command, the done keyword is used as an argument to the compiler and then there is no done keyword, leading to the shell syntax error you see.

for file_dir in $(SOURCES); do \
    $(CC) $(CFLAGS) -o $($$file_dir:.c=.o) -c $$file_dir; \
done

ETA

Also, this is wrong: $($$file_dir:.c=.o) You are trying to use a make variable expansion on a shell variable. That cannot work: all make variables are expanded BEFORE the shell is invoked.

You need something like $${file_dir%.c}.o, using shell features.

PPS

All your makefile appears to do is compile the files. Make has built-in rules that know how to do this. All you have to do is this:

SOURCES := $(shell find ./src -name '*.c')

compile: $(SOURCES:.c=.o)

That's it. Make knows how to compile a .c file and create a .o file, on its own.

  • Related