在定义命令的文件所在的目录中执行命令

发布于 2024-09-10 15:54:01 字数 481 浏览 4 评论 0原文

如果愿意的话,请考虑以下情况:

$ pwd
/tmp/submake_example
$ head $(find -type f)
==> ./subdir/Makefile <==
subtarget:
        echo "executing subtarget from directory $$(pwd)"

==> ./Makefile <==
include subdir/Makefile
$ make subtarget
echo "executing subtarget from directory $(pwd)"
executing subtarget from directory /tmp/submake_example

有没有一种方法可以让我从目录 subdir 中执行目标 subtarget 的命令?我希望能够从主目录中的命令行访问包含的 makefile 的目标。

Consider, if you will, the following situation:

$ pwd
/tmp/submake_example
$ head $(find -type f)
==> ./subdir/Makefile <==
subtarget:
        echo "executing subtarget from directory $(pwd)"

==> ./Makefile <==
include subdir/Makefile
$ make subtarget
echo "executing subtarget from directory $(pwd)"
executing subtarget from directory /tmp/submake_example

Is there a way that I can have the command for the target subtarget executed from within the directory subdir? I'd like to be able to access the targets of included makefiles from the command line in the main directory.

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

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

发布评论

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

评论(1

清秋悲枫 2024-09-17 15:54:01

经过一些挖掘和实验,我发现了一些事情。

此参考文献推荐的方法,引用了论文递归使人认为有害,非常复杂,并且涉及在整个目录中手动维护目录堆栈makefile 包含层次结构。

我还发现,与任何引用无关,变量 $(MAKEFILE_LIST) 的最后一个元素至少对于一些基本测试用例将包含当前包含的 makefile 的名称。这意味着可以使用像

foo: dir := $(dir $(lastword $(MAKEFILE_LIST)))

这样的代码将其目录存储在一个简单扩展的、特定于目标的变量中。然后您可以像任何其他变量一样在该规则中使用 $(dir) ;它保留在包含 makefile 期间假定的值。 cd 到它,将其放入命令路径中,无论如何。

您必须小心地将赋值给 dir 放在该 makefile 中的任何包含指令之前。

如果目录名称中有空格,这将不起作用,但我发现如果文件或目录名称中有空格, make 中几乎没有任何东西可以工作。

还值得注意的是,这种方法使用了仅在 GNU make 中找到的功能。对我来说听起来像是一个杀手级应用程序,尽管我仍然有点困惑为什么它们不只在内置变量或函数中提供目录名称。

无论如何,这似乎有效,至少乍一看是这样。我仍然只是在没有任何真正备份的情况下浮动这个方法,因此非常欢迎对此方法的实用性发表评论以及替代建议。

After some digging and experimentation, I've discovered a couple of things.

The approach recommended by this reference, which refers to the paper Recursive Make Considered Harmful, is pretty complicated, and involves manually maintaining a directory stack throughout the makefile inclusion heirarchy.

I also discovered, independently of any reference, that the last element of the variable $(MAKEFILE_LIST) will, at least for some basic test cases, contain the name of the makefile that's currently being included. This means that it's possible to store its directory in a simply expanded, target-specific variable with code like

foo: dir := $(dir $(lastword $(MAKEFILE_LIST)))

That's it. Then you can just use $(dir) within that rule like any other variable; it retains the value that it assumed during makefile inclusion. cd to it, put it in command paths, whatever.

You have to be careful to put the assignment to dir before any include directives in that makefile.

This won't work if there's a space in the directory name, but I gather that pretty much nothing in make works if there are spaces in file or directory names.

It's also notable that this approach uses features only found in GNU make. Sounds like a killer app to me, though I remain a bit perplexed as to why they don't just provide the directory name in a builtin variable or function.

Anyway this seems to work, at least at first glance. I'm still pretty much just floating this one without any real backup, so comments on the practicality of this approach, and alternative suggestions, are very welcome.

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