如何在GNU make中获取Makefile所在父目录的基本名称?

5

假设您想要一个makefile文件,它将生成一个以父目录命名的文件。一种方法是硬编码目标名称,但这不是非常“通用”,例如:

TARGET := dirname.pdf

$(TARGET): $(TARGET:.pdf=.tex)
    pdflatex $(@:.pdf=.tex)

通过make函数检索目录名称会更好。 SA上有各种关于如何检索makefile的完整路径(例如,https://dev59.com/m2Ml5IYBdhLWcg3wyJUe#18137056),但没有父目录的名称......

在GNU make中,最有效和便携的方法是什么?

4个回答

5

为什么不直接使用内置的文件名函数呢?

TARGET := $(notdir $(CURDIR))

我猜你说的"parent directory"是有点含糊不清的。如果你能举出一个具体的路径名和你想要的结果,那么就更容易理解了。


这似乎比Vroomfondel的解决方案更优雅。起初我认为在使用-C时它不会起作用,但文档明确说明CURDIR是在应用任何-C操作之后设置的,而且我已经在GNU make 4.1上进行了测试。谢谢! - stefanct

2

这非常取决于您所谓的“父”目录是什么意思。毕竟,make只能处理字符串,并没有真正的数据类型来表示目录和文件。您可以通过调用此函数来提取路径的最后一个名称:

parent_name = $(lastword $(subst /, ,$(dir $(abspath $1))))
$(info $(call parent_name,/home/stefanct/myproject/foo.c))

输出:

myproject

对,我忘了用 dir 命令从路径中删除 makefile 的名称。然后使用 lastword 就很容易了(参见我的复杂解决方案 :) 谢谢! - stefanct

2
如果你说的父目录是指:
Makefile 路径:
/some/file/path/Makefile

Makefile目录:

/some/file/path

Makefile的上级目录

/some/file

那么以下简单的代码可能是您要找的:

最初的回答。

 MK_PATH:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
 MK_PARENT:=$(realpath $(MK_PATH)../)

我对OP的问题有相同的理解。请注意,如果您的$(MK_PATH)变量在末尾没有定义“/”,那么您需要将“MK_PARENT:= $(realpath $(MK_PATH)/ .. /)”中的“/”添加上。这个问题困扰了我一段时间。 - Kiteloopdesign

0
如果您有安装GNU make >4.0且支持Guile(输出 $(info .FEATURES) 包含 guile),并且basename不包含空格,则以下解决方案可以在没有外部依赖或子进程的情况下正常工作:
MAKEFILE_PATH:=$(abspath $(lastword $(MAKEFILE_LIST)))
MAKEFILE_PATH_ELEMS:=$(subst /, ,$(MAKEFILE_PATH))
PARENT_DIR:=$(word $(guile (- $(words $(MAKEFILE_PATH_ELEMS)) 1)),$(MAKEFILE_PATH_ELEMS))

很不幸,(所有/许多)发行版默认情况下并未启用Guile支持,因此需要安装一个特定的软件包(例如,在Ubuntu上是make-guile),该软件包提供Guile支持并替代普通的make


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接