* templates: convert C++ module templates to the universal authoring model
minimal-module, external-lib-module, and ui-qml-backend now use
interface: "universal" — you write only the impl (core) or the .rep +
*Backend (UI), and the *Plugin/*Interface Qt glue is generated:
- minimal-module: MinimalImpl : LogosModuleContext (std types, a
logos_events event); no hand-written interface/plugin.
- external-lib-module: ExternalLibImpl : LogosModuleContext wrapping the
vendored C lib.
- ui-qml-backend: UiExampleBackend : UiExampleSimpleSource +
LogosModuleContext; metadata gains interface:universal + codegen.rep.
CMake drops the module_config.h boilerplate (name/version come from the
generated glue). test-templates.nix asserts the universal interface (and
that the QML-only template stays legacy). minimal + ui-qml-backend build
green; lm shows the generated plugins load with methods + protocol stamp.
* docs/skills: teach the universal authoring model for the converted templates
create-logos-module, create-ui-module, update-logos-module, SKILL.md, README
and docs/{getting-started,configuration,quick-reference,cmake-reference,nix-api}
now show the impl-class (core) and .rep+Backend (UI) form that the templates
use, instead of the removed hand-written interface/plugin classes. Documents
the interface:universal + codegen fields, REP_FILE/INCLUDE_DIRS, logos_events:,
and modules() typed calls. The QML-only template and the legacy
initLogos(LogosAPI*) path are noted as still supported.
* templates: derive module NAME from metadata.json (single source of truth)
The universal conversion had hardcoded NAME in logos_module(); restore the
file(READ metadata.json) + string(JSON ... name) read so the module name lives
only in metadata.json. (The module_config.h #define boilerplate stays gone —
the universal impl does not use MODULE_NAME/MODULE_VERSION macros.)
7.7 KiB
CMake Reference
Complete reference for LogosModule.cmake functions and options.
Overview
LogosModule.cmake is a CMake module that handles all the boilerplate for building Logos plugins. It provides:
- Automatic SDK and liblogos detection
- Qt6/Qt5 finding and configuration
- Code generation setup
- External library handling
- Platform-specific RPATH configuration
- Install targets
Including LogosModule.cmake
# Method 1: Via environment variable (recommended for nix builds)
include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake)
# Method 2: Local copy
include(cmake/LogosModule.cmake)
# Method 3: Vendor directory
include(vendor/logos-module-builder/cmake/LogosModule.cmake)
logos_module()
The main function to define a Logos module.
Syntax
logos_module(
NAME <module_name>
SOURCES <source_files>...
[REP_FILE <rep_file>]
[INCLUDE_DIRS <dirs>...]
[EXTERNAL_LIBS <library_names>...]
[FIND_PACKAGES <package_names>...]
[LINK_LIBRARIES <library_names>...]
[PROTO_FILES <proto_files>...]
)
Parameters
NAME (required)
The module name. Used for:
- Output filename:
{NAME}_plugin.so/{NAME}_plugin.dylib - CMake target name:
{NAME}_module_plugin
logos_module(
NAME my_module
...
)
SOURCES (required)
List of source files for the module. In the universal authoring model you list
only your impl (or backend) sources — the generated glue ({name}_interface.h,
{name}_plugin.{h,cpp}) is compiled automatically and must not be listed.
For a core module, this is the impl class:
src/{name}_impl.h- Impl class declaration (public methods = API)src/{name}_impl.cpp- Impl class implementation
plus any extra helpers you add:
logos_module(
NAME my_module
SOURCES
src/my_module_impl.h
src/my_module_impl.cpp
src/helper.cpp
src/utils.cpp
)
Classic modules (no
"interface"field inmetadata.json) instead list the hand-writtensrc/{name}_interface.h,src/{name}_plugin.h, andsrc/{name}_plugin.cpp. This path is still supported for backward compatibility, but the templates and recommended path are universal.
REP_FILE (optional)
Path to a .rep Qt Remote Objects contract for a universal C++ UI backend
("type": "ui_qml" + "interface": "universal"). repc is run on it and the
generated source (rep_<name>_source.h) is made available to your *Backend
class. Pair it with INCLUDE_DIRS src so the generated header resolves.
logos_module(
NAME my_ui
REP_FILE src/my_ui.rep
SOURCES
src/my_ui_backend.h
src/my_ui_backend.cpp
INCLUDE_DIRS
src
)
INCLUDE_DIRS (optional)
Additional include directories added to the plugin target. Commonly src for
universal UI backends so the generated rep_*_source.h is found.
logos_module(
NAME my_module
SOURCES ...
INCLUDE_DIRS
src
vendor/include
)
EXTERNAL_LIBS (optional)
External libraries to link. Libraries are searched in lib/ directory.
logos_module(
NAME my_module
SOURCES ...
EXTERNAL_LIBS
libfoo
libbar
)
The function will:
- Search for
lib/libfoo.soorlib/libfoo.dylib - Add
lib/to include directories - Link the library
- Copy the library to the output directory
- Fix install names on macOS
FIND_PACKAGES (optional)
CMake packages to find via find_package().
logos_module(
NAME my_module
SOURCES ...
FIND_PACKAGES
Protobuf
Threads
ZLIB
)
LINK_LIBRARIES (optional)
Additional libraries to link (after find_package).
logos_module(
NAME my_module
SOURCES ...
FIND_PACKAGES Threads
LINK_LIBRARIES
Threads::Threads
${ZLIB_LIBRARIES}
)
generated_code/ (automatic)
If generated_code/ exists next to CMakeLists.txt, all *.cpp and *.h files there are added to the plugin target (except logos_sdk.cpp and core_manager_api.cpp, which are already provided by the Nix preConfigure / SDK layout). You do not need to list glue or dispatch sources manually.
metadata.json (automatic)
metadata.json is copied to CMAKE_CURRENT_BINARY_DIR so Q_PLUGIN_METADATA can resolve it during the build.
Go static archives (CMake cache variable)
When mkLogosModule passes -DLOGOS_MODULE_GO_STATIC_LIBS=name1;name2 (from go_build: true entries in metadata.json), LogosModule.cmake finds lib/lib<name>.a under lib/, links with whole-archive (Linux) or -force_load (macOS), and adds CoreFoundation/Security frameworks on Apple platforms.
PROTO_FILES (optional)
Protocol Buffer .proto files to compile.
logos_module(
NAME my_module
SOURCES ...
PROTO_FILES
src/protobuf/message.proto
src/protobuf/types.proto
)
This will:
- Find Protobuf via
find_package(Protobuf REQUIRED) - Compile each
.protofile to.pb.ccand.pb.h - Add generated files to sources
- Add Protobuf include directories
- Link Protobuf libraries
Helper Functions
logos_find_dependencies()
Find and configure Logos SDK and liblogos.
logos_find_dependencies()
Sets variables:
LOGOS_LIBLOGOS_ROOT- Path to logos-liblogosLOGOS_CPP_SDK_ROOT- Path to logos-cpp-sdkLOGOS_LIBLOGOS_IS_SOURCE- TRUE if source layoutLOGOS_CPP_SDK_IS_SOURCE- TRUE if source layout
logos_find_qt()
Find Qt6 (or Qt5 fallback) with required components.
logos_find_qt()
Sets:
QT_VERSION_MAJOR- 5 or 6
Environment Variables
LOGOS_MODULE_BUILDER_ROOT
Path to logos-module-builder. Set automatically by nix builds.
export LOGOS_MODULE_BUILDER_ROOT=/path/to/logos-module-builder
LOGOS_CPP_SDK_ROOT
Override path to logos-cpp-sdk.
export LOGOS_CPP_SDK_ROOT=/path/to/logos-cpp-sdk
LOGOS_LIBLOGOS_ROOT
Override path to logos-liblogos.
export LOGOS_LIBLOGOS_ROOT=/path/to/logos-liblogos
Generated Targets
For a module named my_module, the following are created:
| Target | Description |
|---|---|
my_module_module_plugin |
Main library target |
run_cpp_generator_my_module |
Code generation target (source layout) |
my_module_generate_protos |
Protobuf generation target (if PROTO_FILES) |
Output Files
build/
└── modules/
├── my_module_plugin.so # or .dylib
├── libfoo.so # external libs copied here
└── ...
Complete Example
cmake_minimum_required(VERSION 3.14)
project(ChatModulePlugin LANGUAGES CXX)
# Include the helper
include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake)
# Define the module (universal model: list only the impl + helpers)
logos_module(
NAME chat
SOURCES
src/chat_impl.h
src/chat_impl.cpp
src/chat_api.cpp
src/chat_api.h
FIND_PACKAGES
Protobuf
Threads
PROTO_FILES
src/protobuf/message.proto
LINK_LIBRARIES
absl::base
absl::strings
)
Customization
For advanced customization, you can use the helper functions directly:
cmake_minimum_required(VERSION 3.14)
project(CustomModulePlugin LANGUAGES CXX)
# Include helpers
include($ENV{LOGOS_MODULE_BUILDER_ROOT}/cmake/LogosModule.cmake)
# Find dependencies manually
logos_find_dependencies()
logos_find_qt()
# Create library manually
add_library(my_plugin SHARED
my_plugin.cpp
# ... more sources
)
# Custom configuration
target_compile_definitions(my_plugin PRIVATE MY_CUSTOM_DEFINE)
target_include_directories(my_plugin PRIVATE ${CUSTOM_INCLUDE_DIR})
# Link Qt (required)
target_link_libraries(my_plugin PRIVATE
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::RemoteObjects
)