如何从make目标手动调用另一个目标?

时间:2011-03-21 12:01:04

标签: gnu-make

我想要一个这样的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

一种后必备条件?

3 个答案:

答案 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)。