Monday, July 13, 2026

CMakeLists.txt for building STM8 projects with SDCC

A short guide to CMakeLists.txt for building STM8 projects with SDCC.

The goal is to produce two output files: .elf for debugging and .ihx for flashing the chip.

The overall workflow is as follows:
* configure CMake to use SDCC as the build tool
* set the correct compiler and linker options
* build the *.elf
* convert the *.elf into binary data in *.ihx

Next, I go through the key parts in more detail, and at the end you’ll find the complete CMakeLists.txt file. I’ll note upfront: I’m using CMake version 4.2.3, but the solution should also work on relatively newer versions, I haven’t tested older releases.

First, we need to define the platform and the fact that SDCC will be used as the compiler. CMake already knows about SDCC out of the box and can work with it, but we will use it in a slightly different way than the default behavior.

set (CMAKE_SYSTEM_NAME Generic)
set (CMAKE_C_COMPILER sdcc)

These settings must be defined before the project(...) call appears in CMakeLists.txt.

project (cmake_empty C)

In this SDCC/CMake setup, the default output extension is .ihx, so we override it.

set (CMAKE_EXECUTABLE_SUFFIX ".elf")

The target and the compile/link options are added in the usual way. However, it’s especially important to highlight the compiler option -mstm8. SDCC may generate code for a different architecture such as Z80 or 8051. This kind of build mistake is easy to miss, and troubleshooting efforts are usually first directed toward problems in the firmware source code. Make sure you pass -mstm8, otherwise SDCC may target the wrong architecture.

Then we force the SDCC output format to .elf; SDCC typically emits .ihx.

target_link_options (${PROJECT_NAME}
    PRIVATE "--out-fmt-elf"
)

At the end, we generate the .ihx file from the .elf file using stm8-objcopy from the stm8-binutils-gdb package. I describe how to build stm8-binutils-gdb on Ubuntu 26.04 with GCC 15 in a separate note. Adding a custom command and target for .ihx conversion is usually straightforward and does not require further comments.

If you don't have stm8-objcopy, there is an alternative way to generate .ihx and .elf files: you can add two separate executable targets for each format. However, this solution is not ideal, as your IDE may show duplicate source trees.

A small note: I like having more build information, so I set CMAKE_VERBOSE_MAKEFILE to ON and add --verbose to the SDCC compile flags. If you prefer, you can remove these settings to keep the build log more compact.

Full CMakeLists.txt

cmake_minimum_required (VERSION 3.10)

set (CMAKE_SYSTEM_NAME Generic)
set (CMAKE_C_COMPILER sdcc)

project (cmake_empty C)

set (CMAKE_VERBOSE_MAKEFILE  ON)
set (CMAKE_EXECUTABLE_SUFFIX ".elf")

add_executable (${PROJECT_NAME} main.c)

# mandatory key option, SDCC compiler port specification stm8, z80, 8051 etc.
target_compile_options (${PROJECT_NAME} PRIVATE -mstm8)
target_compile_options (${PROJECT_NAME}
    PRIVATE --all-callee-saves
            --stack-auto
            --float-reent
            --std=c23
            --no-peep
            --verbose
            --debug
)
# SDCC can produce .elf only for stm8 platform
target_link_options (${PROJECT_NAME}
    PRIVATE -mstm8
            --out-fmt-elf
)

set (FULL_IHX_PATH "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.ihx")

find_program (SDOBJCOPY NAMES stm8-objcopy REQUIRED)
add_custom_command (
    OUTPUT "${FULL_IHX_PATH}"
    COMMAND ${SDOBJCOPY} -O ihex
            $<TARGET_FILE:${PROJECT_NAME}>
            ${FULL_IHX_PATH}
    DEPENDS ${PROJECT_NAME}
    COMMENT "Converting ELF to Intel HEX using ${SDOBJCOPY}..."
)
add_custom_target ("${PROJECT_NAME}-inx" ALL DEPENDS "${FULL_IHX_PATH}")

No comments:

Post a Comment