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-eabi is often incompatible (newlib syscall stubs such as _write can 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-gcc toolchain)

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
  1. 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

  1. 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

  • Git

  • 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 make program, 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:

  1. 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 when CMakeLists.txt changes.

  2. Build/Compilation: cmake --build <build-dir> (from any directory) or make (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

  1. 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).

  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.

  3. Implement Logic:

    • Edit Libs/Sources/ for service code.

    • For GUI, configure TouchGFX in TouchGFX-GUI/ (e.g., update application.config, generate code via TouchGFX Designer).

  4. Add Resources:

    • Place icons in MyApp/Resources/ (30x30 and 60x60 PNGs required; copy from the original app or create new ones).

  5. Set Environment: Ensure the UNA_SDK environment 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

  1. Copy Projects:

    • Copy from Examples/Apps/<app-name> to Examples/Apps/<your-app-name>

  2. Customize:

    • Edit .project and .cproject: Replace names/IDs.

    • Update Linker.ld: App name, paths.

    • Modify Core/Src/ and Core/Inc/ for logic.

  3. Import to CubeIDE:

    • File > Import > Existing Projects into Workspace > Select copied dirs.

    • Fix paths in Project Properties > C/C++ Build > Settings.

  4. 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

  1. 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).

  2. 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 .touchgfx configuration 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_SDK and 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-gcc to the cmake command.

  • Build Conflicts: Clean build dirs if errors persist after changes. Use rm -rf build (Linux) or Remove-Item -Recurse build (PowerShell) and reconfigure.