考虑下面的Makefile
include ../../common/make.config
CC = gcc
CC_FLAGS = -g -fopenmp -O2
NVCC = $(CUDA_DIR)/bin/nvcc
NVCC_FLAGS = -I$(CUDA_DIR)/include
# 'make dbg=1' enables NVCC debugging
ifeq ($(dbg),1)
NVCC_FLAGS += -g -O0
else
NVCC_FLAGS += -O2
endif
# 'make emu=1' compiles the CUDA kernels for emulation
ifeq ($(emu),1)
NVCC_FLAGS += -deviceemu
endif
kmeans: cluster.o getopt.o kmeans.o kmeans_clustering.o kmeans_cuda.o rmse.o
$(CC) $(CC_FLAGS) cluster.o getopt.o kmeans.o kmeans_clustering.o kmeans_cuda.o rmse.o -o kmeans -L$(CUDA_LIB_DIR) -lcuda -lcudart -lm
%.o: %.[ch]
$(CC) $(CC_FLAGS) $< -c
kmeans_cuda.o: kmeans_cuda.cu
$(NVCC) $(NVCC_FLAGS) -c kmeans_cuda.cu
clean:
rm -f *.o *~ kmeans kmeans_cuda.linkinfo
当我运行make
时,我得到这个错误
$ make
gcc -g -fopenmp -O2 kmeans.h -c
gcc -g -fopenmp -O2 cluster.o getopt.o kmeans.o kmeans_clustering.o kmeans_cuda.o rmse.o -o kmeans -L/usr/local/cuda/lib64 -lcuda -lcudart -lm
gcc: error: kmeans.o: No such file or directory
文件是
$ ls
cluster.c getopt.c getopt.o kmeans_clustering.c kmeans_cuda.cu kmeans_cuda.o kmeans.h.gch Makefile_nvidia rmse.c run
cluster.o getopt.h kmeans.c kmeans_clustering.o kmeans_cuda_kernel.cu kmeans.h Makefile README rmse.o unistd.h
虽然有kmeans.c
,但我想知道为什么没有kmeans.o
,因此无法在下一步中链接目标文件。
有办法解决这个问题吗?
考虑规则…
%.o: %.[ch]
$(CC) $(CC_FLAGS) $< -c
由于某些原因,似乎对于茎kmeans
%.[ch]
被扩展为kmeans.h kmeans.c
,因此该规则在扩展时变成…
kmeans.o: kmeans.h kmeans.c
$(CC) $(CC_FLAGS) $< -c
内置变量$<
指向第一个先决条件,在本例中是kmeans.h
,因此您看到编译命令…
gcc -g -fopenmp -O2 kmeans.h -c
相反,你可能想要的是…
%.o: %.c %.h
$(CC) $(CC_FLAGS) $< -c
现在第一个先决条件将始终是.c
文件,但要显式依赖于相关的头文件。