【问题标题】:checking subfolders recursively for additional make files [closed]递归检查子文件夹以获取其他make文件[关闭]
【发布时间】:2020-12-27 10:00:10
【问题描述】:

我有一个项目。如果它在每个子目录的每一级都包含一个Makefile,并且有一个最顶层目录Makefile。然后如何使makefiles编译所有C文件并在根目录输出一个生成的.o文件。怎么可能?

【问题讨论】:

  • output one resulted .o file at the root 是晦涩难懂的,每个编译的文件都会产生一个关联的对象(除非你直接产生可执行文件),如果你想要一个单独的目标文件,你需要编译一个单独的源文件。 makefile 有什么链接?手动或通过 make 对编译没有任何影响。你确定你说的是对象 (.o) 而不是可执行文件或 lib 吗?
  • 有一个类似的问题here。它可能会有所帮助
  • 如果可以生成一个 .o 文件,那么您可能不需要多个 Makefile。
  • @tripleee 为什么内核源代码在每个文件夹中都有太多的makefile

标签: c makefile


【解决方案1】:

如果您在 GNU/Linux(或任何带有 find 实用程序的类 UNIX 操作系统)下使用 GNU make,目录名称中不要有空格,并且所有 makefile 都命名为 Makefile,以下可能是开始观点。将其添加到您的顶级 makefile 并键入 make all 以构建所有子目录:

SUBDIRS := $(dir $(shell find . -mindepth 2 -type f -name 'Makefile'))

.PHONY: $(SUBDIRS) all

all: $(SUBDIRS)

$(SUBDIRS):
    $(MAKE) -C $@

解释:

find . -mindepth 2 -type f -name 'Makefile' 是一个 shell 命令,它在当前目录的任何子目录 (-mindepth 2) 中查找所有名为 Makefile (-name 'Makefile') 的文件 (-type f)。

$(shell CMD) 是将shell 命令CMD 传递给shell 并返回结果的make 函数。

$(dir LIST)返回LIST的所有路径的目录部分。

SUBDIRS := $(dir ...) 将所有这些分配给 make 变量 SUBDIRS(将 SUBDIRS 替换为您想要的任何名称,它只是一个名称)。所以,如果你有两个名为foobar/baz 的子目录,并且如果它们包含一个名为Makefile 的文件,find . -mindepth 2 -type f -name 'Makefile' 返回foo/Makefile bar/baz/Makefile,而SUBDIRS := $(dir $(shell find . ...))foo bar/baz 分配给make 变量SUBDIRS .

.PHONY: $(SUBDIRS) all 声明 make 变量 SUBDIRS 的值中的任何名称加上 all 都是 目标:也就是说,它们不是真正的文件名(即使文件或具有这些名称的目录实际上存在),并且当被要求时,make 将重建它们,即使它们已经存在并且就其先决条件而言是最新的。

all: $(SUBDIRS) 告诉 make all 目标依赖于 make 变量 SUBDIRS 的值中的所有名称;为了使all make 应首先使make 变量SUBDIRS 的值中的所有名称。

最后:

$(SUBDIRS):
    $(MAKE) -C $@

是一个 make 规则,它解释了如何在 make 变量 SUBDIRS 的值中创建任何名称。配方 ($(MAKE) -C $@) 只包含再次调用 make ($(MAKE)) 但在 $@ 目录 (-C $@) 中。您必须使用$(MAKE) 而不仅仅是make 的原因可以在GNU make 文档中找到。 $@ 是许多 make 自动变量之一。在配方中它扩展为当前目标。所以,如果SUBDIRS make 变量的值是foo bar/baz,则这条规则与两条单独的规则相同:

foo:
    $(MAKE) -C foo

bar/baz:
    $(MAKE) -C bar/baz

【讨论】:

  • 你能解释一下SUBDIRS := $(dir $(shell find . -mindepth 2 -type f -name 'Makefile'))是什么。 SUBDIRS 是 make 构造还是环境变量,什么是 .PHONY 以及为什么你使用 $(MAKE) -C $@。我认为-C是在读取makefile之前更改目录但是$@是什么?
  • @Alex SUBDIRS 是一个 make 变量。 shell 指示 make 使用 shell 调用 find 以生成名称列表,dir 去除尾随路径组件。 .PHONY 告诉 make SUBDIRSall 都不是真正的目标。您使用 $(MAKE) -C 在 SUBDIRS 中列出的每个目录中重新调用正确的 MAKE。 $@ 是导致配方运行的目标的名称。
猜你喜欢
  • 2021-10-19
  • 2017-08-19
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 2019-06-26
  • 2018-10-16
  • 2021-03-04
  • 1970-01-01
相关资源
最近更新 更多