为什么我的目标总是被重新编译,即使代码没有任何变化?
Why does my target always get recompiled, even if nothing has changed in code?
我几乎是编写 Makefile 的新手,对于可能出现的小错误深表歉意。
我的 Makefile 一直在重新编译可执行文件 (.out
),即使源代码没有任何变化。
目标对其他对象有一些依赖性。无论如何,这些对象不会重新编译相关源文件(就像它应该的那样)。
那么为什么目标重新编译 .out
文件呢?
任何其他建议将不胜感激。
# -*- 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
例如当我输入
make future
第一次全部编译:
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
如果我不更改代码中的任何内容并立即重新键入 make future,我希望得到类似“无事可做...”的结果。
但我得到的是:
nvcc -std=c++14 -g -DMEASURES -Iinclude/ bin/main_cos.o bin/farmkernels.o bin/cudaUtils.o -o bin/future.out
您明确告诉 make
始终重建而不考虑依赖时间戳:
.PHONY: future managed stream clean
make
正在按照您的要求进行操作。
如果您想要漂亮的命名目标而不导致重建,请不要为命名目标编写规则。相反,给他们依赖。正如您已经注意到的,.PHONY
不会强制重建所有依赖项,它只会运行直接规则。
.PHONY: future managed stream clean
future: $(BIN)future.out
$(BIN)future.out: $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o
$(CC) $(ALLFLAGS) $+ -o $@
(也按照"Don't Repeat Yourself"原则使用了自动变量)
为什么目标总是重新编译?
您已指出 future
是一个“虚假目标”。这意味着:
future
与实际文件不对应,即
- 没有日期 Make 可以检查以确定
future
是否是最新的,因此
future
永远不会是最新的,因此
- 无论何时构建
future
,都必须为其执行命令
并且您的链接命令列在 future
目标下;所以它每次都会重新运行。
有关.PHONY
的更深入的解释,请参阅:What is the purpose of .PHONY in a Makefile?
你能做些什么
两个选项:
使用文件目标。您的 future
目标的命令生成 $(BIN)future.out
,对吗?所以用 $(BIN)future.out
目标替换它,然后构建它。
添加一个 $(BIN)future.out
目标,但为了方便起见,不要直接构建它 - 让 future
目标依赖于它,就像@BenVoigt 建议的那样:
.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
我几乎是编写 Makefile 的新手,对于可能出现的小错误深表歉意。
我的 Makefile 一直在重新编译可执行文件 (.out
),即使源代码没有任何变化。
目标对其他对象有一些依赖性。无论如何,这些对象不会重新编译相关源文件(就像它应该的那样)。
那么为什么目标重新编译 .out
文件呢?
任何其他建议将不胜感激。
# -*- 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
例如当我输入
make future
第一次全部编译:
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
如果我不更改代码中的任何内容并立即重新键入 make future,我希望得到类似“无事可做...”的结果。 但我得到的是:
nvcc -std=c++14 -g -DMEASURES -Iinclude/ bin/main_cos.o bin/farmkernels.o bin/cudaUtils.o -o bin/future.out
您明确告诉 make
始终重建而不考虑依赖时间戳:
.PHONY: future managed stream clean
make
正在按照您的要求进行操作。
如果您想要漂亮的命名目标而不导致重建,请不要为命名目标编写规则。相反,给他们依赖。正如您已经注意到的,.PHONY
不会强制重建所有依赖项,它只会运行直接规则。
.PHONY: future managed stream clean
future: $(BIN)future.out
$(BIN)future.out: $(BIN)main_cos.o $(BIN)farmkernels.o $(BIN)cudaUtils.o
$(CC) $(ALLFLAGS) $+ -o $@
(也按照"Don't Repeat Yourself"原则使用了自动变量)
为什么目标总是重新编译?
您已指出 future
是一个“虚假目标”。这意味着:
future
与实际文件不对应,即- 没有日期 Make 可以检查以确定
future
是否是最新的,因此 future
永远不会是最新的,因此- 无论何时构建
future
,都必须为其执行命令
并且您的链接命令列在 future
目标下;所以它每次都会重新运行。
有关.PHONY
的更深入的解释,请参阅:What is the purpose of .PHONY in a Makefile?
你能做些什么
两个选项:
使用文件目标。您的
future
目标的命令生成$(BIN)future.out
,对吗?所以用$(BIN)future.out
目标替换它,然后构建它。添加一个
$(BIN)future.out
目标,但为了方便起见,不要直接构建它 - 让future
目标依赖于它,就像@BenVoigt 建议的那样:.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