多个文件扩展名的 Makefile 通配符规则

Makefile wildcard rules for multiple file extensions

我在一个目录中有许多汇编和 C 源文件。我已经提到了要编译为 C_OBJFILESASM_OBJFILES 的文件列表。我已将规则添加为

%.o: %.S
    $(AS) $(ASFLAGS) -o $@ $<

%.o: %.c
    $(CC) $(CFLAGS) -o $@ $<

用于生成目标文件。一些程序集文件具有 .s 扩展名。有些有 .S 和剩余的 .asm。有没有办法在单个规则中指定这些不同的扩展名而不是单独的 %.o:%.asm 和 %.o:%.s?

虽然可以在make之前通过一个简单的prename来解决,但我想探索一下Makefile的选项。下面是我写的完整的Makefile。

ASM_OBJLIST:=startup.o vectors.o lowlevel.o
C_OBJLIST:=test.o
LD_SCRIPT:=test.ld

CROSS_COMPILE:=arm-none-eabi-
AS:=$(CROSS_COMPILE)as
CC:=$(CROSS_COMPILE)gcc
LD:=$(CROSS_COMPILE)ld
OBJCOPY:=$(CROSS_COMPILE)objcopy

CFLAGS:= -c -mcpu=arm926ej-s -g
ASFLAGS:= -mcpu=arm926ej-s -g

BIN_TARGET:=test.bin

$(BIN_TARGET): $(C_OBJLIST) $(ASM_OBJLIST)
    $(LD) -T $(LD_SCRIPT) -o $@.elf $^
    $(OBJCOPY) -O binary $@.elf $@

%.o: %.S
    $(AS) $(ASFLAGS) -o $@ $<

%.o: %.c
    $(CC) $(CFLAGS) -o $@ $<

clean:
    rm -f *.o *.elf *.bin

如果可以在单个规则中处理多个扩展名,我可以只对所有源文件使用 gcc,而不必费心使用 as。 (我猜的)

使用静态模式并将对象分成两组,还有许多其他改进

  • Make 已经有 ASCC 之类的默认值,请使用它们。
  • 您已经正确使用 ASFLAGSCFLAGS-c 除外,见下文),其他标志也使用相同的模式
  • 你错过了表达 bin->elf 依赖的机会
  • 即使需要重新定义规则(LINK.oCOMPILE.c已经有-c标志)也可以回收内置配方,虽然.c 规则目前是多余的,因为它与内置规则完全相同。
  • 干净应该是PHONY
  • 从不 删除带有 * 的内容,只明确删除您负责的文件。

我只想使用 GCC 来 link,但如果您需要 link 和 LD,那么您需要更改配方。


ASM_OBJLIST := startup.o
S_OBLIST    := vectors.o lowlevel.o
C_OBJLIST   := test.o
LD_SCRIPT   := test.ld

CROSS_COMPILE := arm-none-eabi-

AS      := $(CROSS_COMPILE)$(AS)
CC      := $(CROSS_COMPILE)$(CC)
OBJCOPY := $(CROSS_COMPILE)objcopy

CFLAGS   := -mcpu=arm926ej-s -g
ASFLAGS  := -mcpu=arm926ej-s -g
LDFLAGS  := -Wl,-T $(LD_SCRIPT)
OBJFLAGS := -O binary 

BIN_TARGET := test.bin

$(BIN_TARGET): $(BIN_TARGET).elf
    $(OBJCOPY) $(OBJFLAGS) $< $@

$(BIN_TARGET).elf: $(C_OBJLIST) $(ASM_OBJLIST)
    $(LINK.o) $^ $(LDLIBS) -o $@

$(ASM_OBJLIST): %.o: %.asm
$(S_OBJLIST): %.o: %.S
$(ASM_OBJLIST) $(S_OBJLIST):
    $(COMPILE.S) -o $@ $<

%.o: %.c
    $(COMPILE.c) -o $@ $<

.PHONY: clean
clean:
    $(RM) $(C_OBJLIST) $(ASM_OBJLIST) $(BIN_TARGET).elf $(BIN_TARGET)