GCC ищет файл .o

#gcc #makefile

#gcc #makefile

Вопрос:

Рассмотрим следующий 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)

lt; -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 , и, следовательно, он не может связать объектные файлы на следующем шаге.

Есть способ это исправить?

Ответ №1:

Рассмотрим правило…

 %.o: %.[ch]
    $(CC) $(CC_FLAGS)

lt; -c

По какой-то причине кажется, что для stem kmeans %.[ch] расширяется, kmeans.h kmeans.c так что это правило при расширении становится…

 kmeans.o: kmeans.h kmeans.c
    $(CC) $(CC_FLAGS)

lt; -c

Встроенная переменная $< ссылается на первое предварительное условие, которое в данном случае является kmeans.h , следовательно, вы видите команду компиляции…

 gcc -g -fopenmp -O2  kmeans.h -c
 

Вместо этого вы, вероятно, хотите что-то вроде…

 %.o: %.c %.h
    $(CC) $(CC_FLAGS)

lt; -c

Теперь первым предварительным условием всегда будет .c файл, но с явной зависимостью от связанного заголовка.