A CMake-based bootstrap framework that enables building C/C++ projects for Linux and baremetal platforms (with or
without RTOS) from a single codebase. It provides toolchain configuration via CMake variables and platform-specific
entry point abstraction through a unified appMain() interface.
Main features:
- toolchain setup: configures compiler, architecture flags, and build settings for target platform via CMake toolchain files,
- unified main(): provides platform-specific
main()implementations that invoke application-definedappMain()function.
Important
platform requires target project to use CMake.
toolchain:- Configures compiler and architecture flags via
PLATFORM+TOOLCHAINCMake variables from the list of supported ones. - On Linux, additionally allows enabling sanitizers (
asan,lsan,tsan,ubsan) and code coverage support.
- Configures compiler and architecture flags via
main:- Provides platform-specific
main()that calls application-definedappMain(). - On Linux, an optional
platform::main-pathstarget exposes API for getting install, config, and data root paths.
- Provides platform-specific
package:- Exposes build-time metadata (compiler, build type) and git metadata (e.g. tag, branch, commit), regenerated at every CMake reconfiguration.
Important
Only components explicitly referenced by find_package(platform COMPONENTS ...) are processed by CMake and those
referenced by target_link_libraries() are actually built.
The main component abstracts the entry-point dispatch across all supported platforms:
flowchart TD
main["main()"] --> Platform{platform}
Platform -->|Linux| AppMainLinux["appMain()"]
Platform -->|Baremetal| AppMainBaremetal["appMain()"]
Platform -->|RTOS| CreateThread[Create thread]
CreateThread --> Scheduler[Run scheduler]
Scheduler e1@-->|new thread| AppMainRTOS["appMain()"]
e1@{ animation: fast }
classDef mainStyle stroke:#ff6600
classDef appMainStyle stroke:#00ff00
class main mainStyle
class AppMainLinux,AppMainBaremetal,AppMainRTOS appMainStyle
- Language: C++23, C17
- Build System: CMake (minimum version 3.28)
- Documentation: MkDocs with Material theme
- Static Analysis: clang-format, clang-tidy
- CI/CD: GitHub Actions
platform follows standard kubasejdak-org repository layout for C++ library:
platform/
├── cmake/ # CMake build system
│ ├── compilation-flags.cmake # Internal compilation flags
│ ├── components.cmake # Helper component loader (FetchContent helper)
│ ├── modules/ # CMake Find*.cmake modules for dependencies
│ └── presets/ # Internal presets helpers
├── lib/ # Core components
│ ├── main/ # appMain() entrypoint for given platform
│ │ ├── linux/ # Entrypoint for Linux
│ │ ├── baremetal-arm/ # Entrypoint for baremetal on ARM
│ │ └── freertos-arm/ # Entrypoint for FreeRTOS on ARM
│ ├── package/ # Component with repo build, version and git info
│ └── toolchain/ # Toolchain configurations
│ ├── linux/ # Toolchain configs for Linux
│ ├── baremetal-arm/ # Toolchain configs for baremetal on ARM
│ └── freertos-arm/ # Toolchain configs for FreeRTOS on ARM
├── examples/ # Examples of platform usage
├── tools/ # Internal tools and scripts
├── .devcontainer/ # Devcontainers configs
├── .github/workflows/ # GitHub Actions configs
└── CMakePresets.json # Development CMake presetsCreate a Findplatform.cmake module (typically in cmake/modules directory):
include(FetchContent)
FetchContent_Declare(platform
GIT_REPOSITORY https://github.com/kubasejdak-org/platform.git
GIT_TAG <commit-sha|branch|tag>
SOURCE_SUBDIR lib
)
FetchContent_MakeAvailable(platform)
include(${platform_SOURCE_DIR}/cmake/components.cmake)Note
GIT_TAG accepts any ref recognized by CMake FetchContent: a full commit SHA, a branch name, or a tag.
This will allow defining which platform version should be used. It will also automatically download repo into build
directory.
Then, add directory containing that file to CMake search paths and use required components:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
...
find_package(platform COMPONENTS toolchain) # Must be requested before project()
project(myproject)
...
find_package(platform COMPONENTS main package) # Other components can be requested after project()Control platform selection via CMake variables (typically in CMakePresets.json):
| Variable | Purpose | Examples |
|---|---|---|
PLATFORM |
Target platform | linux, baremetal-arm, freertos-arm |
TOOLCHAIN |
Compiler toolchain | gcc, clang, arm-none-eabi-gcc |
FREERTOS_VERSION |
FreeRTOS kernel version (freertos-arm only) |
freertos-10.2.1 |
Implement appMain() instead of main() in the application:
#include <cstdlib>
int appMain(int argc, char* argv[])
{
// Application code
return EXIT_SUCCESS;
}target_link_libraries(my-app
PRIVATE
platform::main # Provides main() → appMain() dispatch
)Tip
See examples/ for complete, per-platform integration examples.
Note
This section is relevant when working with platform itself, in standalone way. However presets used to build
platform tests and examples can be used as a reference for dependent projects.
- Configure:
cmake --preset <preset-name> . -B out/build/<preset-name> - Build:
cmake --build out/build/<preset-name> --parallel - Run tests:
cd out/build/<preset-name>/bin; ./<binary-name> - Reformat code:
tools/check-clang-format.sh - Run linter:
cd out/build/<preset-name>; ../../../tools/check-clang-tidy.sh- Must be launched with clang preset (usually in clang devcontainer)
- Native Linux:
- Dependencies provided by target system:
linux-native-{gcc,clang}-{debug,release}
- Dependencies provided by target system:
- Cross-compilation:
- Generic ARM64:
linux-arm64-{gcc,clang}-{debug,release} - Yocto (via SDK):
yocto-sdk-{gcc,clang}-{debug,release} - Baremetal ARMv7:
baremetal-armv7-*-{gcc,clang}-{debug,release} - FreeRTOS ARMv7:
freertos-armv7-*-{gcc,clang}-{debug,release}
- Generic ARM64:
- Sanitizers:
*-{asan,lsan,tsan,ubsan}variants
Note
For local development use linux-native-conan-gcc-debug preset.
Warning
clang variants for baremetal platforms are only to allow static analysis via clang-tidy.
- Zero Warning Policy: All warnings treated as errors
- Code Formatting: clang-format with project-specific style checked
- Static Analysis: clang-tidy configuration checked
- Coverage: Code coverage reports generated
- Valgrind: Tests and examples run under valgrind
- Sanitizers: Address, leak, thread, and undefined behavior sanitizers checked
- Component Structure: Each component is a separate, reusable module in
lib/with the following structure:<component>/include/platform/<component>/: public headers<component>/: private implementation files<component>/CMakeLists.txt: component configuration- optionally:
<component>/<module>/with the same structure if it form a separate smaller part within component
- Testing: Always run tests when making changes. Test fixtures are well-established.
- Dependencies: Be careful with dependency management. This project has specific version requirements.
- Code Style: Follow the established patterns. The project has strict formatting and static analysis rules.
- Error Handling: Always use
std::error_codefor error reporting, never exceptions. - Documentation: Update documentation when adding new components or changing APIs.
- Namespace: All code should be in the
platform::namespace hierarchy.