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.s
source 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,
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- builds the
.s.so
displaying the output from@echo
but not the$(CC)
command line (since$(Q)
expands to@
, it seems); no errors yet - 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)
).