我想要一个这样的makefile:
cudaLib :
# Create shared library with nvcc
ocelotLib :
# Create shared library for gpuocelot
build-cuda : cudaLib
make build
build-ocelot : ocelotLib
make build
build :
# build and link with the shared library
即。 *Lib
任务创建一个直接在设备或gpuocelot上运行cuda的库。
对于这两个构建任务,我需要运行相同的构建步骤,只创建库不同。
是否有替代直接运行make?
make build
一种后必备条件?
答案 0 :(得分:51)
注意:此答案侧重于给定makefile中不同目标的强大递归调用方面。
为了补充Jack Kelly's helpful answer,这是一个GNU makefile片段,演示了如何使用$(MAKE)
强健地调用同一个makefile中的不同目标(确保相同的{{ 1}}二进制被调用,并且相同的makefile被定位):
make
输出:
# Determine this makefile's path.
# Be sure to place this BEFORE `include` directives, if any.
THIS_FILE := $(lastword $(MAKEFILE_LIST))
target:
@echo $@ # print target name
@$(MAKE) -f $(THIS_FILE) other-target # invoke other target
other-target:
@echo $@ # print target name
使用$ make target
target
other-target
和$(lastword $(MAKEFILE_LIST))
可确保-f ...
命令使用相同的makefile,即使make make最初是以make显式路径($(MAKE)
)传递的调用
注意:虽然GNU -f ...
确实具有递归调用的功能 - 例如,变量make
专门用于启用它们 - 它们的重点是调用从属 makefile,而不是在相同的 makefile中调用不同的目标。
尽管如此,即使上面的解决方法有点麻烦和模糊,它确实使用常规功能,应该健壮。
以下是手册部分的链接,内容涉及递归调用(“sub-make”):
答案 1 :(得分:24)
大多数make版本都设置了一个变量$(MAKE)
,您可以将其用于递归调用。
答案 2 :(得分:11)
正如你所写,build
目标将需要做一些不同的事情,这取决于你是否刚刚完成了ocelot或cuda构建。这是另一种说法,你必须以某种方式参数化build
。我建议使用相关变量来创建单独的构建目标(就像您已经拥有的那样)。类似的东西:
build-cuda: cudaLib
build-ocelot: ocelotLib
build-cuda build-ocelot:
shell commands
which invoke ${opts-$@}
在命令行中键入make build-cuda
(例如)。首先构建cudaLib
,然后执行build-cuda
的配方。它在调用shell之前扩展宏。在这种情况下,$@
为build-cuda
,因此${opts-$@}
首先展开为${opts-build-cuda}
。现在继续扩展${opts-build-cuda}
。您将在makefile的其他位置定义opts-build-cuda
(当然还有其姐妹opts-build-ocelot
)。
P.S。自build-cuda
等。人。不是真正的文件,你最好告诉make(.PHONY: build-cuda
)。