Files
logos-module-builder/docs/cmake-reference.md
T
Dario Lipicar e0fd2a4368 templates: convert C++ module templates to the universal authoring model (#120)
* 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.)
2026-06-13 09:15:05 -03:00

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 in metadata.json) instead list the hand-written src/{name}_interface.h, src/{name}_plugin.h, and src/{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:

  1. Search for lib/libfoo.so or lib/libfoo.dylib
  2. Add lib/ to include directories
  3. Link the library
  4. Copy the library to the output directory
  5. 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
)

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:

  1. Find Protobuf via find_package(Protobuf REQUIRED)
  2. Compile each .proto file to .pb.cc and .pb.h
  3. Add generated files to sources
  4. Add Protobuf include directories
  5. 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-liblogos
  • LOGOS_CPP_SDK_ROOT - Path to logos-cpp-sdk
  • LOGOS_LIBLOGOS_IS_SOURCE - TRUE if source layout
  • LOGOS_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
)