#c #assembly #makefile #gnu-make
#c #собрание #сделать файл #gnu-сделать
Вопрос:
Вот некоторые части 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 $lt;" $(CC) $lt; -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 $lt;" $(Q)$(CC) $lt; -c $(CFLAGS) -o $@
Однако при попытке скомпилировать исходные тексты это дало мне ошибку:
ASM myfile.asm.s out/myfile.asm.s.o:1: *** missing separator. Stop.
Я нашел следующее исправление — удалите последнюю строку в файле Makefile: -include $(MY_DEP)
.
Что вызвало ошибку?
Почему удаление -include
линии устранило проблему? Какова вообще цель этой линии?
Комментарии:
1. У вас, вероятно, не было пустой строки до
include
этого . Трудно устранить проблемы с пробелами с помощью stackoverflow, особенно если вы не предоставляете полный точный файл.2. @Jester У меня действительно была пустая строка. На самом деле, я даже не коснулся последних строк файла Makefile. Я только добавил
.s
поддержку, как указано выше.3.
out/myfile.asm.s.o
включается, потомуMY_DEP := $(MY_OBJ:.c.o=.c.d)
что не преобразуется.s.o
в.d
?4. Да, хороший улов! Даже если бы это было так, мне интересно, правильно ли
.d
сгенерированы файлы для сборки.5. Хотя ассемблер gnu поддерживает генерацию зависимостей через
-MD
, gcc, похоже, не вызывает его. Вам просто нужно будет написать отдельное правило для создания зависимостей непосредственно через ассемблер.
Ответ №1:
Что вызвало ошибку?
Сообщение об ошибке указывает на синтаксическую ошибку в двоичном файле out/myfile.asm.s.o
. Ошибка не обнаружена во время включения, потому -include
что использовалась директива (попробуйте info make include
, ближе к концу). myfile.asm.s
добавляется к MY_SRC
, и out/myfile.asm.s.o
, следовательно, к MY_OBJ
и MY_DEP
. Двоичный файл включается, потому MY_DEP := $(MY_OBJ:.c.o=.c.d)
что остается .s.o
нетронутым.
ОБНОВЛЕНИЕ: Чтобы быть более точным в отношении временной шкалы,
make
, увидев-include $(MY_DEP)
, решает, что он может переделать запрошенный.s.so
файл из неявного правила; на данный момент ошибок нет, даже если его нельзя было переделать- строит
.s.so
отображение выходных данных из@echo
, но не из$(CC)
командной строки (так$(Q)
@
как, похоже, расширяется до); ошибок пока нет - считывает и анализирует файл
.s.so
как файл создания, завершается ошибкой в строке 1 и завершается сообщением об ошибке (завершение ОБНОВЛЕНИЯ).
Почему удаление
-include
линии устранило проблему?
Он пропускает чтение, которое не является файлом создания. out/myfile.asm.s.o
Какова вообще цель этой линии?
Видеть 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 $lt;" $(AS) $lt; -c $(ASFLAGS) $(call MDOPT_ASM,$(@:.s.o=.s.d)) -o $@
Необходимо было проявлять особую осторожность в отношении MDOPT_ASM
того , что необходимо было определить как MDOPT_AS = -MD $(1)
, что отличается от того, что относится к .c
целям ( MDOPT_C = -MMD -MF $(1)
).