从makefile获取makefile的名称

hcs*_*s42 21 makefile

如何在makefile中获取makefile的名称?

谢谢.

注意:

我需要那个,因为我希望我的makefile自己调用,但makefile不是Makefile,所以我想写这样的东西:

target:
    ($MAKE) -f ($MAKEFILENAME) other_target
Run Code Online (Sandbox Code Playgroud)

Mic*_*kis 12

location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
WHERE_ART_THOU := $(location)
$(warning $(WHERE_ART_THOU))
Run Code Online (Sandbox Code Playgroud)

我也相信这是GNU特定的,但我不太确定.

  • 但是对于包含的makefile,你将不得不使用不同的名称:一个makefile的`WHERE_ART_THOU`,另一个的WHERE_ART_THOU_2`等等.我的目的是为所有makefile引入一个名称,这个名称不仅适用于一个make的顶部. (5认同)
  • 如果在包含另一个makefile后检查makefile名称,则此解决方案不起作用!(复制粘贴的评论) (3认同)

P S*_*ved 10

(如果您有任何疑问,请参阅令人惊讶的GNU制作手册.但请记住,就像Makefile一样,在将这些概念付诸实践之前,应该完整阅读本手册).

我无法弄清楚它是如何轻松完成的.据我了解,你将不得不做一些手工工作.

稍后我将描述如何完成它并显示引入current_makefile变量的脚本.但我想首先强调一个重要的概念.

你应该明白,如果我们有某种变量current_makefile,它扩展到当前的makefile名称,那么在读取makefile的过程中它必须改变.这意味着它应该在"立即"扩展上下文中使用 - 即读取makefile 期间执行的命令中.但是,大多数命令都是在读取makefile之后执行的.因此,某些命令将平滑地打印正确的值,而在某些使用" 延迟 "扩展的地方,它将始终扩展为根makefile文件名.

例如,如果您想在规则文本中使用此变量,则必须执行一些技巧,因为规则文本始终具有延迟扩展.所以,如果你有规则

rule:
        echo In makefile $(current_makefile):
        echo Making target $@
Run Code Online (Sandbox Code Playgroud)

它将始终打印根makefile的名称.相反,要强制立即扩展,您必须使用特定于makefile的名称创建另一个变量(即每个makefile中此类变量的名称应该不同):

this_makefile_unique_name := $(current_makefile)
rule:
        echo In makefile $(current_makefile):
        echo Making target $@
Run Code Online (Sandbox Code Playgroud)

或使用eval:.

define make_rule
rule:
        echo In makefile $(1):
        echo Making target $$@

$(eval $(call make_rule,$(current_makefile)))
Run Code Online (Sandbox Code Playgroud)

如果您只想将当前makefile的名称用于调试目的,请考虑特殊的调试功能,如警告或信息:.

$(warning We're in makefile $(current_makefile))
Run Code Online (Sandbox Code Playgroud)

这些功能使用"立即"扩展并打印正确的值.


如何定义这样的$(current_makefile)?

您必须手动维护堆栈的makefile包含.当您包含makefile时,它的名称将放在堆栈的顶部; 当您从包含的makefile返回到外部文件时,最顶层的名称将从堆栈中弹出.这是通过在makefile的开头和结尾插入特殊调用来实现的:

# Beginning of makefile
$(eval $(makefile_names_push))
#... makefile text
$(warning $(current_makefile))
#...
$(eval $(makefile_names_pop))
#End of file
Run Code Online (Sandbox Code Playgroud)

现在在根makefile的开头定义函数.

lastword=$(word $(words $(1)),$(1))

define makefile_names_push
current_makefile := $$(CURDIR)/$$(call lastword,$$(MAKEFILE_LIST))
makefile_stack :=$$(makefile_stack) $$(current_makefile)
endef

define makefile_names_pop
makefile_stack := $$(filter-out $$(current_makefile),$$(makefile_stack))
current_makefile := $$(call lastword,$$(makefile_stack))
endef
Run Code Online (Sandbox Code Playgroud)

如果你确定你的make足够新(版本3.81+),lastword请用内置函数替换call:

#inctead of $$(call lastword,$$(MAKEFILE_LIST))
$$(lastword $$(MAKEFILE_LIST))
Run Code Online (Sandbox Code Playgroud)

它有用吗?

完全没用.这里唯一有用的用法是将100个makefile作为符号链接到一个makefile,这些makefile中的规则取决于它们的名称.但它可以在手册中描述的一个makefile和foreach-eval技术中实现.所以我的帖子完全是浪费时间,虽然我有一些乐趣:-)


Nar*_*ico 7

这将返回调用的第一个 Makefile 的名称,即调用堆栈底部的名称:

MAKEFILE_JUSTNAME := $(firstword $(MAKEFILE_LIST))
MAKEFILE_COMPLETE := $(CURDIR)/$(MAKEFILE_JUSTNAME)
Run Code Online (Sandbox Code Playgroud)

当在非交叉递归情况下使用时(例如用于 makedepend),它只是当前 makefile 的名称。