【问题标题】:Master Makefile for Subprojects Won't Compile Subprojects子项目的主 Makefile 不会编译子项目
【发布时间】:2009-03-28 15:14:53
【问题描述】:

我有一个正在发布的项目,它实际上包含 3 个子项目,所有这些子项目都需要一次性编译。我的 makefile 大致如下:

all: a b c

a:
    @cd a && make

b:
    @cd b && make

c:
    @cd c && make

项目 A 和 B 都编译得很好,但是对于第三个项目,它告诉我没有什么可做的,尽管切换到 C 目录并运行 make 实际上可以编译代码。

更具体一点:上例中的项目 C 实际上是 Mozilla 的 SpiderMonkey。 A 和 B 是我编写的代码/makefile,而 C 只是来自 Mozilla 网站的 SpiderMonkey 的原始副本。它的实际编译命令是:

make JS_DIST=/usr JS_THREADSAFE=1 JS_HAS_FILE_OBJECT=1

在我的主 Makefile 中,我有:

spidermonkey:
    @cd spidermonkey/src && $(MAKE) JS_DIST=/usr JS_THREADSAFE=1 JS_HAS_FILE_OBJECT=1

运行“make spidermonkey”会输出“make: Nothing to be done for `spidermonkey'。”如何让 make 运行命令?

编辑: 我尝试将以下几行添加到我的 makefile 中:

.PHONY: spidermonkey

以及将spidermonkey规则重命名为sm,但仍然没有变化。

编辑: 我的错!当我应该有一个标签时,我有空格。呵呵!

【问题讨论】:

  • make 中的 TAB 与空格问题有点棘手,但大多数现代 make 编辑器(例如 Emacs)非常清楚地突出显示应该有制表符的空格。 Emacs 甚至不会在不询问您是否真的需要空格的情况下让您保存。

标签: makefile compilation


【解决方案1】:

您可能在顶层有一个名为“spidermonkey”的文件或目录。 Make 认为这是它应该创造的东西,既然它已经在那里,那就停下来。

在编写 makefile 时要遵循的最重要的规则之一是每个目标都应该创建一个与目标同名的文件。换句话说,如果你有

 a:
       <some command>

该命令应该生成一个名为“a”的文件。

不生成文件但仅作为占位符存在的规则称为虚假目标,它们应该这样声明:

 .PHONY: a

Make 将始终假定必须重新制作 a。

此外,作为一般规则不要使用“make”递归调用 make,而是使用 $(MAKE)

编辑:将“伪”更改为“假”

【讨论】:

  • 我怀疑您在回答中将 .PSEUDO 与 .PHONY 混淆了! (改变它,你会得到我的 +1 :-))
  • 澄清一下:Jesper 的回答很好,只是他的“伪目标”实际上被称为“伪目标”并且由“.PHONY:”而不是“.PSEUDO:”声明。
  • 感谢 JesperE。我已经更新了我的问题。不幸的是,.PHONY 并没有改变 make 行为。不知道为什么。
【解决方案2】:

Make 只检查与规则目标名称相同的文件(或目录)是否存在,如果存在(并且它比依赖项更新),那么从 make 的角度来看,没有什么可做的了。

所以你的问题是你有一个 spidermonkey 规则(没有依赖项)以及一个名为 spidermonkey 的目录,然后 make 认为“目标已经完成,我无事可做”。要让 make 做你想做的事,重命名 spidermonkey 规则(或目录)。

顺便说一下递归make,这不一定是个好主意, 见Recursive Make Considered Harmful

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2013-12-17
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多