linuxmakefilecudarebuild

Why does my target always get recompiled, even if nothing has changed in code?


I'm almost new in writing Makefiles, so sorry for possible trivial mistakes.

My Makefile keeps recompiling the executable file (.out) even if nothing has changed in source code. The target has some dependencies on other objects, but they don't recompile their source files (as expected). So, why does the target recompile the .out file instead?

Any other advice would be really appreciated.

# -*- Makefile -*-

CC:= nvcc
CFLAGS:= -std=c++14 -g -DMEASURES
ALLFLAGS:= $(CFLAGS) -Iinclude/ 
LOWPAR:= $(ALLFLAGS) -DLOWPAR


BIN:=bin/
SRC:=src/
INCLUDE:=include/


.PHONY: future managed stream clean

####DEVICE####
#cos future, stream, managed
future: $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o
    $(CC) $(ALLFLAGS) $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o -o $(BIN)future.out

managed: $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o
    $(CC) $(ALLFLAGS) $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o -o $(BIN)managed.out

stream: $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o
    $(CC) $(ALLFLAGS) $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o -o $(BIN)stream.out


$(BIN)main_cos.o: $(SRC)main_cos.cpp $(INCLUDE)cosFutStr.h $(INCLUDE)cudaUtils.h
    $(CC) $(ALLFLAGS) -c $(SRC)main_cos.cpp -D$(shell echo $(MAKECMDGOALS) | tr a-z A-Z) -o $(BIN)main_cos.o

$(BIN)farmkernels.o:  $(SRC)farmkernels.cu $(INCLUDE)cosFutStr.h $(INCLUDE)cudaUtils.h
    $(CC) $(ALLFLAGS) -c $(SRC)farmkernels.cu -o $(BIN)farmkernels.o

$(BIN)cudaUtils.o: $(SRC)cudaUtils.cpp  $(INCLUDE)cudaUtils.h
    $(CC) $(ALLFLAGS) -c $(SRC)cudaUtils.cpp -o $(BIN)cudaUtils.o

####clean####
clean:
    rm -f $(BIN)*.o 
    rm -f $(BIN)*.out

For example when I type

make future

the first time I get everything compiled:

nvcc -std=c++14 -g -DMEASURES -Iinclude/  -c src/main_cos.cpp -DFUTURE -o bin/main_cos.o
nvcc -std=c++14 -g -DMEASURES -Iinclude/  -c src/farmkernels.cu -o bin/farmkernels.o
nvcc -std=c++14 -g -DMEASURES -Iinclude/  -c src/cudaUtils.cpp -o bin/cudaUtils.o
nvcc -std=c++14 -g -DMEASURES -Iinclude/  bin/main_cos.o bin/farmkernels.o bin/cudaUtils.o -o bin/future.out

If I don't change the code and immediately re-type make future, I expect something like "nothing to be done for...". What I get instead is:

nvcc -std=c++14 -g -DMEASURES -Iinclude/  bin/main_cos.o bin/farmkernels.o bin/cudaUtils.o -o bin/future.out

Solution

  • Why does the target always recompile?

    You have indicated that future is a "phony target". This means that:

    And you have your linking command listed under the future target; so it gets re-run every time.

    For a more in-depth explanation about.PHONY, see: What is the purpose of .PHONY in a Makefile?

    What you can do about it

    Two options:

    1. Use file targets. Your future target's commands generate $(BIN)future.out, right? So replace it with a $(BIN)future.out target, and build that.

    2. Add a $(BIN)future.out target, but for convenience, don't build that directly - have the future target depend on it, like @BenVoigt suggested:

       .PHONY: future other_pho ny_target s_here
      
       future: $(BIN)future.out
      
       $(BIN)future.out: $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o
           $(CC) $(ALLFLAGS) $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o -o $(BIN)future.out