makefile不同的编译器生成多个中间文件

    xiaoxiao2021-03-26  22

    makefile不同的代码进行不同的编译,比如cuda代码中想将cpp代码和cu代码分开分别编译成.o文件,再将.o文件编译成一个哭文件或者可执行文件,这时可能cpp和cuda的编译器不一样,那么就不能够使用自动推导,当然,也可以将两个编译器组合成一个编译器,让系统根据代码自己去选择相应的编译器,这里将的是如果想分开的话,应该怎么做?

    首先,假设这里有3个cpp文件,2个cu文件:

    a.cpp ,b.cpp,d.cpp kernel1.cu,kernel2.cu

    首先获取相应的文件名称以及去掉后缀后的文件名:

    SRC :=$(wildcard *.cpp) OBJ :=$(SRC:%.cpp=%.o) NAM := $(foreach src,$(SRC),$(eval NAM += $$(shell basename $(src) .cpp));)

    然后将不同的代码进行编译

    gen_cpp: $(foreach n, $(NAM), $(EXEC) $(HOST_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o ${n}.o -c $(n).cpp;)

    上面的代码就会自动生成相应的.o文件 同样,对cu代码:

    SRC_CU :=$(wildcard *.cu) OBJ_CU :=$(SRC_CU:%.cu=%.o) NAM_CU := $(foreach src,$(SRC_CU),$(eval NAM_CU += $$(shell basename $(src) .cu));) #下面这句和上面这句一样,不同的是,使用的是makefile自己的basename变量: #shell的basename是去掉路径的前缀,一般结合pwd可以用来获取目录名,在后面加上.cu可以再去掉后缀 #而makefile中的basename是用来去掉后缀的 $(foreach src,$(SRC_CU),$(eval NAM_CU += $$(basename $(src)));)

    然后将不同的代码进行编译

    gen_cu: $(foreach n, $(NAM_CU), $(NVCC) $(INCLUDES) $(ALL_CCFLAGS) -o ${n}.o -c $(n).cu;)

    最后,完整的代码:

    .PHONY : gen_cpp gen_cu #注意,这里gen_cpp,gen_cu一定要先放在build的前面,因为build会依赖这两项生成的中间文件 all: gen_cpp gen_cu build SRC :=$(wildcard *.cpp) OBJ :=$(SRC:%.cpp=%.o) NAM := $(foreach src,$(SRC),$(eval NAM += $$(shell basename $(src) .cpp));) gen_cpp: $(foreach n, $(NAM), $(EXEC) $(HOST_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o ${n}.o -c $(n).cpp;) SRC_CU :=$(wildcard *.cu) OBJ_CU :=$(SRC_CU:%.cu=%.o) NAM_CU := $(foreach src,$(SRC_CU),$(eval NAM_CU += $$(shell basename $(src) .cu));) gen_cu: $(foreach n, $(NAM_CU), $(NVCC) $(INCLUDES) $(ALL_CCFLAGS) -o ${n}.o -c $(n).cu;) build : target.so target:$(gen_cpp) $(gen_cu) $(ALL_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ -shared $^

    还有一种更简单的模式规则可以使用,相比上面,下面代码的好处是,由于需要生成的目标是实际存在的,因此,如果编译时间较长时,上面这种方法由于是伪目标,每次都需要重新进行编译,会很耗时,而下面这种,只会编译更改后的源文件:

    #注意,这里gen_cpp,gen_cu一定要先放在build的前面,因为build会依赖这两项生成的中间文件 SRC :=$(wildcard *.cpp) OBJ :=$(SRC:%.cpp=%.o) SRC_CU :=$(wildcard *.cu) OBJ_CU :=$(SRC_CU:%.cu=%.o) all: $(OBJ_CU) $(OBJ) target.so $(OBJ_CU):%.o:%.cu $(NVCC_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^ $(OBJ):%.o:%.cpp $(HOST_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^ target.so:$(OBJ_CU) $(OBJ) $(ALL_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^

    注意如果将上面的

    $(OBJ_CU):%.o:%.cu $(NVCC_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^ $(OBJ):%.o:%.cpp $(HOST_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^

    更改成

    $(OBJ_CU):$(SRC_CU) $(NVCC_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^ $(OBJ):$(SRC) $(HOST_COMPLIER) $(INCLUDES) $(ALL_CCFLAGS) -o $@ $^

    看似是正确的,实际上会报错

    转载请注明原文地址: https://ju.6miu.com/read-659718.html

    最新回复(0)