【问题标题】:Gnu Make: how to handle sub-projectsGnu Make:如何处理子项目
【发布时间】:2015-01-09 14:55:18
【问题描述】:
ProjFolder
 \ 
  Subfolder
    sources.cpp
    makefile
makefile

Subfolder 应该是一个单独的外部仓库,在签出项目时拉入。当我将make all 调用到顶级makefile 时,将执行以下配方:

all:  $(NAME).elf $(NAME).s19 $(NAME).hex

$(NAME).elf: $(OBJECTS) $(LDSCRIPT) Subfolder/lib.a
    make -C CppAudioPeriphs all
    @ echo "...linking"
    $(CC) $(OBJECTS) Subfolder/lib.a $(LDFLAGS) $(LIBS) -o $@

如您所见,如果Subfolder 的最终产品 - 文件lib.a 发生更改,则会调用Subfolder 生成文件以重新制作它,然后所有产品都链接到最终的闪存映像中。

问题在于顺序。 我想总是先调用子makefile。它知道何时以及如何重新制作lib.a。然后检查lib.a是否被修改以确定是否重新制作$(NAME).elf。


这是一种解决方案。

.PHONY all $(NAME).elf

这只是指示make 无论如何都要重新制作 $(NAME).elf。我过去曾在小型项目中使用过这种解决方案,但对于目前的项目,它是不可接受的。

【问题讨论】:

    标签: c++ makefile gnu-make


    【解决方案1】:

    正如 MadScientist(以及谁更好)指出的那样,我错过了这个问题的明显解决方案。

    解决方案是始终尝试FORCE Subfolder/lib.a 目标。只要Subfolder makefile 仅在某些内容发生更改时更新lib.a,其余内容都会正确退出。

    因此,您需要以下内容作为您的 Subfolder/lib.a 目标。其余的可以保持原样。如前所述,这里的技巧是您可以强制 make 运行 Subfolder/lib.a 目标本身,但如果 Subfolder/lib.a 上的时间戳没有改变,那么列出 Subfolder/lib.a作为先决条件不需要重建。

    FORCE: ;
    
    Subfolder/lib.a: FORCE
            $(MAKE) -C $(@D) target-to-build-lib.a*
    

    【讨论】:

    • 为什么要打扰“if .. -q ...”?如果问题的答案是“运行真正的 make”,那么您应该始终运行它......结果将是相同的,并且只运行一次而不是两次会快得多。
    • @MadScientist 获取“是否更新”信息。可以通过手动时间戳检查或将原始目标保留为Subfolder/lib.a 的先决条件并相信 make 会正确检测到这一点来避免(但我不知道这实际上是一个有效的事情,比赛时make 检查时间戳等)。但确实,我并没有考虑子制作速度很慢。如果速度不是很快,手动时间戳检查每次都会赢一英里。
    • 其实我不明白这个问题。为什么不让顶级 makefile 直接依赖于 Subfolder/lib.a,并使用 FORCE 规则来确保它被尝试过?如果库是最新的,则 submake 不会更改库上的时间戳,因此顶级 make 不会重建。
    • @MadScientist 因为出于某种原因我没有想到这一点。 =) 这显然是更好的答案(我在很多地方工作时都会这样做)。
    • 例如,在顶部 make 列表“Subfolder/lib.a”中作为 $(NAME).elf 的先决条件,然后创建一个规则 Subfolder/lib.a: FORCE,其中包含调用子 make 的配方。
    【解决方案2】:

    你也可以尝试把你的东西放在一个带有自己的 makefile 的子文件夹中(例如 Mystuff)。然后您可以按照以下方式编写一个顶级makefile

    all: Mystuff
    Mystuff: Subfolder
    
    Subfolder Mystuff:
        ${MAKE} -C $@
    

    但是,Recursive Make Considered Harmful :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-01
      • 2011-10-04
      • 1970-01-01
      相关资源
      最近更新 更多