SDK Setup and Build Overview
This guide covers SDK installation, manual environment setup, and primary workflows using CMake or STM32CubeIDE.
The focus is on a manual, transparent setup (no helper scripts required on Linux) so you can see exactly which tools are used and which environment variables are expected.
For platform architecture, see platform overview. For tutorials, see HelloWorld tutorial.
Prerequisites
Linux/macOS/Windows development machine
CMake 3.21+ (for manual builds)
A build tool:
make(Unix Makefiles)Python 3 + pip (for packaging/build utilities)
ST ARM GCC Toolchain (CRITICAL): STM32CubeIDE or STM32CubeCLT version required. System
gcc-arm-none-eabiis often incompatible (newlib syscall stubs such as_writecan be missing). See toolchain setup.TouchGFX (Windows-only for Designer): For GUI development - TouchGFX Designer requires Windows. See TouchGFX below.
USB cable for device flashing
Git for cloning the SDK
The rest of this document provides OS-specific, end-to-end setup sections (Linux/Windows) that follow the same flow:
Get required software → Prepare → Clone and setup environment → Copy example and build
Toolchain Setup
CRITICAL: Use STMicroelectronics GNU Tools for STM32 (from STM32CubeIDE or STM32CubeCLT).
The system gcc-arm-none-eabi shipped by many distros (often GCC 13+) is frequently incompatible with this SDK’s bare-metal/newlib expectations and may fail with undefined syscall stubs (_write, _close, etc.).
Linux Setup
Get required software
Git (clone + version string generation)
Python 3 + pip (packaging utilities)
CMake 3.21+
make
STM32CubeIDE or STM32CubeCLT (provides the ST
arm-none-eabi-gcctoolchain)
Install hints (keep it minimal; equivalents work on other distros):
# Ubuntu/Debian
sudo apt update
sudo apt install -y git python3 python3-pip cmake build-essential
Prepare
Toolchain (CubeIDE/CubeCLT) and PATH
Install the ST toolchain (choose one):
STM32CubeCLT (CLI-first):
chmod +x ~/Downloads/STM32CubeCLT_Linux64_v1-*.run ~/Downloads/STM32CubeCLT_Linux64_v1-*.run
STM32CubeIDE (IDE + toolchain): Download/install from: https://www.st.com/en/development-tools/stm32cubeide.html
Ensure the ST toolchain is on your
PATH.
If you installed CubeCLT, the toolchain is typically under:
export PATH="$HOME/.local/share/stm32cube/bundles/gnu-tools-for-stm32/*/bin:$PATH"
If arm-none-eabi-gcc is still not found and you installed CubeIDE, add the directory that contains arm-none-eabi-gcc to your PATH (it is usually a .../plugins/...gnu-tools-for-stm32.../tools/bin folder inside the CubeIDE installation).
Clone and setup environment
# Clone
git clone --recursive https://github.com/UNAWatch/una-sdk.git
cd una-sdk
# Export environment for the current shell
export UNA_SDK="$PWD"
# Satisfy python dependencies
python3 -m pip install -r "$UNA_SDK/Utilities/Scripts/app_packer/requirements.txt"
Verify your environment
This SDK expects the toolchain and build tools to be discoverable via PATH.
which arm-none-eabi-gcc || true
which cmake || true
which make || true
which python3 || true
python3 -m pip --version
arm-none-eabi-gcc --version || true
cmake --version || true
make --version || true
If which arm-none-eabi-gcc prints nothing, your ST toolchain bin directory is not on PATH yet. Add it (see Prepare above) and re-open your terminal.
Copy and Build an Existing Example
This section demonstrates how to copy an existing app example (Alarm) and build it without modifications to verify your setup. For creating and customizing a new app by modifying a copy, see “Creating New Apps” below.
This uses the same Alarm CMake example flow as Windows: copy project → create build dir → configure → build.
# Copy entire project for simplicity
cp -r "$UNA_SDK/Examples/Apps/Alarm/"* MyAlarm
# Create build dir
mkdir -p MyAlarm/build
# Configure
cmake -G "Unix Makefiles" -S MyAlarm/Software/Apps/Alarm-CMake -B MyAlarm/build
# Build
cmake --build MyAlarm/build
Optional (Linux)
Persist UNA_SDK and toolchain PATH
If you don’t want to export variables every time, add them to your shell profile.
For bash:
echo 'export UNA_SDK="$HOME/path/to/una-sdk"' >> ~/.bashrc
echo 'export PATH="$HOME/.local/share/stm32cube/bundles/gnu-tools-for-stm32/*/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
For zsh:
echo 'export UNA_SDK="$HOME/path/to/una-sdk"' >> ~/.zshrc
echo 'export PATH="$HOME/.local/share/stm32cube/bundles/gnu-tools-for-stm32/*/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Note about distro gcc-arm-none-eabi
If you installed gcc-arm-none-eabi from your distro repositories and builds fail with missing syscall stubs, switch to the ST toolchain from CubeIDE/CubeCLT and ensure its arm-none-eabi-gcc is the one found first in PATH.
Windows Setup
Get required software
Python 3 - Notes:
Enable “Add python.exe to PATH” checkmark
Click “Disable path length limit” after installation
STM32CubeIDE - Provides Toolchain, CMake, Make utilities (note: STM32CubeCLT does not includes
makeprogram, which is required)VS Code - IDE
Prepare
Clone and setup environment
# Clone via SSH
git clone --recursive git@github.com:UNAWatch/una-sdk.git
# Or use HTTPS
git clone --recursive https://github.com/UNAWatch/una-sdk.git
# Export environment (persistent)
# If you encounter a security error (e.g., running scripts is disabled), run this first:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
. ./una-sdk/Utilities/Scripts/export-stm32-tools.ps1
# Satisfy python dependencies
pip install -r ${env:UNA_SDK}/Utilities/Scripts/app_packer/requirements.txt
# If pip fails or dependencies are not found, verify Python is in PATH and restart PowerShell.
Reboot your PC or restart PowerShell to apply the environment variables. This ensures all changes take effect and may resolve issues like copy errors in later steps.
Copy and Build an Existing Example
This section demonstrates how to copy an existing app example (Alarm) and build it without modifications to verify your setup. For creating and customizing a new app by modifying a copy, see “Creating New Apps” below.
# Copy entire project for simplicity
# Note: The copied folder will retain original names like Alarm-CMake. Use the original name in commands below (e.g., Alarm-CMake instead of MyAlarm-CMake).
# If you get "Container cannot be copied onto existing leaf item" error, restart PowerShell and try again.
cp "${env:UNA_SDK}\Examples\Apps\Alarm\*" MyAlarm -Recurse -Force
# Create build dir
mkdir -p MyAlarm\build
# Call CMake
cmake -G "Unix Makefiles" -S MyAlarm/Software/Apps/Alarm-CMake -B MyAlarm/build
# Build
cmake --build MyAlarm/build
Troubleshooting Windows Setup
If you encounter errors like “include could not find requested file: /cmake/una-app.cmake” or “/cmake/una-sdk.cmake”, ensure the UNA_SDK environment variable is set. Run the export script with dot sourcing to apply it to the current shell: . ./una-sdk/Utilities/Scripts/export-stm32-tools.ps1. Reboot your PC or restart PowerShell if issues persist, as environment variables may not apply immediately.
If CMake reports “CMAKE_MAKE_PROGRAM is not set”, “CMAKE_C_COMPILER not set”, or “CMAKE_CXX_COMPILER not set”, even after setting environment variables, add the following compiler flags to the CMake command:
cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Generic -DCMAKE_C_COMPILER=arm-none-eabi-gcc -DCMAKE_CXX_COMPILER=arm-none-eabi-g++ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_ASM_COMPILER=arm-none-eabi-gcc -S MyAlarm/Software/Apps/Alarm-CMake -B MyAlarm/build
Then proceed with the build step: cmake --build MyAlarm/build.
CMake-Based Workflow Development
The CMake workflow is recommended for command-line control and is fully standalone. Apps reference the SDK via UNA_SDK and use relative paths for flexibility.
Examples/ Project Structure Overview
MyApp/ # App root (can be anywhere)
├── Software/
│ ├── Apps/
│ │ ├── MyApp-Service-CubeIDE/ # CubeIDE project with Service
│ │ ├── MyApp-GUI-CubeIDE/ # CubeIDE project with GUI
│ │ ├── MyApp-CMake/ # CMake project dir
│ │ │ ├── CMakeLists.txt
│ │ │ ├── MyAppService.ld # Linker script
│ │ │ └── syscalls.cpp
│ │ └── TouchGFX-GUI/ # For GUI apps
│ └── Libs/
│ ├── Header/ # Headers
│ └── Sources/ # Sources
├── Resources/
│ ├── icon_30x30.png
│ └── icon_60x60.png
└── Output/ # Built .uapp files
CMake Command Explanations
The CMake build process is a two-step procedure:
Configuration/Generation:
cmake -G "Unix Makefiles" -S <source-dir> -B <build-dir>generates intermediate build files (e.g., Makefiles) in the specified build directory. This step configures the project, resolves dependencies, sets compilers and paths, and prepares the build environment. Run this for initial setup or whenCMakeLists.txtchanges.Build/Compilation:
cmake --build <build-dir>(from any directory) ormake(inside the build directory) compiles the source code using the generated build files. Run this to build or recompile after source file modifications.
For a clean rebuild, remove the build directory and repeat both steps: rm -rf build && cmake -S . -B build && cmake --build build.
If build files are generated in the wrong directory (e.g., root instead of build dir), navigate to the correct build directory and run make or cmake --build . from there.
Creating New Apps
Copy CMake Template: To create a new app, copy an existing one from Examples/Apps (replace
with e.g., “Alarm” or “HRMonitor”). There are two ways: an easy way without renaming (no path changes needed) and an optional way to fully rename and reorganize. Easy Way (No Renaming, Minimal Changes):
# Copy the entire app folder cp -r "${UNA_SDK}/Examples/Apps/<app-name>" MyApp # Copy or create icons in MyApp/Resources/ if needed (required: icon_30x30.png, icon_60x60.png)
This keeps all original folder and file names. When building, use the original
-CMake in commands (e.g., cmake -S MyApp/Software/Apps/ -CMake -B MyApp/build). To adapt for your app:
Update APP_NAME and APP_ID in MyApp/Software/Apps/
-CMake/CMakeLists.txt (see step 2). For GUI apps: Open MyApp/Software/Apps/TouchGFX-GUI/
GUI.touchgfx in TouchGFX Designer, update project name if desired, and save as MyAppGUI.touchgfx.
Other references remain the same.
Optional: Full Rename and Reorganization (Customize Structure): If you want to match your app name or change folder structure:
# Create custom structure mkdir -p MyApp/Software/Apps/MyApp-CMake MyApp/Software/Libs MyApp/Software/Apps/TouchGFX-GUI MyApp/Resources MyApp/Output # Copy and rename CMake folder contents cp -r "${UNA_SDK}/Examples/Apps/<app-name>/Software/Apps/<app-name>-CMake/*" MyApp/Software/Apps/MyApp-CMake/ # Rename internal files, e.g.: mv MyApp/Software/Apps/MyApp-CMake/<app-name>Service.ld MyApp/Software/Apps/MyApp-CMake/MyAppService.ld # Copy libs (or move to custom path and update LIBS_PATH in CMakeLists.txt) cp -r "${UNA_SDK}/Examples/Apps/<app-name>/Software/Libs/*" MyApp/Software/Libs/ # Copy TouchGFX (skip if not GUI; adjust TOUCHGFX_PATH if moved) cp -r "${UNA_SDK}/Examples/Apps/<app-name>/Software/Apps/TouchGFX-GUI/*" MyApp/Software/Apps/TouchGFX-GUI/ # Rename TouchGFX project if desired: mv MyApp/Software/Apps/TouchGFX-GUI/<app-name>GUI.touchgfx MyApp/Software/Apps/TouchGFX-GUI/MyAppGUI.touchgfx # Copy or create icons in MyApp/Resources/ (adjust RESOURCES_PATH if changed)
Note: A clean template is planned for future releases. If reorganizing, update paths in CMakeLists.txt accordingly (see step 2).
Customize CMakeLists.txt (located at MyApp/Software/Apps/MyApp-CMake/CMakeLists.txt): Update the following variables to customize your app. These are defined in the CMakeLists.txt and control build parameters, paths, and app metadata. Defaults are provided where applicable.
APP_NAME: Set to your app’s name, e.g., “MyApp”. This is used for output filenames and internal references.APP_ID: A unique 16-character uppercase hexadecimal string identifying your app.Generate locally:
Bash/Linux: python -c ‘import hashlib; print(hashlib.md5(b”MyApp”).hexdigest().upper()[:16])’
PowerShell/Windows: python -c “import hashlib; print(hashlib.md5(b’MyApp’).hexdigest().upper()[:16])”
Alternatively, acquire from the developer portal for published apps as described in deploy.md. Replace “MyApp” with your app name. See API reference for details.
DEV_ID: Device identifier, typically “UNAWatch”.APP_TYPE: App type, e.g., “app”.APP_AUTOSTART: “On” or “Off” (default “Off”) to enable autostart.Paths (adjust if reorganizing file structure):
LIBS_PATH: Path to libraries, default “../../Libs”.OUTPUT_PATH: Path for built files, default “../../../Output”.RESOURCES_PATH: Path to resources like icons, default “../../../Resources”.TOUCHGFX_PATH: Path to TouchGFX directory for GUI apps, e.g., “../TouchGFX-GUI”.
Memory settings (optional, adjust for app needs; defaults in una-app.cmake):
UNA_APP_SERVICE_STACK_SIZE: Service stack, default 10*1024.UNA_APP_SERVICE_RAM_LENGTH: Service RAM, default 500K.UNA_APP_GUI_STACK_SIZE: GUI stack, default 10*1024.UNA_APP_GUI_RAM_LENGTH: GUI RAM, default 600K.
Other optional:
BUILD_VERSION(auto-detected from git or script),APP_USER_NAME(defaults to APP_NAME).
After updating APP_NAME, rename files like the linker script (e.g., from AlarmService.ld to MyAppService.ld) to match, as CMakeLists.txt references “${APP_NAME}Service.ld”.
Note: Paths are relative to CMakeLists.txt. You can reorganize folders by updating these paths accordingly. For example, if libs are in a different location, change LIBS_PATH.
Implement Logic:
Edit
Libs/Sources/for service code.For GUI, configure TouchGFX in
TouchGFX-GUI/(e.g., updateapplication.config, generate code via TouchGFX Designer).
Add Resources:
Place icons in
MyApp/Resources/(30x30 and 60x60 PNGs required; copy from the original app or create new ones).
Set Environment: Ensure the
UNA_SDKenvironment variable is set, as described in the Linux or Windows setup sections above (e.g., run the export script or export command). If you’ve just set it, restart your terminal or PowerShell for the changes to take effect.
Building Apps Manually
Navigate to the app’s CMake directory:
cd MyApp/Software/Apps/MyApp-CMake
# Ensure UNA_SDK and other vars are exported
# Configure (creates build dir)
cmake -G "Unix Makefiles" -S . -B build
# Build
cmake --build build
# Output: .uapp in Output/
For clean rebuild: rm -rf build && cmake -S . -B build && cmake --build build.
Alternative Workflow: STM32CubeIDE
For IDE users, copy CubeIDE projects from Examples.
Creating New Apps in CubeIDE
Copy Projects:
Copy from
Examples/Apps/<app-name>toExamples/Apps/<your-app-name>
Customize:
Edit
.projectand.cproject: Replace names/IDs.Update
Linker.ld: App name, paths.Modify
Core/Src/andCore/Inc/for logic.
Import to CubeIDE:
File > Import > Existing Projects into Workspace > Select copied dirs.
Fix paths in Project Properties > C/C++ Build > Settings.
Build:
Build service/GUI separately.
Manual merge: Use SDK scripts (e.g.,
Utilities/Scripts/app_merging/app_merging.py) with icons/resources.
TouchGFX (Windows-only for Designer)
TouchGFX is a high-performance graphics framework designed for STM32 microcontrollers, enabling rich graphical user interfaces on embedded devices with limited resources.
For now this is single supported way to create graphical applications for UNAwatch platform.
Note: Glances operates without TouchGFX framework, it uses embedded lightweight drawing API which allow to draw simple text and icons in glances menu.
Installation
Download and Install TouchGFX Designer:
Create a free account on the STMicroelectronics website.
Download the latest version of TouchGFX from the ST Developer Zone.
Install the TouchGFX Designer tool on your development machine (Windows only).
Framework Integration:
In the UNA SDK, TouchGFX is pre-integrated in example GUI projects (e.g.,
Examples/Apps/<app>/Software/Apps/TouchGFX-GUI/).For new projects, copy the TouchGFX-GUI directory from an example and ensure the framework libraries are available via the SDK paths.
No separate installation of the framework is needed if using the SDK’s bundled version; otherwise, download the TouchGFX framework package from ST.
Using TouchGFX Designer for Visual Editing
Launch Designer: Open TouchGFX Designer and create a new project or open an existing
.touchgfxconfiguration file (e.g.,MyAppGUI.touchgfx).Visual Design: Define display settings, add widgets, organize screens, import assets, and configure interactions.
Preview and Simulate: Use the built-in simulator to test the UI before generating code.
For comprehensive guidance on TouchGFX Designer usage, code generation, project structure, CMake integration, build configuration, code organization, MVP pattern implementation, and custom GUI development, see the TouchGFX Port Architecture document.
Integration with CMake
In UNA SDK projects, TouchGFX integrates seamlessly with CMake for building GUI applications. Set TOUCHGFX_PATH in CMakeLists.txt, include touchgfx.cmake, and configure GUI sources.
Modifying Generated Code Safely
Avoid Editing Generated Files: Files in
generated/are automatically overwritten during code generation.Custom Code Locations: Place custom implementations in
gui/src/(views, presenters, model).Regeneration Workflow: Design → Generate Code → Implement custom logic in
gui/src/→ Rebuild.
Troubleshooting
Missing Dependencies: Ensure all required libraries are linked.
Path Errors: Verify
UNA_SDKand other paths are correctly set.Toolchain Issues: Confirm ARM GCC is properly installed and in PATH. On Windows, run the export script with dot sourcing and reboot if necessary.
CMake Compiler Errors: If CMake cannot find compilers (e.g., “CMAKE_C_COMPILER not set”), add
-DCMAKE_SYSTEM_NAME=Generic -DCMAKE_C_COMPILER=arm-none-eabi-gcc -DCMAKE_CXX_COMPILER=arm-none-eabi-g++ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_ASM_COMPILER=arm-none-eabi-gccto the cmake command.Build Conflicts: Clean build dirs if errors persist after changes. Use
rm -rf build(Linux) orRemove-Item -Recurse build(PowerShell) and reconfigure.