多个规则指定同一个假依赖,依赖只执行一次

发布于 2024-08-01 13:07:32 字数 463 浏览 4 评论 0原文

我有一个关于下面的 GNU makefile 示例的问题:

.PHONY: $(subdirs) build x y

subdirs =  a b c

build: x y

x: target=prepare
x: $(subdirs)

y: target=build
y: $(subdirs)

$(subdirs):
    $(make) -f $@/makefile $(target)

当我运行 make 时,我希望为每个指定目标“prepare”然后指定目标“build”的子目录调用 make。 不幸的是, $(subdirs) 目标执行一次(成为“准备”目标),但不会为“构建”目标再次执行。

对于规则 x,make 似乎确定需要运行 $(subdirs) 目标,但对于规则 y,$(subdirs) 目标是最新的。

有没有什么办法解决这一问题?

谢谢!

I have a question regarding the GNU makefile example below:

.PHONY: $(subdirs) build x y

subdirs =  a b c

build: x y

x: target=prepare
x: $(subdirs)

y: target=build
y: $(subdirs)

$(subdirs):
    $(make) -f $@/makefile $(target)

When I run make, I expect make to be called for each sub-directory specifying the target 'prepare' then the target 'build'. Unfortunately, the $(subdirs) target executes once (making the 'prepare' target), but doesn't execute again for the 'build' target.

It appears that for rule x, make determines the $(subdirs) target needs to be run, but for rule y, the $(subdirs) target is up-to-date.

Is there any way to fix this?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

弄潮 2024-08-08 13:07:33

与您的尝试相比,我更喜欢 Ville 的方法。
通常有两种方法可以使用不同的参数进行多次运行。

  1. 编写外部脚本(或者像 Ville 的想法一样在外部 Makefile 中进行迭代)
    • 在每个子 Makefile 中编写一个 all 规则来运行 prepare,然后运行 ​​build
    • 这会将 prepare+build 组合集成到子 Makefile 中,
      您只需从外部 Makefile 运行 all —— 更加模块化。

在这个示例中,您可以轻松地得到不必要的复杂 Makefile

I prefer Ville's method over your attempt.
There are generally two ways to get a multiple run with varying arguments.

  1. Write an outer script (or, like Ville's idea iterate within the outer Makefile)
    • Write an all rule in each sub-Makefile to run prepare followed with build
    • this will integrate the prepare+build combination within the sub-Makefiles and,
      you would be just running an all from the outer Makefile -- much more modular.

This is one example where you can easily land up with an unnecessarily complex Makefile

入画浅相思 2024-08-08 13:07:33

您发布的 makefile 似乎假设 $(subdirs) 目标的命令将运行两次:一次针对 x,第二次针对 y< /代码>。 不幸的是,这不是 makefile 和依赖项的工作方式。 每次 make 调用最多运行一次目标命令(除非出现异常情况,例如在 make 运行期间修改 makefile 时)。

以下内容将适用于 UNIX 风格的系统。 它只是循环运行子目录,一个接一个:

subdirs = a b c

.PHONY: build
build:
    for dir in $(subdirs); do \
      $(MAKE) -f $dir/makefile prepare; \
      $(MAKE) -f $dir/makefile build; \
    done

如果您需要并行构建子目录,您可以使用以下内容:

subdirs = a b c

.PHONY: build
build: $(addprefix build-,$(subdirs))

define submake-rule
  .PHONY: build-$(1)
  build-$(1):
    $(MAKE) -f $(1)/makefile prepare
    $(MAKE) -f $(1)/makefile build
endef

$(foreach dir,$(subdirs),$(eval $(call submake-rule,$(dir))))

这为每个子目录定义了一个规则 build- $(subdirs) 中的项目,并使 build 目标依赖于所有这些项目。 作为一个额外的好处,它也可以移植到 Windows,而不需要使用 Cygwin bash shell 或类似的。 缺点是比较难理解。

The makefile you posted seems to assume that the commands for the $(subdirs) target would be run two times: once for x and a second time for y. Unfortunately, that's not how makefiles and dependencies work. The commands for a target are run at most once per make invocation (barring unusual circumstances, such as when makefiles are modified during the make run).

The following will work on UNIX -style systems. It simply runs the subdirectory makes in a loop, one after each other:

subdirs = a b c

.PHONY: build
build:
    for dir in $(subdirs); do \
      $(MAKE) -f $dir/makefile prepare; \
      $(MAKE) -f $dir/makefile build; \
    done

If you need to build the subdirectories in parallel, you can use the following:

subdirs = a b c

.PHONY: build
build: $(addprefix build-,$(subdirs))

define submake-rule
  .PHONY: build-$(1)
  build-$(1):
    $(MAKE) -f $(1)/makefile prepare
    $(MAKE) -f $(1)/makefile build
endef

$(foreach dir,$(subdirs),$(eval $(call submake-rule,$(dir))))

This defines a rule build-<dirname> for each item in $(subdirs), and makes the build target depend on all of them. As an added bonus, this is portable to Windows as well, without requiring using a Cygwin bash shell or similar. The downside is that it's a bit harder to understand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文