Проблема с обработкой файлов сборки в операторе Makefile — include?

#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 нетронутым.

ОБНОВЛЕНИЕ: Чтобы быть более точным в отношении временной шкалы,

  1. make , увидев -include $(MY_DEP) , решает, что он может переделать запрошенный .s.so файл из неявного правила; на данный момент ошибок нет, даже если его нельзя было переделать
  2. строит .s.so отображение выходных данных из @echo , но не из $(CC) командной строки (так $(Q) @ как, похоже, расширяется до); ошибок пока нет
  3. считывает и анализирует файл .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) ).