0

This makefile is for making hex file for an ARM micro-controller. My makefile takes all the c files kept in the folder and generates the hex file. The hex file, .obj files etc. are placed in the bin folder.

My makefiles works fine(i.e I am able to see the hex file, .obj files etc.) when there is only one c file inside the folder. But if I place more than one c file in the folder, build fails. Below is the error what I get when I have more than one c file.

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

I am attaching my makefile for reference.

Could you please let me know why it doesn't work for multiple c files ?

## 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
Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
robomon
  • 269
  • 2
  • 16

1 Answers1

1

This is probably the most direct problem: On the line that starts $(Q)$(LD) -o $(OBJDIR) you have the text:

$(OBJDIR)/$(OBJS)

This does not do what you (seem to) expect. This just appends the string value of $(OBJDIR) to the string value of $(OBJS). It isn't actually prefixing each word in the latter. You probably want instead to say this:

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

which will prefix each word in $(OBJS) with the value of $(OBJDIR) followed by a slash.

danfuzz
  • 4,253
  • 24
  • 34
  • One more question. Could you please answer. Each time when I do a make, the files are getting compiled again and again even though the source files are not changed. As per my understanding, make will only compile the files which are only changed. For the first time when we run make, it will generate hex file. But next time if we run, it should show some warning saying "No rule to make target" (I don't remember the exact warning). Do you know why it is not shown ? Is it because I am building the hex in a different folder than source ? – robomon Dec 24 '13 at 03:40
  • 1
    Hard to tell what's going on without more info. Consider posting another question, so you can flesh this out with example makefile code and a transcript of the run. – danfuzz Dec 24 '13 at 16:15
  • 1
    The reason is almost certainly that your rule to compile `.o` files is quite wrong. But danfuzz is correct, you should ask another question providing the appropriate details such as the exact error messages, etc. – MadScientist Dec 27 '13 at 07:24