Home > database >  Handling assembly files in Makefile - include statement problem?
Handling assembly files in Makefile - include statement problem?

Time:12-09

Here are parts of a 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)

The MDOPT is defined as MDOPT = -MMD -MF $(1).

I needed to add assembly .asm.ssource files, so I added:

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

However, when trying to compile the sources, it gave me error:

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

I have found the following fix - remove the last line in the Makefile: -include $(MY_DEP).

What caused the error?
Why did removal of the -include line fix the problem? What is the purpose of this line at all?

CodePudding user response:

What caused the error?

The error message suggests a syntax error in the binary file out/myfile.asm.s.o. The error isn't detected at include time because the -include directive was used (try info make include, near the end). myfile.asm.s is appended to MY_SRC, and out/myfile.asm.s.o therefore to MY_OBJ and MY_DEP. The binary file gets included because MY_DEP := $(MY_OBJ:.c.o=.c.d) leaves .s.o intact.

UPDATE: To be more precise about the timeline,

  1. make, on seeing -include $(MY_DEP), decides it can remake the requested .s.so file from an implicit rule; no errors at this point, even if it could not be remade
  2. builds the .s.so displaying the output from @echo but not the $(CC) command line (since $(Q) expands to @, it seems); no errors yet
  3. reads and parses the .s.so as a makefile, fails on line 1, and terminates with an error message (end UPDATE)

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

It skips reading out/myfile.asm.s.o which isn't a makefile.

What is the purpose of this line at all?

See info make 'Automatic Prerequisites'.

CodePudding user response:

The problem was resolved in two steps:

  • MY_DEP := $(MY_OBJ:.c.o=.c.d) did not take in the .s assembly files. This was fixed with:
MY_DEP_TEMP := $(MY_OBJ:.c.o=.c.d)
MY_DEP  = $(MY_DEP_TEMP:.s.o=.s.d)
  • Additional target for compiling .s files needed to be changed in order to generate .d files:
$(BUILD_PATH)/%.s.o: %.s
    @echo "  AS     $<"
    $(AS) $< -c $(ASFLAGS) $(call MDOPT_ASM,$(@:.s.o=.s.d)) -o $@

Special care needed to be taken with respect to MDOPT_ASM which needed to be defined as MDOPT_AS = -MD $(1), which is different then the one for .c targets (MDOPT_C = -MMD -MF $(1)).

  • Related