Getting started with Raspberry Pico and CMake

What is CMake about?

  • Configuring: CMake is the tool to configure your project. You call it from the top-level directory with cmake -B build -S ., where build is the output directory, and ./ the directory with the root level cmake file.
  • Compiling: You will build your project using the make command, and this command uses Makefiles that were generated by CMake.
  • Building: You will also build executable files that link to your library code and/or external libraries. This is also done with the make command, and the Makefiles will include all the defined build options of your CMake configuration.
  • main config: The top-level directory includes the root CMake file. This file needs to set essential config options, and it will list all additional directories that will be included when you execute CMake.
  • library config: Directories in which you just build a library, you will put a config file that includes the add_library directive. During the compilation process, you will product library files, which are typically named lib.a.
  • executable config: In directories in which you have executable code, you will put a config file that contains the directive add executable. During building, you will have one and only one C file with a main() method, and the result will be named file.out

Main CMake Config File

cmake_minimum_required(VERSION 3.12)include($ENV{PICO_SDK_PATH}/pico_sdk_init.cmake)
  • cmake_minimum_version A flag that controls the compatibility of your CMake files with a specific version
  • project The name of this CMake file, its used throughout the build chain
  • add_subdirectory List any other directories that contain a CMakeLists.txt file

Library CMake Config File

file(GLOB FILES *.c *.h)add_library(pico-shift-register ${FILES})target_link_libraries(pico-shift-register pico_stdlib)target_include_directories(pico-shift-register PUBLIC ../include/)
  • file: Collect all files that need to be compiled. You can use a GLOB function as shown here, or explicitly mention the specific files
  • add_library: With this declaration, you express the intent to build a library. The first argument, here its pico-shift-register, is the name of the library, the second argument are the files that will be compiled to create your library.
  • target_link_libraries If you link with other libraries, list them here
  • target_include_directories Libraries need to publish their header files so that you can import them in source code. This statement expresses where to find the files - typically in an include directory of your projects.

Executable CMake Config File

add_executable(8_led_blink 8_led_blink.c)target_link_libraries(8_led_blink pico_stdlib pico-shift-register)pico_add_extra_outputs(8_led_blink)
  • add_executable Defines the intent to create an executable file (.bin, .uf2 etc.), the first argument is the name, the second argument are the source files.
  • target_link_libraries As before, the names of all additional libraries that you want to link with your executable.

Build Commands

# Configure
cmake -B build -S .
# Build the library / produces libpico-shift-register.a.
make -C build/src
# Build the examples / produces 8_led_blink.elf, .uf2 etc.
make -C build/examples




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store