如何在makefile中指定多个目标?

如何在makefile中指定多个目标?,makefile,Makefile,我使用的make版本如下: $make-v GNU Make 4.3 专为x86_64-pc-cygwin构建 版权所有(C)1988年至2020年自由软件基金会。 许可证GPLv3+:GNU GPL版本3或更高版本 这是自由软件:您可以自由更改和重新发布它。 在法律允许的范围内,不提供任何担保。使用模式规则的一个示例: SRC_DIR := ../../src/hello ASM_TARGETS := hellomain.s sayhello.s .PHONY: all clean al

我使用的make版本如下:

$make-v
GNU Make 4.3
专为x86_64-pc-cygwin构建
版权所有(C)1988年至2020年自由软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。

在法律允许的范围内,不提供任何担保。
使用模式规则的一个示例:

SRC_DIR := ../../src/hello
ASM_TARGETS := hellomain.s sayhello.s

.PHONY: all clean

all: $(ASM_TARGETS)

# build .s file from .c file placed in a specified source dir
%.s: $(SRC_DIR)/%.c
    gcc -S $^ -o $@

clean:
    rm -f $(ASM_TARGETS)

使用模式规则的一个示例:

SRC_DIR := ../../src/hello
ASM_TARGETS := hellomain.s sayhello.s

.PHONY: all clean

all: $(ASM_TARGETS)

# build .s file from .c file placed in a specified source dir
%.s: $(SRC_DIR)/%.c
    gcc -S $^ -o $@

clean:
    rm -f $(ASM_TARGETS)

您应该始终提供您正在使用的GNU make版本和正在运行的操作系统

我最好的猜测是您使用的是不支持
&:
语法的较旧版本的GNU make。您需要GNU make 4.3才能使用此功能

最好阅读操作系统附带的GNU make手册版本,因为该版本与您正在使用的GNU make版本相关。此外,您还可以查看新闻文件,了解添加功能的时间:


您应该始终提供您正在使用的GNU make版本和运行的操作系统

我最好的猜测是您使用的是不支持
&:
语法的较旧版本的GNU make。您需要GNU make 4.3才能使用此功能

最好阅读操作系统附带的GNU make手册版本,因为该版本与您正在使用的GNU make版本相关。此外,您还可以查看新闻文件,了解添加功能的时间:


首先,
make
识别默认目标,而不是默认规则。默认目标是文件中出现的第一个不以
和大写字母开头的目标。如果运行
make
时未指定要生成的目标,则它假定您希望生成默认目标,在您的情况下,即
hellomain.s
。(并且只有
hellomain.s
,即使在指定多个目标的规则中出现。)

因此,
make
为您展示的行为是完全正常的,尽管使用了分组目标规则(见下文)。您运行
make
时没有指定目标,因此它会解释您想要构建默认目标。该目标已存在并且是最新的。makefile中描述的另一个目标丢失与此无关。如果您想用当前的makefile重建它,那么您可以非常明确地告诉
make

make sayhello.s
现在,我们来谈谈分组目标规则。请注意,对这些的支持是

  • 特定于较新版本的GNU
    make
    ,并且在大多数
    make
    实现中不可用,例如,在撰写本文时,包括许多Linux发行版中包含的GNU
    make
    版本

  • 不适用于您所使用的用途

  • 分组目标规则解决了
    make
    设计的一个长期问题:如何描述不可避免地一起创建的目标。典型的例子可能是
    yacc
    bison
    的输出:一个C源文件和相应的头文件,两者都是由同一程序的一次运行一起生成的。您可能还没有使用
    make
    的经验,无法理解用传统的
    make
    s来正确描述这一点有多么困难,但在GNU
    make
    4.3及更高版本中它很简单

    你人为地造成了类似的情况。不要那样做。如果您想通过一个规则构建多个目标,那么惯用的方法是为它们提供自己的规则,并将它们命名为同一规则的先决条件。此外,在这种情况下,将默认目标命名为“所有”是常规做法,尽管不是强制性的。例如:

    src_prefix = ../../src/hello
    
    all: hellomain.s sayhello.s
    
    hellomain.s : $(src_prefix)/hellomain.c
        gcc -S $(src_prefix)/hellomain.c -o hellomain.s
    
    sayhello.s : $(src_prefix)/sayhello.c
        gcc -S $(src_prefix)/sayhello.c -o sayhello.s
    
    clean : 
        -rm -f hellomain.s sayhello.s
    
    .PHONY : all clean
    
    并不是说makefile通常表现出良好的形式。出于教学目的,我一直将它与您的原作保持相当接近,但如果我正在编写它,并假设GNU make,那么我可能会使用更类似的内容:

    src_prefix = ../../src/hello
    
    # A variable naming the targets, so I don't need to repeat the list, or risk
    # different copies getting out of sync:
    ASSEMBLY_TARGETS = hellomain.s sayhello.s
    
    # specify the assembler command as a variable, near the top, to enable it to be
    # easily changed:
    AS = gcc -S
    
    # default target named "all", with all targets I want to build as its prerequisites    
    all: $(ASSEMBLY_TARGETS)
    
    # One pattern rule covering both targets.  Pattern rules are GNU-specific, but
    # I already stipulated that I'm writing for GNU make
    %.s : $(src_prefix)/%.c
        $(AS) $^ -o $@
    
    # The clean rule also relies on the ASSEMBLY_TARGETS variable, so that we don't need
    # to repeat the target list explicitly here.
    clean : 
        -rm -f $(ASSEMBLY_TARGETS)
    
    .PHONY : all clean
    

    首先,
    make
    识别默认目标,而不是默认规则。默认目标是文件中出现的第一个不以
    和大写字母开头的目标。如果运行
    make
    时未指定要生成的目标,则它假定您希望生成默认目标,在您的情况下,即
    hellomain.s
    。(并且只有
    hellomain.s
    ,即使在指定多个目标的规则中出现。)

    因此,
    make
    为您展示的行为是完全正常的,尽管使用了分组目标规则(见下文)。您运行
    make
    时没有指定目标,因此它会解释您想要构建默认目标。该目标已存在并且是最新的。makefile中描述的另一个目标丢失与此无关。如果您想用当前的makefile重建它,那么您可以非常明确地告诉
    make

    make sayhello.s
    
    现在,我们来谈谈分组目标规则。请注意,对这些的支持是

  • 特定于较新版本的GNU
    make
    ,并且在大多数
    make
    实现中不可用,例如,在撰写本文时,包括许多Linux发行版中包含的GNU
    make
    版本

  • 不适用于您所使用的用途

  • 分组目标规则解决了
    make
    设计的一个长期问题:如何描述不可避免地一起创建的目标。典型的例子可能是
    yacc
    bison
    的输出:一个C源文件和相应的头文件,两者都是由同一程序的一次运行一起生成的。您可能还没有使用
    make
    的经验来理解描述是多么困难