Makefile не работает для нескольких файлов c, но работает для одного файла c

Этот make-файл предназначен для создания шестнадцатеричного файла для микроконтроллера ARM. Мой makefile берет все файлы c, хранящиеся в папке, и генерирует шестнадцатеричный файл. Шестнадцатеричный файл, файлы .obj и т. д. помещаются в папку bin.

Мои make-файлы работают нормально (т. е. я могу видеть шестнадцатеричный файл, файлы .obj и т. д.), когда в папке есть только один файл c. Но если я помещу в папку более одного файла c, сборка завершится ошибкой. Ниже приведена ошибка, которую я получаю, когда у меня есть более одного файла c.

arm-none-eabi-gcc: error: main.o: No such file or directory
make: *** [32bitTimer.elf] Error 1

Я прилагаю свой make-файл для справки.

Не могли бы вы сообщить мне, почему это не работает для нескольких файлов c?

## makefile

BINARY   = 32bitTimer
LDSCRIPT = stm32f4-discovery.ld

SRCS     = $(wildcard *.c)
OBJDIR   = bin

PREFIX  = arm-none-eabi
CC  = $(PREFIX)-gcc
LD  = $(PREFIX)-gcc
OBJCOPY = $(PREFIX)-objcopy
OBJDUMP = $(PREFIX)-objdump
GDB = $(PREFIX)-gdb

TOOLCHAIN_DIR ?= ../libopencm3

CFLAGS      += -Os -g \
            -Wall -Wextra -Wimplicit-function-declaration \
            -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
            -Wundef -Wshadow \
            -I$(TOOLCHAIN_DIR)/include \
            -fno-common -mcpu=cortex-m4 -mthumb \
            -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -DSTM32F4
LDFLAGS     += --static -lc -lnosys -L$(TOOLCHAIN_DIR)/lib \
            -L$(TOOLCHAIN_DIR)/lib/stm32/f4 \
            -T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
            -mthumb -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
OBJS        = $(SRCS:.c=.o)

# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q := @
endif

all: $(OBJDIR) $(BINARY).images

%.images: %.elf
    $(Q)$(OBJCOPY) -Obinary $(OBJDIR)/$(*).elf   $(OBJDIR)/$(*).bin
    $(Q)$(OBJCOPY) -Oihex   $(OBJDIR)/$(*).elf   $(OBJDIR)/$(*).hex
    $(Q)$(OBJCOPY) -Osrec   $(OBJDIR)/$(*).elf   $(OBJDIR)/$(*).srec
    $(Q)$(OBJDUMP) -S       $(OBJDIR)/$(*).elf > $(OBJDIR)/$(*).list

$(BINARY).elf:  $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f4.a
    $(Q)$(LD) -o $(OBJDIR)/$(BINARY).elf $(OBJDIR)/$(OBJS) -lopencm3_stm32f4 $(LDFLAGS)

%.o:%.c
    $(Q)$(CC) $(CFLAGS) -o $(OBJDIR)/$@ -c $<

$(OBJDIR):
    $(Q)mkdir $(OBJDIR)

clean:
    $(Q)rm -rf $(OBJDIR)

.PHONY: images clean

person robomon    schedule 23.12.2013    source источник


Ответы (1)


Это, вероятно, самая прямая проблема: в строке, которая начинается с $(Q)$(LD) -o $(OBJDIR), у вас есть текст:

$(OBJDIR)/$(OBJS)

Это не делает то, что вы (кажется) ожидаете. Это просто добавляет строковое значение $(OBJDIR) к строковому значению $(OBJS). На самом деле это не префикс каждого слова в последнем. Вместо этого вы, вероятно, хотите сказать следующее:

$(patsubst %,$(OBJDIR)/%,$(OBJS))

который будет ставить перед каждым словом в $(OBJS) значение $(OBJDIR), за которым следует косая черта.

person danfuzz    schedule 23.12.2013
comment
Еще один вопрос. Не могли бы вы ответить. Каждый раз, когда я делаю make, файлы компилируются снова и снова, хотя исходные файлы не изменяются. Насколько я понимаю, make будет компилировать только те файлы, которые были изменены. В первый раз, когда мы запустим make, он сгенерирует шестнадцатеричный файл. Но в следующий раз, если мы запустим, он должен показать какое-то предупреждение о том, что нет правила для создания цели (я не помню точное предупреждение). Знаете, почему его не показывают? Это потому, что я создаю шестнадцатеричный файл в папке, отличной от исходной? - person robomon; 24.12.2013
comment
Трудно сказать, что происходит без дополнительной информации. Подумайте о том, чтобы опубликовать еще один вопрос, чтобы вы могли конкретизировать его с помощью примера кода make-файла и стенограммы запуска. - person danfuzz; 24.12.2013
comment
Причина почти наверняка в том, что ваше правило компилировать .o файлов совершенно неверно. Но danfuzz прав, вы должны задать другой вопрос, указав соответствующие детали, такие как точные сообщения об ошибках и т. д. - person MadScientist; 27.12.2013