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

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 $@ $^

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值