代码之家  ›  专栏  ›  技术社区  ›  hcs42

从makefile获取makefile的名称

  •  20
  • hcs42  · 技术社区  · 15 年前

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

    谢谢。

    注:

    我需要它,因为我希望我的makefile调用自己,但是makefile不是makefile,所以我想写如下内容:

    target:
        ($MAKE) -f ($MAKEFILENAME) other_target
    
    6 回复  |  直到 6 年前
        1
  •  11
  •   Sinan Ünür    15 年前
    location = $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
    WHERE_ART_THOU := $(location)
    $(warning $(WHERE_ART_THOU))
    

    我也相信这是GNU做的具体,但我不太确定。

        2
  •  8
  •   P Shved    15 年前

    (如果您有任何问题,请参考 GNU make manual .但请记住,与makefile一样,在将概念付诸实践之前,应该完全阅读本手册)。

    我想不出这是怎么容易做到的。据我所知,你得做些体力活。

    稍后,我将描述如何完成这项工作,并展示介绍 current_makefile 变量。但我想首先强调一个重要的概念。

    你应该理解如果我们有某种变量 当前生成文件 ,扩展到当前生成文件名,然后在读取生成文件的过程中必须进行更改。那意味着 它应该与“即时”扩展上下文一起使用 --即在执行的命令中 在期间 正在读取生成文件。但是,大多数命令是在读取makefiles之后执行的。因此,有些命令将平滑地打印正确的值,而在某些地方,其中“ 推迟 “使用扩展,它将始终扩展到根makefile名称。

    例如,如果您想在规则文本中使用这个变量,就必须进行一些技巧,因为规则文本总是延迟了扩展。所以,如果你有规则的话

    rule:
            echo In makefile $(current_makefile):
            echo Making target $@
    

    它将始终打印根makefile的名称。相反,要强制立即扩展,必须使用makefile特定的名称(即 这些变量的名称在每个makefile中应该是不同的 ):

    this_makefile_unique_name := $(current_makefile)
    rule:
            echo In makefile $(current_makefile):
            echo Making target $@
    

    或使用EVA:。

    define make_rule
    rule:
            echo In makefile $(1):
            echo Making target $$@
    
    $(eval $(call make_rule,$(current_makefile)))
    

    如果只想将当前生成文件的名称用于调试目的,请考虑特殊的调试功能,如警告或信息:。

    $(warning We're in makefile $(current_makefile))
    

    这些函数使用“立即”扩展,并将打印正确的值。


    如何定义这样一个$(当前的生成文件)?

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

    # Beginning of makefile
    $(eval $(makefile_names_push))
    #... makefile text
    $(warning $(current_makefile))
    #...
    $(eval $(makefile_names_pop))
    #End of file
    

    现在在根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
    

    如果您确定您的品牌足够新(3.81以上版本),请更换 lastword 使用内置函数调用:。

    #inctead of $$(call lastword,$$(MAKEFILE_LIST))
    $$(lastword $$(MAKEFILE_LIST))
    

    有用吗?

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

        3
  •  3
  •   Michiel Buddingh    15 年前

    一次短途旅行 Google 建议 this 网站有答案。

        4
  •  2
  •   Keith M    6 年前

    当我使用make来管理简单的重复性任务时,我想做一些类似的事情(用于回显makefile的内容)。我翻过这一页,发现它正是我所追求的,对我对make有限的理解非常有用。

    我阅读此页后的结果:

        # Makefile - 'make' and 'make help' now echo the makefile.
        help:
            cat $(lastword $(MAKEFILE_LIST))
        start:
            sudo -u www /path/to/webapp/myhttpd restart
        stop:
            sudo kill `cat /path/to/webapp/data/httpd.pid`
    
        5
  •  1
  •   Narcolessico    14 年前

    这将返回被调用的第一个makefile的名称,即位于调用堆栈底部的名称:

    MAKEFILE_JUSTNAME := $(firstword $(MAKEFILE_LIST))
    MAKEFILE_COMPLETE := $(CURDIR)/$(MAKEFILE_JUSTNAME)
    

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

        6
  •  0
  •   Rob Wells    15 年前

    G'Day.

    如果要复制原始makefile,请说makefile_test,然后输入命令:

    make -np -f makefile_test 2>&1 | tee output
    

    这将评估makefile和make环境,但不执行任何命令。在输出文件中查找make file测试的引用将显示make环境中设置的内容以及设置该值的位置。

    注意,这会产生很多信息!不要添加-d(debug)开关,它将生成关于make的决策过程的大量额外输出,但是关于make的env的额外信息最少。

    高温高压