我有一个像这样的Makefile:
.SECONDARY:
NVCC = nvcc
NVCCFLAGS = --gpu-architecture compute_20
CXX = g++
CXXFLAGS = -O3 -std=c++0x -Wall
CXXLINT = python cpplint.py
CXXLINTFLAGS = --filter=-build/include,-readability/streams,-runtime/sizeof,-whitespace/parens
PROTOC = protoc
PROTOCFLAGS = --cpp_out=.
BINS = my_binary
LIBS = -lcublas -lcusparse
PROTOS = $(wildcard *.proto)
SOURCES = $(wildcard *.cu)
HEADERS = $(wildcard *.cuh)
PBS = $(PROTOS:%.proto=%.pb)
DEPS = $(SOURCES:%.cu=%.d)
TESTS = my_test
all: lint protos
all: deps
all: bins
protos: ${PBS}
deps: ${DEPS}
bins: ${BINS}
clean:
rm -rf *.o *.d *.pb.cc *.pb.h ${BINS} ${TESTS}
lint:
${CXXLINT} ${CXXLINTFLAGS} ${SOURCES}
${CXXLINT} ${CXXLINTFLAGS} ${HEADERS}
tests: lint protos
tests: deps
tests: ${TESTS}
tests: tests-run
tests-run: ${TESTS}
for f in $^; do eval "/usr/bin/time -f \"$$f runtime: %E\" ./$$f"; done
%: %.o
${NVCC} ${NVCCFLAGS} -o $@ $^ ${LIBS}
%.d: %.cu
# ${CXXLINT} ${CXXLINTFLAGS} $*.cu
${NVCC} -M -o $*.d $*.cu
%.o: %.cu
${NVCC} ${NVCCFLAGS} -c -o $@ $*.cu
rm $*.d
%.pb: %.proto
${PROTOC} ${PROTOCFLAGS} $*.proto
${CXX} ${CXXFLAGS} -c -o $*.pb.o $*.pb.cc
ifneq ($(MAKECMDGOALS),clean)
-include ${DEPS}
endif
出现问题,因为在构建proto目标之前我无法生成DEPS。因为构建协议缓冲区会向树添加新的头文件,如果在DEPS之前没有这样做,则nvcc -M(make依赖)将失败,因为它找不到生成的* .pb.h 。任何想法如何解决这个问题?
答案 0 :(得分:6)
另一种解决方案是使您的依赖项文件依赖于协议缓冲区生成的结果。以下代码段包含了执行此操作的所有步骤,因为很难逐一解释它们,并在底部解释了一些项目:
CXX_FLAGS := $(shell pkg-config --cflags protobuf) -xc++
LD_FLAGS := $(shell pkg-config --libs protobuf)
PROTOS := $(wildcard *.proto)
PROTO_OBJS := $(PROTOS:.proto=.pb.o)
BINS := my_binary
SRCS := $(wildcard *.cu)
OBJS := $(SRCS:.cu=.o)
DEPS := $(SRCS:.cu=.d)
PBSRCS := $(wildcard *.proto)
PBOBJS := $(PROTOS:.proto=.pb.o)
PBGENS := $(PROTOS:.proto=.pb.cc) $(PROTOS:.proto=.pb.h)
all: $(BINS)
clean:
rm -f $(BINS) $(OBJS) $(DEPS) $(PBOBJS) $(PBGENS)
$(BINS): $(OBJS)
$(OBJS): $(DEPS)
$(DEPS): $(PBOBJS)
.PRECIOUS: $(PBGENS)
%.d: %.cu
$(CXX) -M $(CXX_FLAGS) $< > $@
%.pb.cc: %.proto
protoc --cpp_out=. $<
%.pb.o : %.pb.cc
$(CXX) $(CXX_FLAGS) -c -o $@ $<
%.o: %.cu
$(CXX) $(CXX_FLAGS) -c -o $@ $<
$(BINS): %: %.o
$(CXX) $(LD_FLAGS) -o $@ $(PROTO_OBJS) $^
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
pkg-config
命令不是必需的,但如果您想自动获取与protobuf文件相关的编译和链接标志,则很方便。当然,您必须将自己的标志添加到此变量中。
-xc++
对你来说可能没用,但是为了能够使用.cu
文件并将它们解释为C ++,这里使用{};即使是与nvcc
不同的编译器。
行$(DEPS): $(PBOBJS)
表示应在创建依赖项之前创建和编译protobuf文件。有几种方法可以实现这一点,所以这只是一个如何做到这一点的例子。
.PRECIOUS
行指示make
保留生成的protobuf文件。在此示例代码段中,这些文件被视为中间文件,因此在没有此行的情况下将被删除。
我将此作为一个单独的答案发布,因为前一个和这个没有太多共同点。
答案 1 :(得分:1)
构建依赖项时,即使缺少头文件,也可以选择继续。使用cpp
或gcc
可以通过使用选项-MM -MG
来实现。我没有NVCC的经验,但我没有看到手册中的那些标志有任何支持。如果这是真的,那么您可以尝试切换到cpp
仅用于依赖关系生成。从cpp
手册页:
-MG假定缺少的头文件是生成的文件,并将它们添加到依赖项列表而不会引发错误。
顺便提一下,你的模式规则%.pb: %.proto
对我来说似乎不对。 %.pb.h
和%.pb.cc
取决于%.proto
,并且使用当前方法,make
将不知道如何解决%.pb.h
上的任何依赖关系,因为它不会知道如何创建.pb.h
文件。