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

发布于 2024-10-25 06:03:58 字数 481 浏览 2 评论 0原文

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

是一种后置条件吗?

I would like to have a makefile like this:

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

I.e. the *Lib tasks create a library that runs cuda directly on the device, or on gpuocelot respectively.

For both build tasks I need to run the same build steps, only creating the library differs.

Is there an alternative to running make directly?

make build

Kind of a post-requisite?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凉城凉梦凉人心 2024-11-01 06:03:58

注意:此答案重点关注给定 makefile 中不同目标的稳健递归调用方面。

补充 Jack Kelly 的有用答案,这是一个 GNU makefile 片段,演示了如何使用 $(MAKE)稳健地调用同一 makefile 中的不同目标(确保调用相同的 make 二进制文件,并且以相同的 makefile 为目标):

# 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 .. . 确保 $(MAKE) 命令使用相同的 makefile,即使该 makefile 是通过显式路径 (-f ...) 传递的make 最初被调用。


注意:虽然 GNU make 确实具有递归调用的功能 - 例如,变量 $(MAKE) 专门存在来启用它们 - 它们的重点是调用 从属< /em> makefile,而不是在相同 makefile 中调用不同的目标。

也就是说,尽管上面的解决方法有些麻烦和晦涩,但它确实使用了常规功能,并且应该健壮

以下是涵盖递归调用(“子版本”)的手册部分的链接:

Note: This answer focuses on the aspect of a robust recursive invocation of a different target in a given makefile.

To complement Jack Kelly's helpful answer, here's a GNU makefile snippet that demonstrates the use of $(MAKE) to robustly invoke a different target in the same makefile (ensuring that the same make binary is called, and that the same makefile is targeted):

# 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

Output:

$ make target

target
other-target

Using $(lastword $(MAKEFILE_LIST)) and -f ... ensures that the $(MAKE) command uses the same makefile, even if that makefile was passed with an explicit path (-f ...) when make was originally invoked.


Note: While GNU make does have features for recursive invocations - for instance, variable $(MAKE) specifically exists to enable them - their focus is on invoking subordinate makefiles, not on calling a different target in the same makefile.

That said, even though the workaround above is somewhat cumbersome and obscure, it does use regular features and should be robust.

Here is the link to the manual section covering recursive invocations ("sub-makes"):

睡美人的小仙女 2024-11-01 06:03:58

大多数版本的 make 都会设置一个可用于递归调用的变量 $(MAKE)

Most versions of make set a variable $(MAKE) that you can use for recursive invocations.

半衾梦 2024-11-01 06:03:58

正如您所写的,build 目标将需要执行不同的操作,具体取决于您刚刚完成了 ocelot 还是 cuda 构建。这就是说您必须以​​某种方式参数化 build 的另一种说法。我建议单独的构建目标(就像您已经拥有的那样)以及关联的变量。类似于:

build-cuda: cudaLib
build-ocelot: ocelotLib

build-cuda build-ocelot:
    shell commands
    which invoke ${opts-$@}

在命令行上输入 make build-cuda (比如说)。 Make 首先构建 cudaLib,然后执行 build-cuda 的配方。它在调用 shell 之前扩展宏。 $@ 在本例中是 build-cuda,因此 ${opts-$@} 首先扩展为 ${opts-构建cuda}。现在继续扩展${opts-build-cuda}。您将在 makefile 的其他位置定义 opts-build-cuda (当然还有它的姐妹 opts-build-ocelot)。

PS 自 build-cuda 等。等人。不是真实的文件,你最好告诉 make this (.PHONY: build-cuda)。

As you have written it, the build target will need to do something different depending on whether you have just done an ocelot or cuda build. That's another way of saying you have to parameterise build in some way. I suggest separate build targets (much like you already have), with associated variables. Something like:

build-cuda: cudaLib
build-ocelot: ocelotLib

build-cuda build-ocelot:
    shell commands
    which invoke ${opts-$@}

On the command-line you type make build-cuda (say). Make first builds cudaLib, then it carries out the recipe for build-cuda. It expands the macros before calling the shell. $@ in this case is build-cuda, thus ${opts-$@} is first expanded to ${opts-build-cuda}. Make now goes on to expand ${opts-build-cuda}. You will have defined opts-build-cuda (and of course its sister opts-build-ocelot) elsewhere in the makefile.

P.S. Since build-cuda et. al. are not real files, you had better tell make this (.PHONY: build-cuda).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文