Comprehensive Report On Using Makefiles in STM32 E
Comprehensive Report On Using Makefiles in STM32 E
Introduction to Makefiles
A Makefile is a script used to automate the compilation and linking of source code files,
particularly in C/C++ projects [1] [2] [3] . It defines rules for building targets (e.g., executables)
based on dependencies (e.g., .c or .h files) and executes commands only when dependencies
change [2] [4] . For example:
Here, main.out is the target, main.c and hello.c are prerequisites, and the command compiles
them into an executable [1] [5] .
Core Components
STM32 projects require cross-compilation using the ARM GCC toolchain. A Makefile for STM32
typically includes:
1. Toolchain Configuration
Define paths and flags for the ARM compiler:
CC = arm-none-eabi-gcc
CFLAGS = -mcpu=cortex-m4 -mthumb -IInc
LDSCRIPT = STM32F767ZITx_FLASH.ld # Linker script for memory layout[^2][^6][^13]
The -mcpu flag specifies the Cortex-M core, while -I adds include directories [6] [7] .
2. Source and Object File Management
Use wildcards to collect source files and generate object files:
SRCDIR = Src
SOURCES = $(wildcard $(SRCDIR)/*.c)
OBJECTS = $(patsubst %.c, Build/%.o, $(SOURCES))
This compiles .c files into .o objects stored in a Build directory [8] [6] .
3. Build Rules
Rules compile source files and link them into an executable:
firmware.elf: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $@ -T$(LDSCRIPT)
Build/%.o: Src/%.c
$(CC) -c $(CFLAGS) $< -o $@
$^ represents all prerequisites, and $< is the first prerequisite [1] [9] .
flash:
st-flash write firmware.bin 0x08000000
This writes the binary to the STM32’s flash memory [6] [10] .
Conditional Compilation
Makefiles support conditional logic to enable/disable features:
#ifdef DEBUG
log("Debug mode active");
#endif
2. Custom Code
Place user code in separate directories (e.g., User/) to avoid overwrites during
regeneration [12] .
Advanced Techniques
1. Modular Makefiles
Split configurations into common.mk and include them:
include common.mk
SOURCES += User/app.c
2. Dependency Automation
GCC’s -MMD flag generates .d files tracking header dependencies:
CFLAGS += -MMD
-include $(OBJECTS:.o=.d)
3. Multi-Configuration Builds
Support debug/release builds:
BUILD_TYPE = RELEASE
ifeq ($(BUILD_TYPE), DEBUG)
CFLAGS += -g
else
CFLAGS += -O3
endif
# Toolchain
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
# Flags
CFLAGS = -mcpu=cortex-m7 -mthumb -IInc -I$(STM32_CUBE_PATH)
LDFLAGS = -TSTM32F767ZITx_FLASH.ld
# Files
SOURCES = Src/main.c Startup/startup_stm32.s
OBJECTS = $(addprefix Build/,$(notdir $(SOURCES:.c=.o)))
# Targets
all: firmware.elf
firmware.elf: $(OBJECTS)
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
Build/%.o: Src/%.c
$(CC) -c $(CFLAGS) $< -o $@
clean:
rm -rf Build/*.o firmware.elf
flash: firmware.elf
st-flash write firmware.bin 0x08000000
This compiles code, links using the STM32 linker script, and supports flashing [6] [7] [10] .
2. Dependency Tracking
Issue: Manual dependency tracking is error-prone.
Fix: Use GCC’s -MMD flag to auto-generate dependencies [6] [10] .
3. Toolchain Compatibility
Issue: Projects fail if the toolchain path is incorrect.
Fix: Set TOOLCHAIN_PATH in the Makefile:
TOOLCHAIN_PATH = /opt/arm-gcc/bin
Best Practices
1. Separate Build Artifacts
Store .o and .elf files in a Build/ directory to avoid clutter [6] [10] .
2. Use Variables
Define compiler flags and paths as variables for easy updates [2] [3] .
3. Automate Flashing
Include flash and debug targets for one-click deployment [6] [10] .
4. Leverage STM32CubeMX
Generate boilerplate code with CubeMX but maintain custom logic in separate files [12] .
Conclusion
Makefiles streamline STM32 development by automating compilation, linking, and flashing. Key
steps include:
1. Configuring the ARM toolchain.
2. Defining build rules for source files.
3. Integrating linker scripts and conditional logic.
4. Managing dependencies and modular code.
For small projects, handwritten Makefiles offer flexibility. For complex systems, combine
STM32CubeMX’s code generation with custom Makefile rules [10] [12] . By adhering to best
practices, developers can ensure efficient, maintainable builds for embedded systems.
⁂
1. https://www.youtube.com/watch?v=U1I5UY_vWXI
2. https://www3.nd.edu/~zxu2/acms60212-40212/Makefile.pdf
3. https://web.stanford.edu/class/archive/cs/cs107/cs107.1174/guide_make.html
4. https://makefiletutorial.com
5. https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_makefiles.html
6. https://james919.github.io/makefile-mcu
7. https://electronics.stackexchange.com/questions/193438/makefile-for-stm32
8. https://stm32-base.org/concepts/makefiles.html
9. https://stackoverflow.com/questions/1484817/how-do-i-make-a-simple-makefile-for-gcc-on-linux
10. https://github.com/bbrown1867/stm32-makefile
11. https://www.linkedin.com/pulse/introduction-makefiles-beginners-guide-mohammad-shadab-abedin-k
b5wc
12. https://community.st.com/t5/stm32cubemx-mcus/help-managing-stm32cubemx-auto-generate-makefil
es/td-p/225171