GNU Makefile是否支持.PHONY目标的递归调用,如;清洁;?

GNU Makefile是否支持.PHONY目标的递归调用,如;清洁;?,makefile,Makefile,我有一个C/C++项目,其组织方式如下: project | +---- c | | | +---- subproject1 | | | | | +---- bin | | | | | +---- obj | | | | | +---- src | | |

我有一个C/C++项目,其组织方式如下:

project
   |
   +---- c
   |     |
   |     +---- subproject1
   |     |         |
   |     |         +---- bin
   |     |         |
   |     |         +---- obj
   |     |         |
   |     |         +---- src
   |     |
   |     +---- subproject2
   |               |
   |               +---- bin
   |               |
   |               +---- obj
   |               |
   |               +---- src
   |     
   +-----+ cpp
   |     |
   |     +---- subproject1
   |     |         |
   |     |         +---- bin
   |     |         |
   |     |         +---- obj
   |     |         |
   |     |         +---- src


  etcetera
项目
级别,有一个包含以下内容的Makefile:

SUBDIRS = c cpp

all: $(SUBDIRS)

.PHONY: $(SUBDIRS)

$(SUBDIRS):
    $(MAKE) -C $@
c
cpp
子目录包含具有不同
子目录
定义的类似makefile。在
项目的命令提示符下键入
make
c
cpp
目录会使make将目录更改为
子目录中的每个sudb目录
,并使用该子目录的Makefile运行make。这与中描述的完全一样,我对此非常满意。手册还指出,您可以在
$@
之后添加像clean这样的目标,它将在子目录的Makefile中调用该目标。同样很好,但是手册没有给出指导的是当
子目录
包含多个子目录时该怎么做,就像我的
项目
c
目录一样。我将给你们两种我知道有效的方法,然后我将提出我的问题

  • clean
    target的配方中的每个子目录添加目标:
  • clean
    目标配方中的每个子目录上循环(基本上与方法1相同,但更容易添加更多子项目):
  • 我的问题是,是否有一种实现上述功能的方法只需要使用现有的GNU make构造,类似这样的东西(顺便说一句,它不起作用):


    我会按目录声明虚假的清理目标,并将其作为
    清理的先决条件添加到

    CLEANSUBDIRS = $(addprefix clean-,$(SUBDIRS))
    .PHONY: clean $(CLEANSUBDIRS)
    clean: $(CLEANSUBDIRS)
    $(CLEANSUBDIRS): clean-%:
        $(MAKE) -C $* clean
    

    我会按目录声明虚假的清理目标,并将其作为
    清理的先决条件添加到

    CLEANSUBDIRS = $(addprefix clean-,$(SUBDIRS))
    .PHONY: clean $(CLEANSUBDIRS)
    clean: $(CLEANSUBDIRS)
    $(CLEANSUBDIRS): clean-%:
        $(MAKE) -C $* clean
    

    谢谢你,教授先生,这很有效。和100%GNU制造,按要求!如果我正确地解释了您的命令,
    $*
    将替换为从调用
    $(cleansdirs)
    规则的先决条件中删除“clean-”后剩余的内容。是这样吗?我想确保我了解这里发生的事情。为了了解最适合阅读的地方是手册。没错,疯狂的科学家,我不该这么懒。现在我清楚地看到雷诺的解决方案是如何在教授先生身上起作用的,这就像一个符咒。和100%GNU制造,按要求!如果我正确地解释了您的命令,
    $*
    将替换为从调用
    $(cleansdirs)
    规则的先决条件中删除“clean-”后剩余的内容。是这样吗?我想确保我了解这里发生的事情。为了了解最适合阅读的地方是手册。没错,疯狂的科学家,我不该这么懒。现在我确切地了解了雷诺的解决方案是如何工作的。我建议切换到使用非递归生成文件的方法。有一个很好的模板库。然后您可以在子项目中声明多个
    clean::
    目标,所有这些目标都将由
    makeclean
    调用。Autotools派生的makefile使用的方法与您的方法(2)非常相似,据我所知,您描述的所有可移植的
    make
    机制都取决于执行每个所需子
    make
    的方法。GNU make确实有
    foreach
    ,但这并不比您的选项(2)更好。事实上,我个人更喜欢(2)而不是GNU特定的、更难阅读的
    foreach
    @igagis,这是一个非常复杂的make环境,我现在要避免它,但当我需要解决更复杂的构建时,我可能会回到它issues@John,我不知道有一个
    foreach
    命令。很高兴知道!我也喜欢选项2,尽管M.Pacalet的建议提供了我所要求的所有make命令解决方案,但我建议切换到使用非递归makefile方法。有一个很好的模板库。然后您可以在子项目中声明多个
    clean::
    目标,所有这些目标都将由
    makeclean
    调用。Autotools派生的makefile使用的方法与您的方法(2)非常相似,据我所知,您描述的所有可移植的
    make
    机制都取决于执行每个所需子
    make
    的方法。GNU make确实有
    foreach
    ,但这并不比您的选项(2)更好。事实上,我个人更喜欢(2)而不是GNU特定的、更难阅读的
    foreach
    @igagis,这是一个非常复杂的make环境,我现在要避免它,但当我需要解决更复杂的构建时,我可能会回到它issues@John,我不知道有一个
    foreach
    命令。很高兴知道!我也喜欢选项2,尽管M.Pacalet的建议提供了我所要求的所有make命令解决方案
    $(SUBDIRS) clean:
        $(MAKE) -C c $@
    
    CLEANSUBDIRS = $(addprefix clean-,$(SUBDIRS))
    .PHONY: clean $(CLEANSUBDIRS)
    clean: $(CLEANSUBDIRS)
    $(CLEANSUBDIRS): clean-%:
        $(MAKE) -C $* clean