如何从 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
是一种后置条件吗?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
注意:此答案重点关注给定 makefile 中不同目标的稳健递归调用方面。
补充 Jack Kelly 的有用答案,这是一个 GNU makefile 片段,演示了如何使用
$(MAKE)
来稳健地调用同一 makefile 中的不同目标(确保调用相同的make
二进制文件,并且以相同的 makefile 为目标):输出:
使用
$(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 samemake
binary is called, and that the same makefile is targeted):Output:
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"):
大多数版本的 make 都会设置一个可用于递归调用的变量
$(MAKE)
。Most versions of make set a variable
$(MAKE)
that you can use for recursive invocations.正如您所写的,
build
目标将需要执行不同的操作,具体取决于您刚刚完成了 ocelot 还是 cuda 构建。这就是说您必须以某种方式参数化build
的另一种说法。我建议单独的构建目标(就像您已经拥有的那样)以及关联的变量。类似于:在命令行上输入
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 parameterisebuild
in some way. I suggest separate build targets (much like you already have), with associated variables. Something like:On the command-line you type
make build-cuda
(say). Make first buildscudaLib
, then it carries out the recipe forbuild-cuda
. It expands the macros before calling the shell.$@
in this case isbuild-cuda
, thus${opts-$@}
is first expanded to${opts-build-cuda}
. Make now goes on to expand${opts-build-cuda}
. You will have definedopts-build-cuda
(and of course its sisteropts-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
).