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

Posted

技术标签:

【中文标题】在 Makefile 中处理汇编文件 - 包含语句问题?【英文标题】:Handling assembly files in Makefile - include statement problem? 【发布时间】:2022-01-09 00:00:22 【问题描述】:

这是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.ssource 文件,所以我添加了:

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 行可以解决问题?这条线的目的到底是什么?

【问题讨论】:

include 之前可能没有空行。很难通过 *** 解决空白问题,特别是如果您不提供完整的确切文件。 @Jester 我确实有空行。事实上,我什至没有触及 Makefile 的最后几行。如上所述,我只添加了.s 支持。 out/myfile.asm.s.o 被包括在内,因为MY_DEP := $(MY_OBJ:.c.o=.c.d) 没有将.s.o 转换为.d 是的,很好!即使是这样,我想知道 .d 文件是否为汇编正确生成。 虽然 gnu 汇编器确实支持通过 -MD 生成依赖项,但 gcc 似乎没有调用它。您只需要编写一个单独的规则来直接通过汇编程序生成依赖项。 【参考方案1】:

是什么导致了错误?

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

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

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

为什么删除-include 行可以解决问题?

它跳过读取out/myfile.asm.s.o 这不是一个makefile。

这条线的目的是什么?

info make 'Automatic Prerequisites'

【讨论】:

【参考方案2】:

问题分两步解决:

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)
编译.s文件的附加目标需要更改以生成.d文件:
$(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)) 不同。

【讨论】:

以上是关于在 Makefile 中处理汇编文件 - 包含语句问题?的主要内容,如果未能解决你的问题,请参考以下文章

编写一个通用的Makefile文件

cmake 怎么配置才能生成预编译文件和汇编文件

makefile

嵌入式Linux—浅析Makefile

makefile--回顾基础篇

在makefile中生成汇编文件