CMake 101


Pin-Hao Chen
2025/04/30

Outline

  • What is CMake?
  • CMake Basics
    • Top Level File
    • Toolchain File
  • Demo

What is CMake?

What is CMake?

  • CMake is meta-build system.
  • CMake create configuration files for a build system.
  • Examples of build system:
    • Unix Makefiles
    • NMake Makefiles
    • Ninja

CMake Basics

Let's take a look at our CMake Project Structure:


						cortex-m-cmake-demo/
						    library/
						        bsp/
						        CMakeLists.txt
						    source/
						        main.c
						    armclang.cmake
						    CMakeLists.txt
					

				
Top Level File

The minimum version


						cmake_minimum_required(VERSION 3.21)
					

It decides the features that can be used.

It dictates the policies, which introduce behavior changes while preserving backward compatibility.

Top Level File

Project declaration


						project(demo
							VERSION 1.0.0
							DESCRIPTION "This is a demo project"
						)
					

The project() call sets up the project name.

The project name is stored in PROJECT_NAME.

Top Level File

Language Setting


						enable_language(C ASM)
					

We are going to use C and Assembly for this project.

Top Level File

Language Setting


						set(CMAKE_C_STANDARD 11)
						set(CMAKE_C_STANDARD_REQUIRED ON)
						set(CMAKE_C_EXTENSIONS OFF)
					

It specifies the language standard to compile for
i.e. -std=c11

The default is gnu11, which may cause different behavior in ARMClang.

Toolchain File

armclang.cmake


						set(CMAKE_SYSTEM_NAME Generic)
					

It indicates we are cross-compiling for bare metal embedded devices.

Toolchain File

armclang.cmake


						set(CMAKE_ASM_COMPILER "armclang")
						set(CMAKE_CXX_COMPILER "armclang")
						set(CMAKE_C_COMPILER "armclang")

						set(CMAKE_AR "armar")
						set(ARM_ELF2BIN "fromelf")
					

The compilers to use for ASM and C

Toolchain File

armclang.cmake


						set(CMAKE_C_COMPILER_TARGET arm-arm-none-eabi)
					

This will cause CMake to add the --target flag.

Toolchain File

armclang.cmake


						set(CMAKE_C_FLAGS_INIT "-mthumb -fdata-sections -fno-exceptions -g ")
						set(CMAKE_ASM_FLAGS_INIT "-mthumb -masm=auto --target=arm-arm-none-eabi -g")
					

CMake offer a variable cache. The official manual describes how CMake searches for variables.

CMAKE_<LANG>_FLAGS_INIT initialize the CMAKE_<LANG>_FLAGS cache entry. It is meant to be set by a toolchain file.

Toolchain File

armclang.cmake


						set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
					

Whenever CMake starts it tries to compile a sample program.

Using STATIC_LIBRARY avoids running the linker.

Top Level File

Adding BSP library


						add_subdirectory(library)
					

The CMakeLists file contained in that subdirectory is evaluated.

The CMakeLists in the subdirectory create a static library called bsp. We will discuss how to add a static library in the future.
Top Level File

Adding the Executable


						set(EXECUTABLE ${PROJECT_NAME})
					

This creates a variable containing the executable name.

Top Level File

Adding the Executable


						add_executable(${EXECUTABLE}
							source/main.c
						)
					

The executable target is added here.

Top Level File

Chain targets


						target_link_libraries(${EXECUTABLE}
							PRIVATE
								bsp
						)
					

We link the bsp libraries to the executable.

PRIVATE is used since the executable is the topmost product.

Understanding Scope


								# Focus on CortexM23Lib here
								target_link_libraries(CortexM23Lib
									PUBLIC
										CortexMLib
								)
							
    Current Targets (CortexM23Lib)
  • Can use symbols (functions, variables, etc.) from CortexMLib
  • Inherits include directories, compile definitions, and link libraries

Understanding Scope


								# Focus on CortexM23Lib here
								target_link_libraries(CortexM23Lib
									PUBLIC
										CortexMLib
								)

								target_link_libraries(M2354Lib
									PUBLIC
										CortexM23Lib
								)

								target_link_libraries(M2351Lib
									PUBLIC
										CortexM23Lib
								)
							
    Current Targets (CortexM23Lib)
  • Can use symbols (functions, variables, etc.) from CortexMLib
  • Inherits include directories, compile definitions, and link libraries
    Dependent Targets (M2354Lib, M2351Lib)
  • Automatically get the link dependency on CortexMLib
  • Also inherit include directories, compile definitions, and link libraries

Understanding Scope

Scope Applies to Current Target Applies to Dependent Target
PUBLIC ✅ Used by current target ✅ Propagate up to dependent targets
PRIVATE ✅ Used by current target ❌ Not propagated
INTERFACE ❌ Not used by current target ✅ Propagate up to dependent targets
Top Level File

Linker Option


						target_link_options(${EXECUTABLE}
							PRIVATE
								--library_type=microlib
								--scatter=${CMAKE_CURRENT_SOURCE_DIR}/scatter/m2354.sct
								--map
						)
					

Put link flags for our executable

We need to provide scatter file (linker script). It tells the linker where to store the objects in memory.

Top Level File

Post-build commands


						add_custom_command(TARGET ${EXECUTABLE}
							POST_BUILD
							COMMAND ${ARM_ELF2BIN} --bin ${EXECUTABLE}.elf --output ${EXECUTABLE}.bin
						)
					

This creates a custom command to generate binary file.

Demo

Reference

Thank You