Makefile未执行多个目标

时间:2019-01-19 14:54:14

标签: makefile

我将在此处更新标题和内容,以明确说明此特定问题是我在其他地方未明确回答的问题。关键概念是要理解,看起来像单个目标在Makefile中执行多项操作的事情实际上是多个目标各自执行一项操作。

我还将删除一些无关紧要的内容,因为最终这些内容无关紧要。

原始内容

我的问题是我有一个Makefile,(显然)没有正确调用我的子目录Makefile之一。我有一个这样的项目结构:

quendor
  src
    cheap
      cheap_init.c
      Makefile

    zmachine
      main.c
      Makefile

  Makefile  

项目根目录中的Makefile将引用各个目录中的Makefile。这是该核心Makefile:

CC ?= gcc

CFLAGS += -Wall -std=c99
CFLAGS += -D_POSIX_C_SOURCE=200809L
CFLAGS += -O2 -fomit-frame-pointer

RANLIB ?= $(shell which ranlib)
AR ?= $(shell which ar)

export CC
export AR
export CFLAGS
export RANLIB

SRC_DIR = src

ZMACHINE_DIR = $(SRC_DIR)/zmachine
ZMACHINE_LIB = $(ZMACHINE_DIR)/quendor_zmachine.a

CHEAP_DIR = $(SRC_DIR)/cheap
CHEAP_LIB = $(CHEAP_DIR)/quendor_cheap.a

SUB_DIRS = $(ZMACHINE_DIR) $(CHEAP_DIR)

SUB_CLEAN = $(SUB_DIRS:%=%-clean)

$(SUB_DIRS):
    @echo $(SUB_DIRS)   # src/zmachine src/cheap
    @echo "DIR:"
    @echo $@            # src/zmachine
    $(MAKE) -C $@

$(SUB_CLEAN):
    -$(MAKE) -C $(@:%-clean=%) clean

clean: $(SUB_CLEAN)

help:
    @echo "Quendor"

.PHONY: $(SUB_DIRS) $(SUB_CLEAN) clean help

对我来说,一个关键问题是上面的内容:

$(SUB_DIRS):
    @echo $(SUB_DIRS)   # src/zmachine src/cheap
    @echo "DIR:"
    @echo $@            # src/zmachine
    $(MAKE) -C $@

我仅使用echo语句来说明正在发生的事情。注意$SUB_DIRS正确显示了两个目录,但是在Makefile运行时,它仅显示src/zmachine。 (其中的注释表明我在运行时看到的内容。)Makefile(显然)不会处理src/cheap

运行的Makefile的完整输出如下(前三行是我的echo语句):

src/zmachine src/cheap
DIR:
src/zmachine
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C src/zmachine
cc -Wall -std=c99 -D_POSIX_C_SOURCE=200809L -O2 -fomit-frame-pointer -fPIC -fpic -o main.o -c main.c
ar rc quendor_zmachine.a main.o
/usr/bin/ranlib quendor_zmachine.a
** Done with Quendor Z-Machine.

我最初唯一想到的是,也许在src/zmachine中运行了子Makefile之后,Make进程要么出错,要么认为它已经完成。但我想,$(SUB_DIRS)部分应该已经遍历两个目录。

所以我对如何进行操作有些困惑。

附加说明:我所说的“我会认为”部分是我不正确的地方。 $(SUB_DIRS)没有像我想象的那样被执行;接受的答案已经澄清了这一点。

1 个答案:

答案 0 :(得分:2)

制造的方式是,如果不提供参数,则将首先扫描Makefile寻找“默认目标” 。默认目标只是它遇到的第一个目标(注意,它是第一个 target ,而不是 targets )。

根据您的情况,规则:

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

等效于:

src/zmachine src/cheap:
    $(MAKE) -C $@

等同于:

src/zmachine:
    $(MAKE) -C $@
src/cheap:
    $(MAKE) -C $@

因此遇到的第一个目标是src/zmachine,这是它的默认目标,也是要处理的目标。如user657267在评论中所述,解决此问题的方法是添加一个您将首先处理的目标,该目标将其他目标(您确实要构建)作为先决条件。