You are not logged in.

#1 2016-11-03 13:56:15

bstaletic
Member
Registered: 2014-02-02
Posts: 658

[SOLVED] Help needed for writing my first big Makefile

In the past few days I've been playing with, what's supposed to be, my first useful had written Makefile. The only thing I'm not absolutely sure I'm doing right is dependencies on header files. Basically, what I'm trying to ask is how to make sure that make will notice a change in header file, compile the appropriate object file and relink anything that needs relinking.

I'll post a simplified Makefile that reflects my use case, but if anyone asks for the actual Makefile from my project I can post that too.

Top level directory structure:

bstaletic@localhost makefiletest % ls
libopencm3  test1  test2  generated.STM32F407VG.ld  linker.ld.d  main.bin  main.c  main.d  main.elf  main.map  main.o  make_def.mk  Makefile

Directories test1 and test2:

test1:
Makefile  test.c  test.d  test.h  test.o

test2:
Makefile  test.c  test.d  test.h  test.o

Top level Makefile:

PROJDIR := ${HOME}/Temp/makefiletest/
BOARD := STM32F407VG

OBJ := main.o test1/test.o test2/test.o

main.bin: main.elf
        arm-none-eabi-objcopy -Obinary $< $@

main.elf : generated.$(BOARD).ld $(OBJ)
        $(CC) --static -nostartfiles -Tgenerated.$(BOARD).ld $(MFLAGS) -Wl,-Map=main.map -Wl,--gc-sections $(LINK_PATH) $(OBJ) $(LINK_LIB) $(LINK_GROUP) -o $@

generated.$(BOARD).ld :
        $(CC) -E $(CFLAGS) -P -E ${PROJDIR}/libopencm3/ld/linker.ld.S > $@

flash: main.bin
        st-link write $< 0x8000000

dodoc:
        doxygen $(DOXYFILE)

include $(PROJDIR)/make_def.mk
.PHONY: dodoc flash

The sourced make_def.mk:

AR := arm-none-eabi-ar
CC := arm-none-eabi-gcc
CFLAGS := -Os -g -Wall -Wextra -pedantic -x c -std=c99 -mfloat-abi=hard -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -DSTM32F4 -DSTM32F407VG -DSTM32F4CCM -D_ROM_OFF=0x08000000 -D_ROM=1024K -D_RAM=128K -D_CCM=64K -D_CCM_OFF=0x10000000 -D_RAM_OFF=0x20000000 -fno-common -fdata-sections -MD -I${PROJDIR}/libopencm3/include
PROJDIR := ${HOME}/Temp/makefiletest
LINK_GROUP := -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
LINK_PATH := -L${PROJDIR}/libopencm3/lib
LINK_LIB := -lopencm3_stm32f4

DOXYFILE := $(PROJDIR)/Doxyfile

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


clean:
        rm -rf *.o
        rm -rf *.elf
        rm -rf *.bin
        rm -rf generated.*.ld
        rm -rf *.map
        rm -rf lib*.a
        rm -rf *.d

-include *.d
.PHONY: clean

Every other Makefile in a subdirectory:

include $(PROJDIR)/make_def.mk

So I am passing '-MD' to gcc and it does create appropriate .d files with all the dependencies defined correctly. Are my Makefiles dealing with dependencies appropriately?
Another question I have: How do I make a rule that will clean every subdirectory, not just the one "make clean" has been run in? I could hack up something using something like "find", but I can't believe there's no elegant way of doing it.

Any other suggestions are welcome too.

Note: This is embedded project and only bare-metal programming is possible, that's why I did not bother with making anything a library. Maybe it's just me, but I don't see an advantage of making a bunch of static libraries over just using the produced object files.

Last edited by bstaletic (2016-11-03 22:10:11)

Offline

#2 2016-11-03 22:09:40

bstaletic
Member
Registered: 2014-02-02
Posts: 658

Re: [SOLVED] Help needed for writing my first big Makefile

I've found the issue. The Makefile, as it is written in the post above, has dependancy resolution, but is only halfway working. That is because the "-include *.d" line in make_def.mk made make only see the *.d files in the directory the modified file resides. What is actually needed is to have all *.d file from the whole project included at once. After doing that, the dependancy resolution woked as expected. Now to just figure out a non-hackish way to include everything I should.

So the modified files look like this:

make_def.mk:

CC := arm-none-eabi-gcc
CFLAGS := -Os -g -Wall -Wextra -pedantic -x c -std=c99 -mfloat-abi=hard -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -DSTM32F4 -DSTM32F407VG -DSTM32F4CCM -D_ROM_OFF=0x08000000 -D_ROM=1024K -D_RAM=128K -D_CCM=64K -D_CCM_OFF=0x10000000 -D_RAM_OFF=0x20000000 -fno-common -fdata-sections -MD -MP -I${PROJDIR}/libopencm3/include -I${PROJDIR}
PROJDIR := ${HOME}/Temp/makefiletest
LINK_GROUP := -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
LINK_PATH := -L${PROJDIR}/libopencm3/lib
LINK_LIB := -lopencm3_stm32f4

DOXYFILE := $(PROJDIR)/Doxyfile

DEPS := main.d test1/test.d test2/test.d

-include $(DEPS)

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


clean:
        rm -rf *.o
        rm -rf *.elf
        rm -rf *.bin
        rm -rf generated.*.ld
        rm -rf *.map
        rm -rf lib*.a
        rm -rf *.d

.PHONY: clean

Top level Makefile:

PROJDIR := ${HOME}/Temp/makefiletest/
DESTDIR := ${PROJDIR}/build/
BOARD := STM32F407VG

OBJ := main.o test1/test.o test2/test.o

${DESTDIR}main.bin: main.elf
        arm-none-eabi-objcopy -Obinary $< $@

main.elf : generated.$(BOARD).ld $(OBJ)
        $(CC) --static -nostartfiles -Tgenerated.$(BOARD).ld $(MFLAGS) -Wl,-Map=main.map -Wl,--gc-sections $(LINK_PATH) $(OBJ) $(LINK_LIB) $(LINK_GROUP) -o $@

generated.$(BOARD).ld :
        $(CC) -E $(CFLAGS) -P -E ${PROJDIR}/libopencm3/ld/linker.ld.S > $@

flash: main.bin
        st-link write $< 0x8000000

dodoc:
        doxygen $(DOXYFILE)

include $(PROJDIR)/make_def.mk
.PHONY: dodoc flash

Rest of the Makefiles:

PROJDIR := ${HOME}/Temp/makefiletest
include $(PROJDIR)/make_def.mk

Offline

#3 2016-11-04 04:21:13

eschwartz
Fellow
Registered: 2014-08-08
Posts: 4,097

Re: [SOLVED] Help needed for writing my first big Makefile

DEPS := $(OBJ:.o=.d)

might be slightly more reusable (for future-proofing updates)

And the "clean" target could also take advantage of reusing the variable(s) specifically meant to keep track of generated files. Which once again properly handles the issue of dealing with subdirectories.


Managing AUR repos The Right Way -- aurpublish (now a standalone tool)

Offline

#4 2016-11-04 08:57:20

bstaletic
Member
Registered: 2014-02-02
Posts: 658

Re: [SOLVED] Help needed for writing my first big Makefile

That sounds like a good idea. And the clean target idea does seem neat. I'll see what I can do. Thanks for the suggestions.

Offline

Board footer

Powered by FluxBB