Issue
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:
future
doesn't correspond to an actual file, i.e.- There is nothing with a date which Make can check to determine whether
future
is up-to-date, therefore future
can never be up-to-date, therefore- Whenever you build
future
, you have to execute the commands for it
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:
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.Add a
$(BIN)future.out
target, but for convenience, don't build that directly - have thefuture
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
Answered By - einpoklum Answer Checked By - David Goodson (WPSolving Volunteer)