Skip to content
Makefile template for Cortex-M projects using the GCC ARM Embedded toolchain.
Branch: master
Clone or download

CM-Makefile: Makefile template for Cortex-M projects

Makefile template for ARM Cortex-M projects using the GCC ARM Embedded toolchain. The template is meant to be included in project-specific Makefile.

See repository cm-makefile-examples for usage examples.


To successfully compile and debug the project, you need:

  • Linux desktop (OS X should work as well)
  • GCC ARM Embedded toolchain
  • MCU vendor's HAL (start-up code, register definitions, ...)

Optional software:

Installation instructions are described in a separate file.


First, create Makefile. The Makefile should link to source files outside the project's source directory (such as libraries provided by the manufacturer) and include *.mk files from the CM-Makefile project. For example:

BIN = hello                     # Name of the output binary
SDK_DIR = ../mcu-vendor         # Target-specific library

INC = -I$(SDK_DIR)/inc
SRC_ASM = $(SDK_DIR)/src/startup.S
SCR_C = $(SDK_DIR)/src/system.c
SRC_LD = $(SDK_DIR)/target.ld

OPENOCD = openocd -f board/my_board.cfg

include cm-makefile/
include cm-makefile/  # For flash, debug and gdb targets
include cm-makefile/

See the cm-makefile-examples repository for real-world examples.

Then simply run make to compile the project and make flash to upload it to the target.

The process will create .elf, .hex and .bin binaries in the build directory together with other files useful for debugging:

  • .disasm: Disassembly output
  • .sym: Name list (useful to check memory layout)
  • .map: Linker map (useful to check linked object files, discarded sections, etc.)

To use a specific toolchain (other than the default arm-none-eabi), simply set the CROSS_COMPILE variable:

make CROSS_COMPILE=/usr/local/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-

Flashing and debugging

To flash the program using OpenOCD, run make flash. To reset the CPU, run make reset.

To debug the project, run make gdb (which starts OpenOCD's GDB server) followed by make debug in a different terminal (which starts GDB in TUI mode).

It is also possible to use the Eclipse standalone debugger using make cdtdebut. The debugger has to be available as cdtdebug. If it isn't, simply change the CDTDEBUG variable.


The configuration is quite straightforward. Most of variables used in and can be modified by the project-specific Makefile. For example:

  • INC: Include path for header files (-I*.h) or linker scripts (-L*.ld)
  • SRC_ASM: Assembly source files (*.S, *.s) outside the current directory (e.g. target-specific startup code)
  • SRC_C: C source files (*.c) outside the current directory
  • SRC_LD: Linker script (*.ld)
  • DEF: Custom macros (-DMACRO equals to #define MACRO)
  • ARCHFLAGS: CPU architecture (see below)
  • FPFLAGS: FLoating point configuration (see below)
  • WARNFLAGS: GCC warning options. You can define your own set of options or disable the unwanted ones by appending -Wno-* flags
  • DBGFLAGS: GCC debugging options (-ggdb by defualt)
  • OPTFLAGS: GCC optimization options (-O3 by defualt)
  • PREPFLAGS: GCC preprocessor options (-MD -MP by defualt)
  • OPENOCD: OpenOCD command (with script selection) to set up debug session. You can use one of the built-in scripts or create your own.

Configuration for a different target

CM-Makefile can be easily used with a different CPU core than the default Cortex-M0. It's only necessary to configure the ARCHFLAGS and FPFLAGS variables (FPFLAGS defaults to -mfloat-abi=soft):

Cortex-M0 (default) -mcpu=cortex-m0 -mfloat-abi=soft
Cortex-M0+ -mcpu=cortex-m0plus -mfloat-abi=soft
Cortex-3 -mcpu=cortex-m3 -mfloat-abi=soft
Cortex-M4 (Soft FP) -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16
Cortex-M4 (Hard FP) -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16


CM-Makefile is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

See COPYING and COPYING.LESSER for details.

You can’t perform that action at this time.