mirror of
https://github.com/logos-co/logos-protocol.git
synced 2026-08-30 21:41:10 +00:00
PR-1+PR-2 of the shared-runtime migration, squashed: they were raised
separately and the second replaced the first's mechanism, so the split was
history rather than review value.
WHY. The runtime types that must exist EXACTLY ONCE per process (TokenManager,
LogosAPIClient, the per-identity StoreRegistry) are moving from "absorbed into
liblogos_core by whole-archive and re-exported through a generated .def" to
"owned by the shared library that defines them". Every image that links a static
archive gets its own copy of every function-local static inside it, so the host
writes a capability token into one store and another in-process image reads an
empty one -- with no build diagnostic.
Three things, and the order they were discovered in is the order they matter:
1. THE CMAKE PACKAGE. logos_protocol_shared was built and installed but
deliberately kept OUT of the export set: it existed only for FFI callers that
dlopen the lp_* C ABI, and those never link it. In-process C++ consumers do,
and a consumer cannot link what find_package() does not hand it. Now exported
as logos-protocol::logos_protocol_shared, with the INSTALL_INTERFACE include
dirs the static target already had, and with ARCHIVE DESTINATION -- on Windows
a shared library's import library (.dll.a) is the ARCHIVE artifact, so
omitting it installs no import library at all and the failure is invisible on
ELF and Mach-O, which have none.
2. THE EXPORT TABLE IS GENERATED, NOT HAND-MARKED. The first attempt annotated
the classes with __declspec(dllexport). That exported 116 symbols and the Qt
host runtime STILL failed to link against it, with ELEVEN undefined
references across five classes -- LogosProviderObject and its vtable,
ModuleProxy, ModuleHandshakeProxy, LogosTransportFactory -- plus free
functions such as logos::qvariantToNlohmann. A curated list is correct only
until the next consumer touches a symbol nobody marked, and the failure lands
in a downstream repo far from the cause.
cmake/gen-shared-exports.sh is adapted from logos-liblogos, which generated
the same table one layer up. The mechanism is unchanged because the reasons
for it are unchanged; this moves it down to the library that owns the
symbols. It cannot be shared as a file: logos-liblogos depends on
logos-protocol, not the other way round.
logos_shared_api.h therefore resolves its "building the shared library"
branch to NOTHING on Windows, so the .def and the annotations never compete.
The macro keeps its import half, which is what stops a consumer pulling the
archive member that would redefine the symbol.
30 exports on master -> 116 hand-marked -> 360 generated.
3. VTABLES AND TYPEINFO ARE CARVED OUT OF THE COMDAT FILTER. The last undefined
symbol was the vtable for LogosProviderObject. PE HAS NO WEAK SYMBOLS --
COMDAT is the mechanism for weak and inline linkage -- so GCC emits a vtable
into .rdata$_ZTV... even when the class has a key function and the vtable is a
single strong definition. The section name cannot tell "one definition nobody
duplicates" from "every TU emits its own", so the filter dropped it. The
filter's reasoning does not apply to vtables: a consumer of a class WITH a key
function emits a .refptr and needs ours; a class WITHOUT one emits its own
copy and never references ours, so exporting is inert. This never mattered
while liblogos_core absorbed both archives -- definition and consumer landed
in one image and the reference never crossed a boundary.
WHY PROTOCOL NEEDS A .def WHEN THE QT HOST DOES NOT. The shared qt-host DLL
exports 2799 symbols with no .def at all, because it carries no dllexport marks
and GNU ld auto-exports everything. Protocol cannot rely on that: LP_API's
dllexport on the lp_* C ABI disables auto-export for the whole target. ANY single
dllexport turns the automatic path off -- which is also why CMake's
WINDOWS_EXPORT_ALL_SYMBOLS was measured as completely inert here.
TWO MACROS, NOT ONE. LOGOS_QT_HOST_API is added for logos-plugin-qt's LogosAPI,
which lives in a different library. While building the Qt host shared library
LogosAPI must NOT be dllimport while TokenManager must be, and one macro cannot
say both in the same translation unit. Off Windows the distinction is moot --
both resolve to default visibility -- which is exactly why getting it wrong would
go unnoticed until a Windows build.
Also corrects this file's own premise, the origin of the false claim that "ELF
and Mach-O give this for free. Both formats interpose symbols across the whole
process image set." True of ELF, false of Mach-O, whose two-level namespace gives
no interposition -- measured in logos-basecamp, where one reference to
LogosAPI::forIdentity dragged logos_api.cpp.o into the executable and produced 31
refused calls against a baseline of 0.
VERIFIED.
aarch64-darwin static archive symbol tables IDENTICAL (14257 lines), exactly
ONE byte differing in 5.4MB -- 351 -> 352 in __.SYMDEF's ar
header, build metadata, not content
logos-protocolTargets.cmake names both targets
checks.tests PASS, .#default PASS
x86_64-linux checks.tests PASS
x86_64-mingw export table 30 -> 360, all 30 lp_* preserved, 0 removed
import library liblogos_protocol.dll.a now installed
logos-plugin-qt#22 links against it, and its PE layering is
correct: defines LogosAPI 25, defines TokenManager 0 and
LogosAPIClient 0, imports from liblogos_protocol.dll
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
376 lines
15 KiB
CMake
376 lines
15 KiB
CMake
cmake_minimum_required(VERSION 3.14)
|
|
project(LogosProtocol)
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_AUTOMOC ON)
|
|
|
|
# Find Qt packages — Qt is an implementation detail of the qt_remote (QRO)
|
|
# and qt_local transports plus the Qt value types used at the QRO boundary.
|
|
# The PUBLIC C ABI (logos_protocol.h) is Qt-free.
|
|
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core RemoteObjects)
|
|
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core RemoteObjects)
|
|
|
|
# Plain-C++ transport dependencies (no Qt).
|
|
#
|
|
# Boost.System is header-only, but Boost 1.87 only EXPORTS the Boost::system
|
|
# imported target when the component is requested -- hence the explicit
|
|
# COMPONENTS below. Boost 1.89 then removed the compiled boost_system library
|
|
# outright, so there is no boost_systemConfig.cmake at all and requesting it as
|
|
# REQUIRED hard-fails ("Could not find a package configuration file provided by
|
|
# boost_system"). Ask for it optionally and fall back to Boost::headers, which
|
|
# carries the same header-only error_code either way.
|
|
find_package(Boost REQUIRED)
|
|
find_package(Boost QUIET OPTIONAL_COMPONENTS system)
|
|
if(TARGET Boost::system)
|
|
set(LOGOS_BOOST_SYSTEM Boost::system)
|
|
else()
|
|
set(LOGOS_BOOST_SYSTEM Boost::headers)
|
|
endif()
|
|
message(STATUS "Boost.System target: ${LOGOS_BOOST_SYSTEM} (Boost ${Boost_VERSION})")
|
|
find_package(OpenSSL REQUIRED)
|
|
find_package(nlohmann_json REQUIRED)
|
|
|
|
set(PROTOCOL_SOURCES
|
|
logos_protocol.h
|
|
logos_module_impl.h
|
|
logos_call_error.h
|
|
logos_shared_api.h
|
|
logos_protocol.cpp
|
|
logos_types.cpp
|
|
logos_types.h
|
|
logos_api_client.cpp
|
|
logos_api_client.h
|
|
logos_api_consumer.cpp
|
|
logos_api_consumer.h
|
|
logos_subscription_state.h
|
|
module_proxy.cpp
|
|
module_proxy.h
|
|
token_manager.cpp
|
|
token_manager.h
|
|
logos_mode.h
|
|
logos_instance.h
|
|
logos_socket_paths.h
|
|
logos_socket_paths.cpp
|
|
plugin_registry.h
|
|
logos_object.h
|
|
logos_thread_marshal.h
|
|
logos_provider_interface.cpp
|
|
logos_provider_interface.h
|
|
logos_json_convert.cpp
|
|
logos_json_convert.h
|
|
logos_transport.h
|
|
logos_transport.cpp
|
|
logos_transport_config.h
|
|
logos_transport_config_json.h
|
|
logos_transport_config_json.cpp
|
|
logos_transport_factory.cpp
|
|
logos_transport_factory.h
|
|
logos_registry.h
|
|
logos_registry_factory.h
|
|
logos_registry_factory.cpp
|
|
implementations/qt_local/local_transport.cpp
|
|
implementations/qt_local/local_transport.h
|
|
implementations/qt_remote/remote_transport.cpp
|
|
implementations/qt_remote/remote_transport.h
|
|
implementations/qt_remote/qt_remote_registry.h
|
|
implementations/qt_remote/qt_remote_registry.cpp
|
|
implementations/mock/mock_store.cpp
|
|
implementations/mock/mock_store.h
|
|
implementations/mock/mock_transport.cpp
|
|
implementations/mock/mock_transport.h
|
|
implementations/mock/mock_registry.h
|
|
implementations/mock/logos_mock.h
|
|
# Plain-C++ wire stack (no Qt)
|
|
implementations/plain/rpc_value.h
|
|
implementations/plain/rpc_message.h
|
|
implementations/plain/rpc_message.cpp
|
|
implementations/plain/wire_codec.h
|
|
implementations/plain/json_mapping.h
|
|
implementations/plain/json_mapping.cpp
|
|
implementations/plain/json_codec.h
|
|
implementations/plain/json_codec.cpp
|
|
implementations/plain/cbor_codec.h
|
|
implementations/plain/cbor_codec.cpp
|
|
implementations/plain/rpc_framing.h
|
|
implementations/plain/rpc_framing.cpp
|
|
implementations/plain/incoming_call_handler.h
|
|
implementations/plain/rpc_connection.h
|
|
implementations/plain/rpc_server.h
|
|
implementations/plain/rpc_server.cpp
|
|
implementations/plain/io_context_pool.h
|
|
implementations/plain/io_context_pool.cpp
|
|
implementations/plain/qvariant_rpc_value.h
|
|
implementations/plain/qvariant_rpc_value.cpp
|
|
implementations/plain/plain_logos_object.h
|
|
implementations/plain/plain_logos_object.cpp
|
|
implementations/plain/plain_transport_host.h
|
|
implementations/plain/plain_transport_host.cpp
|
|
implementations/plain/plain_transport_connection.h
|
|
implementations/plain/plain_transport_connection.cpp
|
|
)
|
|
|
|
add_library(logos_protocol STATIC ${PROTOCOL_SOURCES})
|
|
|
|
# Link Qt + plain-C++ transport deps. Boost.Asio is header-only
|
|
# *except* for `boost::system::error_code` (and friends), which lives
|
|
# in libboost_system — see the matching note in logos-cpp-sdk.
|
|
# Boost.Asio's IOCP backend calls the Winsock EXTENSION functions AcceptEx and
|
|
# GetAcceptExSockaddrs, which live in mswsock rather than ws2_32. Without this
|
|
# the plain TCP transport compiles cleanly and then fails at link with
|
|
# "undefined reference to `AcceptEx'" out of
|
|
# win_iocp_socket_service_base::start_accept_op. ws2_32 supplies core Winsock
|
|
# and is listed explicitly rather than relied upon arriving via Qt::Network.
|
|
if(WIN32)
|
|
set(LOGOS_PROTOCOL_PLATFORM_LIBS ws2_32 mswsock)
|
|
else()
|
|
set(LOGOS_PROTOCOL_PLATFORM_LIBS "")
|
|
endif()
|
|
|
|
target_link_libraries(logos_protocol PUBLIC
|
|
Qt${QT_VERSION_MAJOR}::Core
|
|
Qt${QT_VERSION_MAJOR}::RemoteObjects
|
|
Boost::headers
|
|
${LOGOS_BOOST_SYSTEM}
|
|
OpenSSL::SSL
|
|
OpenSSL::Crypto
|
|
nlohmann_json::nlohmann_json
|
|
${LOGOS_PROTOCOL_PLATFORM_LIBS}
|
|
)
|
|
|
|
target_include_directories(logos_protocol PUBLIC
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/qt_local>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/qt_remote>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/mock>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/plain>
|
|
$<INSTALL_INTERFACE:include>
|
|
$<INSTALL_INTERFACE:include/implementations/qt_local>
|
|
$<INSTALL_INTERFACE:include/implementations/qt_remote>
|
|
$<INSTALL_INTERFACE:include/implementations/mock>
|
|
$<INSTALL_INTERFACE:include/implementations/plain>
|
|
)
|
|
|
|
set_target_properties(logos_protocol PROPERTIES
|
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
|
)
|
|
|
|
install(TARGETS logos_protocol
|
|
EXPORT logos-protocolTargets
|
|
ARCHIVE DESTINATION lib
|
|
LIBRARY DESTINATION lib
|
|
RUNTIME DESTINATION bin
|
|
INCLUDES DESTINATION include
|
|
)
|
|
|
|
# Shared variant of the same sources, exporting the language-neutral lp_*
|
|
# C ABI (extern "C", default visibility) as a loadable library. This exists
|
|
# purely for OUT-OF-PLUGIN callers that bind lp_* at runtime via dlopen/FFI
|
|
# (e.g. logos-js-sdk's koffi.load, logos-rust-sdk's callerBuildSupport) —
|
|
# the role liblogos_module_client previously filled. In-plugin code keeps
|
|
# linking the STATIC `logos_protocol` archive through the EXPORT set below.
|
|
#
|
|
# This target is EXPORTED as of this commit, where it was previously installed
|
|
# but deliberately kept out of the CMake package. The reason it now has to be is
|
|
# a second class of consumer: IN-PROCESS C++ images that link it as the single
|
|
# provider of the runtime types which must exist exactly once per process
|
|
# (TokenManager, LogosAPIClient, the per-identity StoreRegistry). Linking one
|
|
# shared library is what replaces the whole-archive + generated-.def scheme, in
|
|
# which liblogos_core absorbed both static archives and re-exported them. A
|
|
# consumer cannot link what find_package() does not hand it.
|
|
#
|
|
# OUT-OF-PROCESS consumers keep linking the STATIC archive, and that is not a
|
|
# transitional state: module plugins and ui_qml backends run in their own
|
|
# processes, so their own copy of TokenManager is the CORRECT per-process
|
|
# singleton. Staying static also keeps a .lgx self-contained -- a .lgx records
|
|
# an empty nix closure, so a shared library would not travel with it -- and
|
|
# keeps those plugins immune to ABI skew against a separately-updated .so.
|
|
add_library(logos_protocol_shared SHARED ${PROTOCOL_SOURCES})
|
|
|
|
target_link_libraries(logos_protocol_shared PUBLIC
|
|
Qt${QT_VERSION_MAJOR}::Core
|
|
Qt${QT_VERSION_MAJOR}::RemoteObjects
|
|
Boost::headers
|
|
${LOGOS_BOOST_SYSTEM}
|
|
OpenSSL::SSL
|
|
OpenSSL::Crypto
|
|
nlohmann_json::nlohmann_json
|
|
${LOGOS_PROTOCOL_PLATFORM_LIBS}
|
|
)
|
|
|
|
# Only the SHARED build marks the lp_* C ABI dllexport; the static archive
|
|
# leaves LP_API empty so consumers linking it need no import library.
|
|
target_compile_definitions(logos_protocol_shared PRIVATE LOGOS_PROTOCOL_BUILDING_SHARED)
|
|
|
|
# The INSTALL_INTERFACE half mirrors the static target exactly. Without it an
|
|
# exported target carries no include directories at all, and the failure is a
|
|
# confusing one: the target imports fine and the link succeeds, then the
|
|
# consumer fails to COMPILE on `#include "token_manager.h"`.
|
|
target_include_directories(logos_protocol_shared PUBLIC
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/qt_local>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/qt_remote>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/mock>
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/implementations/plain>
|
|
$<INSTALL_INTERFACE:include>
|
|
$<INSTALL_INTERFACE:include/implementations/qt_local>
|
|
$<INSTALL_INTERFACE:include/implementations/qt_remote>
|
|
$<INSTALL_INTERFACE:include/implementations/mock>
|
|
$<INSTALL_INTERFACE:include/implementations/plain>
|
|
)
|
|
|
|
# Same basename as the archive (liblogos_protocol.{so,dylib}); the LIBRARY
|
|
# install below lands it in $out/lib next to liblogos_protocol.a.
|
|
set_target_properties(logos_protocol_shared PROPERTIES
|
|
OUTPUT_NAME logos_protocol
|
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
|
)
|
|
|
|
# ARCHIVE DESTINATION is NOT redundant here. On Windows a shared library's
|
|
# import library (.dll.a) is the ARCHIVE artifact and the DLL itself is RUNTIME,
|
|
# so without an ARCHIVE destination the import library is never installed and a
|
|
# consumer that find_package()s this target gets an imported SHARED target whose
|
|
# IMPORTED_IMPLIB does not exist. It links fine on ELF and Mach-O, where there is
|
|
# no import library at all, and fails only on Windows.
|
|
# PE export table for the shared library, generated from the objects.
|
|
#
|
|
# Not needed off Windows: ELF and Mach-O export a shared library's non-hidden
|
|
# symbols by default, which is exactly why the shortfall this replaces was
|
|
# invisible until a Windows link.
|
|
if(WIN32)
|
|
# CMAKE_NM is normally set by the toolchain file; fall back to the
|
|
# cross-prefixed binary so a plain `cmake -DCMAKE_TOOLCHAIN_FILE=...` still
|
|
# generates. A missing nm must fail HERE, loudly, rather than silently
|
|
# emitting an empty .def -- an empty export table links clean and fails in a
|
|
# downstream repo as an undefined reference.
|
|
set(_lp_nm "${CMAKE_NM}")
|
|
if(NOT _lp_nm)
|
|
find_program(_lp_nm NAMES "${CMAKE_CXX_COMPILER_TARGET}-nm" x86_64-w64-mingw32-nm nm)
|
|
endif()
|
|
if(NOT _lp_nm)
|
|
message(FATAL_ERROR
|
|
"nm not found, so liblogos_protocol.dll cannot be given an export "
|
|
"list. Windows requires one: PE exports nothing that is not named, "
|
|
"and a consumer linking the empty stand-in archive would then fail "
|
|
"with undefined references to the entire C++ runtime.")
|
|
endif()
|
|
|
|
# Generated from the STATIC archive, which is built from the same sources.
|
|
# "*" means every member: ld chooses archive members for reasons unrelated to
|
|
# our symbols, so a partial set is a downstream undefined reference.
|
|
set(_lp_def "${CMAKE_CURRENT_BINARY_DIR}/logos_protocol_shared_exports.def")
|
|
add_custom_command(
|
|
OUTPUT "${_lp_def}"
|
|
COMMAND ${CMAKE_COMMAND} -E env sh
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake/gen-shared-exports.sh"
|
|
"${_lp_nm}" "${_lp_def}"
|
|
"$<TARGET_FILE:logos_protocol>" "*"
|
|
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/gen-shared-exports.sh" logos_protocol
|
|
COMMENT "Generating liblogos_protocol export definition"
|
|
VERBATIM
|
|
)
|
|
add_custom_target(logos_protocol_shared_exports DEPENDS "${_lp_def}")
|
|
add_dependencies(logos_protocol_shared logos_protocol_shared_exports)
|
|
target_link_options(logos_protocol_shared PRIVATE "${_lp_def}")
|
|
set_property(TARGET logos_protocol_shared APPEND PROPERTY LINK_DEPENDS "${_lp_def}")
|
|
endif()
|
|
|
|
install(TARGETS logos_protocol_shared
|
|
EXPORT logos-protocolTargets
|
|
ARCHIVE DESTINATION lib
|
|
LIBRARY DESTINATION lib
|
|
RUNTIME DESTINATION bin
|
|
INCLUDES DESTINATION include
|
|
)
|
|
|
|
install(EXPORT logos-protocolTargets
|
|
FILE logos-protocolTargets.cmake
|
|
NAMESPACE logos-protocol::
|
|
DESTINATION lib/cmake/logos-protocol
|
|
)
|
|
|
|
include(CMakePackageConfigHelpers)
|
|
configure_package_config_file(
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/logos-protocolConfig.cmake.in"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-protocolConfig.cmake"
|
|
INSTALL_DESTINATION lib/cmake/logos-protocol
|
|
)
|
|
write_basic_package_version_file(
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-protocolConfigVersion.cmake"
|
|
VERSION 0.1.0
|
|
COMPATIBILITY SameMajorVersion
|
|
)
|
|
install(FILES
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-protocolConfig.cmake"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/logos-protocolConfigVersion.cmake"
|
|
DESTINATION lib/cmake/logos-protocol
|
|
)
|
|
|
|
# Install headers. Moved headers keep the exact relative paths they had when
|
|
# they shipped from logos-cpp-sdk, so downstream `#include "token_manager.h"`
|
|
# (etc.) keep resolving unchanged through propagated include dirs.
|
|
install(FILES
|
|
logos_protocol.h
|
|
logos_module_impl.h
|
|
# The canonical LIDL <-> JSON codec. Generated module glue includes it, so it
|
|
# has to ship with the library's headers, not just in the source export.
|
|
logos_codec.h
|
|
logos_call_error.h
|
|
logos_rpc_status.h
|
|
# Windows single-provider marker. token_manager.h / logos_api_client.h /
|
|
# logos_types.h include it, and so does logos-qt-sdk's logos_api.h, so it
|
|
# has to ship even though nothing in this library's own sources needs it.
|
|
logos_shared_api.h
|
|
logos_types.h
|
|
logos_api_client.h
|
|
logos_api_consumer.h
|
|
# Named by logos_api_client.h and logos_api_consumer.h alike; the client only
|
|
# forward-declares the consumer, so the enum cannot live in the consumer header.
|
|
logos_subscription_state.h
|
|
module_proxy.h
|
|
token_manager.h
|
|
logos_mode.h
|
|
logos_instance.h
|
|
logos_socket_paths.h
|
|
plugin_registry.h
|
|
logos_object.h
|
|
logos_thread_marshal.h
|
|
logos_provider_interface.h
|
|
logos_json_convert.h
|
|
logos_transport.h
|
|
logos_transport_config.h
|
|
logos_transport_config_json.h
|
|
logos_transport_factory.h
|
|
logos_registry.h
|
|
logos_registry_factory.h
|
|
DESTINATION include
|
|
)
|
|
|
|
install(FILES
|
|
implementations/plain/rpc_value.h
|
|
implementations/plain/rpc_message.h
|
|
implementations/plain/wire_codec.h
|
|
implementations/plain/json_codec.h
|
|
implementations/plain/rpc_framing.h
|
|
DESTINATION include/implementations/plain
|
|
)
|
|
|
|
install(FILES
|
|
implementations/qt_local/local_transport.h
|
|
DESTINATION include/implementations/qt_local
|
|
)
|
|
|
|
install(FILES
|
|
implementations/qt_remote/remote_transport.h
|
|
implementations/qt_remote/qt_remote_registry.h
|
|
DESTINATION include/implementations/qt_remote
|
|
)
|
|
|
|
install(FILES
|
|
implementations/mock/mock_store.h
|
|
implementations/mock/mock_transport.h
|
|
implementations/mock/mock_registry.h
|
|
implementations/mock/logos_mock.h
|
|
DESTINATION include/implementations/mock
|
|
)
|