在 Makefile 中处理汇编文件 - 包含语句问题?

Handling assembly files in Makefile - include statement problem?

以下是 Makefile 的部分内容:

MY_SRC += \
    scr1.c \
    src2.c \
    src3.c

BUILD_PATH=outdir
MY_OBJ := $(addprefix $(BUILD_PATH)/,$(addsuffix .o, $(MY_SRC)))
MY_DEP := $(MY_OBJ:.c.o=.c.d)

.
.
.
$(BUILD_PATH)/%.c.o: %.c
    @echo "  CC      $<"
    $(CC) $< -c $(CFLAGS) $(call MDOPT,$(@:.c.o=.c.d)) -o $@
.
.
.

-include $(MY_DEP)

MDOPT定义为MDOPT = -MMD -MF $(1)

我需要添加程序集.asm.s源文件,所以我添加了:

MY_SRC += myfile.asm.s
.
.
.
$(BUILD_PATH)/%.s.o: %.s
    @echo "  ASM     $<"
    $(Q)$(CC) $< -c $(CFLAGS) -o $@

但是,在尝试编译源代码时,出现错误:

ASM myfile.asm.s out/myfile.asm.s.o:1: *** missing separator.  Stop.

我找到了以下修复方法 - 删除 Makefile 中的最后一行: -include $(MY_DEP).

错误原因是什么?
为什么删除 -include 行可以解决问题?这行的目的是什么?

What caused the error?

错误信息提示二进制文件存在语法错误 out/myfile.asm.s.o。在包含时未检测到错误,因为 使用了 -include 指令(尝试 info make include,靠近 结尾)。 myfile.asm.s 附加到 MY_SRC,并且 out/myfile.asm.s.o 因此 MY_OBJMY_DEP。包含二进制文件 因为 MY_DEP := $(MY_OBJ:.c.o=.c.d) 使 .s.o 完好无损。

更新:为了更准确地说明时间线,

  1. make,看到 -include $(MY_DEP),决定重新制作 从隐式规则请求 .s.so 文件;没有错误 点,就算不能重制
  2. 构建 .s.so 显示 @echo 的输出但不显示 @echo 的输出 $(CC) 命令行(似乎是 $(Q) 扩展为 @);还没有错误
  3. 读取并解析 .s.so 作为 makefile,在第 1 行失败,并且 以错误消息终止 (end UPDATE)

Why did removal of the -include line fix the problem?

它跳过阅读 out/myfile.asm.s.o ,它不是 makefile。

What is the purpose of this line at all?

参见 info make 'Automatic Prerequisites'

分两步解决了问题:

  • MY_DEP := $(MY_OBJ:.c.o=.c.d) 没有接受 .s 汇编文件。这是固定的:
MY_DEP_TEMP := $(MY_OBJ:.c.o=.c.d)
MY_DEP += $(MY_DEP_TEMP:.s.o=.s.d)
  • 为了生成 .d 个文件,需要更改编译 .s 个文件的其他目标:
$(BUILD_PATH)/%.s.o: %.s
    @echo "  AS     $<"
    $(AS) $< -c $(ASFLAGS) $(call MDOPT_ASM,$(@:.s.o=.s.d)) -o $@

需要特别注意 MDOPT_ASM,它需要定义为 MDOPT_AS = -MD $(1),它不同于 .c 目标(MDOPT_C = -MMD -MF $(1) ).