Search code examples
cmakefilegnu-makeintel-mpi

Makefile: fail to compile and link due to missing separator error


I wrote a Makefile to compile my C source codes and generate .o, .d files which aim to be stored at another directory different from where the source .c codes reside. Here is a copy of my Makefile:

SHELL=/bin/bash

EXEC=./bin
OBJ=./obj

CC=mpicc
CFLAGS=-O3 -Wall
LFLAGS=-lm -lstdc++ -lmpi


$(OBJ)/%.o: %.c
    $(CC) -c $(CFLAGS) $< -o $@
    $(CC) $(CFLAGS) -MM $*.c > $(OBJ)/$*.d


FWI_OBJ = $(FWI_SRC:%.c=$(OBJ)/%.o)

FWI_SRC = \
        testmpi.c \
        printneigh.c


fwi2D:      $(FWI_OBJ) fd.h
    $(CC) $(LFLAGS) $(FWI_OBJ) -o $(EXEC)/xtestmpi

all: fwi2D

.PHONY: clean
clean:
    rm -f $(OBJ)/*.o $(OBJ)/*.d $(EXEC)/*

install: clean all

-include $(FWI_OBJ:$(OBJ)/.o=$(OBJ)/.d)

After I make it, the screen shows the error message below:

obj/testmpi.o:1: warning: NUL character seen; rest of line ignored
obj/testmpi.o:1: *** missing separator.  Stop.

Could anyone help debug this Makefile and figure out why it happened?


Solution

  • This ...

    -include $(FWI_OBJ:$(OBJ)/.o=$(OBJ)/.d)
    

    ... is wrong. The substitution reference attempts to convert file names from $(FWI_OBJ) that end with $(OBJ)/.o (as expanded) to end instead with $(OBJ)/.d (as expanded). None of the file names in $(FWI_OBJ) end that way, so they all pass through unchanged. As a result, make tries to include the .o files, not the .d files you wanted.

    Probably you meant this, instead:

    -include $(FWI_OBJ:.o=.d)