Including External Libraries in CMake Projects
Learn how to use CMake’s FetchContent module to automatically download and integrate libraries like CMSIS into your embedded projects, eliminating the hassle of manual copying and updates.
The straight forward way to include libraries is to manually copy them from source to destination. This is relatively easy to do, but managing and updating the library later might be a pain. To make this process more automated, CMake has a handy module called FetchContent which can automatically download and make libraries available to the project.
A common module that any ARM cortex project needs is the CMSIS package. In most cases, it is copied manually, but let's see an example on how to do it with CMake's FetchContent module.
# ====================================================================
# Includes
# ====================================================================
include(FetchContent)
# ====================================================================
# CMSIS Component and Setup
# ====================================================================
FetchContent_Declare(
CMSIS
GIT_REPOSITORY https://github.com/ARM-software/CMSIS_6.git
GIT_TAG v6.1.0
)
FetchContent_MakeAvailable(CMSIS)
# Add CMSIS include paths
# --------------------------------------------------------------------
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
${cmsis_SOURCE_DIR}/CMSIS/Core/Include
${cmsis_SOURCE_DIR}/Device/ARM/ARMCM0/Include
)
This CMake script will download CMSIS version 6 from GitHub and make the required ARM M0 controller directories available to the project (this is an example usage; if another core is used, the include paths must be updated).
Once CMake parses and runs the script, we will have the source of the library download under _deps directory.
Inside this directory, there we will find three additional directories for each library we include:
<library>-build: This directory contains the results of the build process for the library. If the library includes its own build targets, such as static or shared libraries, they will be placed in this directory.<library>-src: Contains the actual source code of the library as it was downloaded or cloned from the repository. It includes all the original files, directories, and submodules exactly as they appear in the source repository.<library>-subbuild: Used by CMake to manage the build process of the library in isolation. It contains a standalone CMake build system specifically for the library.
CMake will download and configure the library for each build target. It is possible to change the dependency target directory with FETCHCONTENTBASEDIR environment variable.
If the library is more complex, lets say FreeRTOS, the integrator must make sure that all the required compile and link options, and defines are provided to the library when compiled.
From Feature Tetris to Full Power – The UV-K5 Flex PCB Brain Hack
The Quansheng UV-K5 makes you play firmware feature Tetris with its tiny MCU. In this project, we perform some embedded brain surgery—replacing it with an STM32 via a custom flex PCB for more flash, RAM, and possibilities.
Debugging Microsecond Delays on STM32: When 1 µs Isn’t What It Seems
Why your STM32 timer-based microsecond delays may not work as you expect. Discover how Cortex-M0+ pipelines and timer register updates can affect your timing. Learn ways to correct these issues.
Remote View Raspberry Pi Camera Stream with Docker
Learn how to containerize the Raspberry Pi Camera Module using MediaMTX and Docker for low-latency remote debugging and visual feedback directly in VS Code.
Whether you're building something new, fixing stability issues, or automating what slows your team down — we can help.