mirror of
https://github.com/logos-co/logos-cpp-sdk.git
synced 2026-08-31 01:31:10 +00:00
The definition lands BEFORE the protocol declares the export. logos-protocol only DECLARES the module-impl C ABI and every backend owes the definition; that gap shipped twice, each time as an undefined symbol at dlopen, on Linux only, invisible on macOS. Declaring first would turn this repo, logos-rust-sdk and logos-module-builder red the night the bump merged. Defining first costs nothing: the guard is MAJOR-aware >= 0.6 and the current pin is 0.5, so nothing is emitted today and the ABI check sees declared == defined. This is the case #146 made possible. The next-MAJOR probe resolves the emitter at MAJOR+1, where a >= 6 guard IS true, so the emitted set there is legitimately a SUPERSET of the declared one. The probe used to demand equality and would have rejected this outright. cpp/logos_caller.h carries the LogosCaller type (std-typed, Qt-free) and logos::currentCaller(), reading a thread-local stack the generated export pushes to. Two things the audit corrected, both worth reading: * A present-but-unreadable `instance` is DROPPED and the module still identified. This backend already did that; Rust returned Unknown, and each had a passing test pinning its own answer, so neither suite could see the divergence. The protocol header now states the rule normatively and Rust is aligned to it. * The accessors are explicitly HIDDEN on ELF. The header argued this state must not be unified across images and then relied on being inline to achieve it — which is false: a function-local static in an inline function emits STB_GNU_UNIQUE at default visibility and the loader collapses every image's copy into one, even under RTLD_LOCAL. Measured across two dlopen'd images: default visibility let a push in A be read by B; hidden restored isolation. logos-module-builder sets no visibility anywhere, so real plugins were built the first way. An anonymous namespace would be worse — vague linkage is load-bearing WITHIN an image, since the generated TU pushes and the author's TU reads. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
120 lines
4.5 KiB
CMake
120 lines
4.5 KiB
CMake
cmake_minimum_required(VERSION 3.14)
|
|
project(LogosSDK)
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# logos-cpp-sdk — the Qt-FREE base C++ SDK.
|
|
#
|
|
# After the protocol extraction (logos-protocol) and the Qt split
|
|
# (logos-qt-sdk), what lives here is the standard-C++ developer surface, split
|
|
# by CAPABILITY. A program is some combination of three distinct things, and
|
|
# each gets its own target so a consumer takes only what it is:
|
|
#
|
|
# ::common logos_json.h, logos_result.h
|
|
# The shared value types. Everything below links this.
|
|
#
|
|
# ::consumer logos_lp_client.h, logos_async_result.h
|
|
# CALLING other modules. Also the compile-time home of the
|
|
# generated <dep>_api.{h,cpp} wrappers and their logos_sdk.h
|
|
# umbrella, which the module builder emits per build.
|
|
#
|
|
# ::provider logos_module_context.h, logos_caller.h, logos_host_services.h
|
|
# IMPLEMENTING a module. LogosModuleContext is the seam the
|
|
# generated provider injects into; logos_host_services.h is the
|
|
# veneer a module uses for services the HOST granted it. (It is
|
|
# module-side despite the `host_services` name, which is what
|
|
# motivated this split; a rename to logos_privileged_services.h
|
|
# has NOT happened — the file installed below is still
|
|
# logos_host_services.h.)
|
|
#
|
|
# ::host logos_host_core.h
|
|
# STANDING UP a core and loading modules into it. Used by
|
|
# logos-basecamp, logos-logoscore-cli, logos-standalone-app,
|
|
# logos-module-viewer. A module never needs this.
|
|
#
|
|
# `logos_headers` remains as an UMBRELLA over all four, so the ~70 existing
|
|
# consumers keep working unchanged; migrate to the narrow targets when touching
|
|
# a repo. Additive first, removal second.
|
|
#
|
|
# Everything is header-only, so every target is an INTERFACE library.
|
|
# Qt-typed wrappers live in logos-qt-sdk, which mirrors this same three-way
|
|
# split. Transports, the consumer core and the lp_* C ABI live in
|
|
# logos-protocol.
|
|
# ---------------------------------------------------------------------------
|
|
|
|
find_package(nlohmann_json REQUIRED)
|
|
|
|
# The include dir and nlohmann are common to every capability; each target
|
|
# below adds only its link interface, since the headers themselves are found
|
|
# through the same include path.
|
|
add_library(logos_common INTERFACE)
|
|
target_link_libraries(logos_common INTERFACE nlohmann_json::nlohmann_json)
|
|
target_include_directories(logos_common INTERFACE
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
$<INSTALL_INTERFACE:include>
|
|
)
|
|
|
|
add_library(logos_consumer INTERFACE)
|
|
target_link_libraries(logos_consumer INTERFACE logos_common)
|
|
|
|
add_library(logos_provider INTERFACE)
|
|
target_link_libraries(logos_provider INTERFACE logos_common)
|
|
|
|
# NOTE: ::host deliberately does NOT link liblogos. logos-liblogos depends on
|
|
# logos-cpp-sdk, so this repo cannot see its headers or its library without
|
|
# inverting the graph; logos_host_core.h declares the logos_core_* ABI itself
|
|
# and the host program provides it at link time.
|
|
add_library(logos_host INTERFACE)
|
|
target_link_libraries(logos_host INTERFACE logos_common)
|
|
|
|
# Umbrella. Pre-split consumers link this and get everything, as before.
|
|
add_library(logos_headers INTERFACE)
|
|
target_link_libraries(logos_headers INTERFACE
|
|
logos_common
|
|
logos_consumer
|
|
logos_provider
|
|
logos_host
|
|
)
|
|
|
|
install(TARGETS logos_headers logos_common logos_consumer logos_provider logos_host
|
|
EXPORT logos-cpp-sdkTargets
|
|
INCLUDES DESTINATION include
|
|
)
|
|
|
|
install(EXPORT logos-cpp-sdkTargets
|
|
FILE logos-cpp-sdkTargets.cmake
|
|
NAMESPACE logos-cpp-sdk::
|
|
DESTINATION lib/cmake/logos-cpp-sdk
|
|
)
|
|
|
|
include(CMakePackageConfigHelpers)
|
|
configure_package_config_file(
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/logos-cpp-sdkConfig.cmake.in"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-cpp-sdkConfig.cmake"
|
|
INSTALL_DESTINATION lib/cmake/logos-cpp-sdk
|
|
)
|
|
write_basic_package_version_file(
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-cpp-sdkConfigVersion.cmake"
|
|
VERSION 0.2.0
|
|
COMPATIBILITY SameMajorVersion
|
|
)
|
|
install(FILES
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-cpp-sdkConfig.cmake"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-cpp-sdkConfigVersion.cmake"
|
|
DESTINATION lib/cmake/logos-cpp-sdk
|
|
)
|
|
|
|
install(FILES
|
|
logos_module_context.h
|
|
logos_json.h
|
|
logos_result.h
|
|
logos_caller.h
|
|
logos_lp_client.h
|
|
logos_async_result.h
|
|
logos_host_services.h
|
|
logos_host_core.h
|
|
DESTINATION include
|
|
)
|