【问题标题】:Setting target variable for the name of the makefile from a subdirectory从子目录中为 makefile 的名称设置目标变量
【发布时间】:2023-03-27 09:36:01
【问题描述】:

如何在目标执行期间定义 $(MAKEFILE) 的变量? 基本上,我在以特定平台“Makefile.aix”命名的子目录中有一些 make 文件,而在所有其他目录中只有 Makefile。我想为在每个子目录中定义的 $(MAKEFILE) 设置一个变量。代码看起来像这样。

MAKEFILE = Makefile

SUBDIR = ./sub ./sub2

    ifneq ($(wildcard Makefile),)
            MAKEFILE = Makefile
    else
            MAKEFILE = Makefile.$(PLATFORM)
    endif


    all:;
            @for i in $(SUBDIR);\
                    do (\
                            echo Making $$i ...;\
                            cd $$i;\
                            make -f $(MAKEFILE)\
                    ); done

【问题讨论】:

    标签: makefile


    【解决方案1】:

    每个子目录中只有一个Makefile.$(PLATFORM),还是有多个,用于不同的平台?
    在第一种情况下,您可以这样做:

    子目录 = ./sub ./sub2 定义脚本 cd $(1); \ $(MAKE) -f 生成文件* endef 全部: $(foreach 目录,$(SUBDIR),$(调用脚本,$(dir)))

    (define 中的空行很重要。可以省略,如果你在$(MAKE) ... 行的末尾添加一个分号,导致一个很长的命令行,包含所有目录的命令,然后一块执行。)

    另一种script 将是(只是您更喜欢的个人喜好问题):

    定义脚本 $(MAKE) -C $(1) -f $(notdir $(wildcard $(1)/Makefile*)) endef

    如果一个目录中有多个Makefile.$(PLATFORM) 文件,则变得更加困难。我得再考虑一下。

    更新:响应您的评论,这样的事情应该可以工作:

    定义脚本 $(MAKE) -C $(1) -f $(notdir $(wildcard $(1)/Makefile $(1)/Makefile.$(PLATFORM))) endef

    【讨论】:

    • 在几个子目录中有几个不同的平台。 "Makefile.aix、Makefile.sun、Makefile.hpux"
    • @Marc:好的,我已经更新了我的答案。我假设$(PLATFORM) 是预先定义为这些选项之一的,对吧?
    • @eriktous。对我的测试 makefile 进行更改后出现错误 "Unix:/src> make all make -C ./sub -f Makefile make -C ./sub2 -f Makefile.aix make: *** ./sub2 : 路径名中的文件或目录不存在.. Stop. make: *** [all] Error 2"
    • @Marc:我无法判断这种格式,但是这两个 make 命令是否出现在一行上?如果是这样,define ... endef 中是否有空行(或分号)? foreach 函数为每个目录计算$(call script,$(dir)),然后连接输出。没有空行(或者更重要的是,前一行的换行符),这一切都变成了一个长命令,调用 make 并带有很多对它没有意义的参数。使用换行符或分号,命令将按预期单独解释。
    • @eriktous:谢谢!有效。我没有换行符。还有一件事。我希望不必重新创建所有目标,或者至少不必大幅更改目标代码。有没有办法使用变量 $(MAKEFILE) 来调用该定义脚本?基本上我想让目标尽可能接近我上面的例子。
    【解决方案2】:

    按照您的逻辑,我建议更新 do () 部分:

                    do (\
                            echo Making $$i ...;\
                            cd $$i;\
                            if [ -f Makefile.$(PLATFORM) ] \
                            then\
                              make -f Makefile.$(PLATFORM) \
                            else\
                              make -f Makefile\
                            fi\
                    ); done
    

    这实际上不是一种制作风格,但如果没有具体的项目,我无法提出更好的建议

    【讨论】:

      【解决方案3】:

      您可以使用 GNU make 的内置函数完成大部分操作,包括目录循环。将以下内容放在中心位置,例如$(TOP_DIR)/mk/subdir.mk:

      makefile-for-dir = \
        $(if $(wildcard $(1)/Makefile),Makefile,Makefile.$(PLATFORM))
      
      make-recursive = \
        $(foreach _d,$(1),$(MAKE) -C $(_d) -f $(call makefile-for-dir,$(_d)) && ) :
      

      在每个启动递归make的makefile中,使用

      include $(TOP_DIR)/mk/subdir.mk
      
      SUBDIRS = dir1 dir2 dir3
      
      .PHONY: all
      all:
          +@$(call make-recursive,$(SUBDIRS))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多