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>
43 lines
1.7 KiB
Nix
43 lines
1.7 KiB
Nix
# Installs the Qt-free base SDK headers in the source-export layout
|
|
# ($out/include/cpp/...). The transport/protocol sources ship from
|
|
# logos-protocol and the Qt developer layer from logos-qt-sdk; build
|
|
# systems that need those add the respective include roots.
|
|
{ pkgs, common, src, logos-protocol }:
|
|
|
|
pkgs.stdenv.mkDerivation {
|
|
pname = "${common.pname}-headers";
|
|
# qtbase\'s setup hook errors in qtPreHook unless a wrapper hook ran or
|
|
# this is set; the wrapper hooks are absent on Windows (they cannot even
|
|
# evaluate for a mingw host) and would skip a PE anyway.
|
|
dontWrapQtApps = true;
|
|
version = common.version;
|
|
|
|
inherit src;
|
|
inherit (common) meta;
|
|
|
|
dontBuild = true;
|
|
dontConfigure = true;
|
|
|
|
installPhase = ''
|
|
runHook preInstall
|
|
|
|
mkdir -p $out/include/cpp
|
|
|
|
# logos_lp_client.h MUST sit in the same directory as the headers it
|
|
# includes (logos_result.h, logos_json.h). A cdylib module's generated
|
|
# dep wrapper includes "logos_lp_client.h" via the include/cpp source-
|
|
# export root, and a quoted include resolves siblings relative to the
|
|
# including file. If logos_lp_client.h lived only at the top-level
|
|
# include/ (the CMake-export layout) while logos_result.h is reached via
|
|
# include/cpp/, a single TU would pull logos_result.h through two
|
|
# distinct realpaths and #pragma once could not dedup them
|
|
# (redefinition of StdLogosResult). Ship every std header in BOTH roots.
|
|
for file in 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; do
|
|
cp cpp/$file $out/include/cpp/
|
|
cp cpp/$file $out/include/
|
|
done
|
|
|
|
runHook postInstall
|
|
'';
|
|
}
|