cmake_minimum_required(VERSION 3.16) project(vmsig VERSION 0.3.3 LANGUAGES C) set(CMAKE_C_STANDARD 17) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) # epoll/eventfd/timerfd/clock_gettime: gnu ext option(VMSIG_LTO "Enable LTO" OFF) # Link the real sibling libraries (their .a, built with -fPIC). By default the spine # builds against headers only: the SI calls are hidden behind these flags, and the # stub mode proves the seam without a real VM. option(VMSIG_WITH_VMIE "Link real vmie (libvmie.a, PIC) for armed memctx" OFF) # ---- Sibling library source (set to your local checkout) -------------------- # vmie stays an EXTERNAL library (.so/.deb); only needed for the armed memctx build. # The input driver (vmctl) is ABSORBED in-tree (src/si/input/) — no external flag. set(LIBVMIE_PATH "" CACHE PATH "Path to the vmie library sources (for VMSIG_WITH_VMIE)") # ---- in-guest vgpu producer (Windows agent, cross-compiled) ----------------- # The host signaling stack below is Linux-only (epoll/eventfd/timerfd), so a Windows-targeted # build (mingw toolchain, CMAKE_SYSTEM_NAME=Windows) produces ONLY this agent. Producer and # host consumer share the ABI header include/vgpu_stream.h, so they version together in one tree. # cmake -S . -B .build-win -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-w64.cmake if(WIN32) add_executable(vgpu-streamer src/si/vgpu-stream/win32/main.c src/si/vgpu-stream/publish.c src/si/vgpu-stream/win32/region.c src/si/vgpu-stream/win32/present.c src/si/vgpu-stream/win32/cursor.c src/si/vgpu-stream/win32/geometry.c src/si/vgpu-stream/win32/capture.c src/si/vgpu-stream/win32/capture_nvfbc.c src/si/vgpu-stream/win32/capture_dda.c src/si/vgpu-stream/win32/capture_gdi.c) target_include_directories(vgpu-streamer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src/si/vgpu-stream/include ${CMAKE_CURRENT_SOURCE_DIR}/src/si/vgpu-stream/win32 ${CMAKE_CURRENT_SOURCE_DIR}/third_party) # vendor NvFBC + Windows.h shim target_compile_definitions(vgpu-streamer PRIVATE CINTERFACE WIN32_LEAN_AND_MEAN=) target_compile_options(vgpu-streamer PRIVATE $<$:-O2;-Wall;-Wextra> $<$:/O2;/W3>) target_link_libraries(vgpu-streamer PRIVATE d3d11 dxgi dxguid uuid user32 gdi32) target_link_options(vgpu-streamer PRIVATE $<$:-static;-s>) return() # a Windows-targeted build is the agent ONLY; the host stack below is skipped endif() find_package(Threads REQUIRED) # ---- signaling library ------------------------------------------------------ add_library(vmsig SHARED src/core/core.c src/core/linux/loop.c src/ctx/ctx.c src/adapter/linux/worker.c src/adapter/memctx/memctx.c src/adapter/input/input.c src/adapter/vmhost/vmhost.c src/control/inproc.c src/control/socket.c src/discovery/slot.c src/discovery/linux/host_probe.c src/discovery/discovery.c # SI input driver (vmctl), absorbed in-tree (host-only: QMP + uinput) src/si/input/open.c src/si/input/qmp.c src/si/input/qmp_driver.c src/si/input/keymap.c src/si/input/power.c src/si/input/linux/uinput_driver.c) target_include_directories(vmsig PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include ${CMAKE_CURRENT_SOURCE_DIR}/src/ctx/include ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/include ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/memctx/include ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/input/include ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/vmhost/include ${CMAKE_CURRENT_SOURCE_DIR}/src/discovery/include ${CMAKE_CURRENT_SOURCE_DIR}/src/si/input/include) target_link_libraries(vmsig PRIVATE Threads::Threads) # armed: vmie stays an EXTERNAL shared library (.so/.deb) — pre-built, IMPORTED. Both # libvmsig (armed memctx) and libvgpu-perception link it dynamically (no duplication; the # package Depends on libvmie). Headers + symbols come from the imported target. if(VMSIG_WITH_VMIE) add_library(vmie SHARED IMPORTED) if(LIBVMIE_PATH) # dev: link against an in-place source-tree build set_target_properties(vmie PROPERTIES IMPORTED_LOCATION ${LIBVMIE_PATH}/.build/libvmie.so INTERFACE_INCLUDE_DIRECTORIES ${LIBVMIE_PATH}/include) else() # CI/system: the installed libvmie-dev package (/usr, or via CMAKE_PREFIX_PATH) find_library(VMIE_LIBRARY NAMES vmie REQUIRED) find_path( VMIE_INCLUDE_DIR NAMES memmodel.h PATH_SUFFIXES vmie REQUIRED) set_target_properties(vmie PROPERTIES IMPORTED_LOCATION ${VMIE_LIBRARY} INTERFACE_INCLUDE_DIRECTORIES ${VMIE_INCLUDE_DIR}) endif() target_link_libraries(vmsig PRIVATE vmie) target_compile_definitions(vmsig PRIVATE VMSIG_WITH_VMIE) endif() target_compile_options(vmsig PRIVATE -O2 -Wall -Wextra) if(VMSIG_LTO) target_compile_options(vmsig PRIVATE -flto) target_link_options(vmsig PRIVATE -flto) endif() # ---- demonstrator on top of the library (like vmie_cli / vmctl) ------------- add_executable(vmsig_cli src/cli.c) target_link_libraries(vmsig_cli PRIVATE vmsig) target_compile_options(vmsig_cli PRIVATE -Wall -Wextra) # ---- vgpu-perception: host-side vgpu Sensor S-lib (absorbed in-tree) --------- # A SEPARATE shipped library (NOT fused into libvmsig — it is consumed by the shell, not the # signaling core). Host-only: reads the vgpu shared region from its own RO vmie_mem. Built # only when armed (needs vmie). The in-guest Windows producer (vgpu-streamer.exe) stays in a # separate repo and is NOT part of this delivery. if(VMSIG_WITH_VMIE) add_library(vgpu-perception SHARED src/si/vgpu-perception/discover.c src/si/vgpu-perception/sample.c src/si/vgpu-perception/control.c) target_include_directories(vgpu-perception PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/si/vgpu-perception/include) target_link_libraries(vgpu-perception PUBLIC vmie) # memmodel.h/win32.h via the vmie target target_compile_options(vgpu-perception PRIVATE -O2 -Wall -Wextra) add_executable(vgpu_perceptiontest src/test/test_perception.c) target_include_directories(vgpu_perceptiontest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/si/vgpu-perception/include) target_link_libraries(vgpu_perceptiontest PRIVATE vgpu-perception) target_compile_options(vgpu_perceptiontest PRIVATE -O2 -Wall -Wextra) add_test(NAME vgpu_perception COMMAND vgpu_perceptiontest) set_tests_properties(vgpu_perception PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${LIBVMIE_PATH}/.build:${CMAKE_BINARY_DIR}") endif() # ---- vmsigd: the management daemon ----------------------------------------- # Links libvmsig (works in stub or armed; armed memctx needs vmie at runtime). Discovery + # socket + a coarse per-uid admission policy; serves whatever appears under the watch dir. add_executable(vmsigd src/daemon/vmsigd.c src/daemon/config.c src/daemon/admission.c) target_link_libraries(vmsigd PRIVATE vmsig Threads::Threads) target_include_directories(vmsigd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/daemon/include ${CMAKE_CURRENT_SOURCE_DIR}/src/discovery/include ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include) target_compile_options(vmsigd PRIVATE -O2 -Wall -Wextra) if(VMSIG_LTO) target_compile_options(vmsigd PRIVATE -flto) target_link_options(vmsigd PRIVATE -flto) endif() # ---- transfer-context tests (ctest) ----------------------------------------- enable_testing() add_executable(vmsig_test src/test/test_ctx.c) target_link_libraries(vmsig_test PRIVATE vmsig) target_compile_options(vmsig_test PRIVATE -Wall -Wextra) add_test(NAME ctx COMMAND vmsig_test) add_executable(vmsig_sectest src/test/test_sec.c) target_link_libraries(vmsig_sectest PRIVATE vmsig) target_compile_options(vmsig_sectest PRIVATE -Wall -Wextra) add_test(NAME sec COMMAND vmsig_sectest) add_executable(vmsig_socktest src/test/test_sock.c) target_link_libraries(vmsig_socktest PRIVATE vmsig Threads::Threads) target_include_directories(vmsig_socktest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/memctx/include) target_compile_options(vmsig_socktest PRIVATE -Wall -Wextra) add_test(NAME sock COMMAND vmsig_socktest) add_executable(vmsig_mvmtest src/test/test_mvm.c) target_link_libraries(vmsig_mvmtest PRIVATE vmsig) target_compile_options(vmsig_mvmtest PRIVATE -Wall -Wextra) add_test(NAME mvm COMMAND vmsig_mvmtest) add_executable(vmsig_dyneptest src/test/test_dynep.c) target_link_libraries(vmsig_dyneptest PRIVATE vmsig Threads::Threads) target_compile_options(vmsig_dyneptest PRIVATE -Wall -Wextra) add_test(NAME dynep COMMAND vmsig_dyneptest) add_executable(vmsig_rostertest src/test/test_roster.c) target_link_libraries(vmsig_rostertest PRIVATE vmsig) target_include_directories(vmsig_rostertest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include) target_compile_options(vmsig_rostertest PRIVATE -Wall -Wextra) add_test(NAME roster COMMAND vmsig_rostertest) add_executable(vmsig_slottest src/test/test_slot.c) target_link_libraries(vmsig_slottest PRIVATE vmsig) target_include_directories(vmsig_slottest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/discovery/include) target_compile_options(vmsig_slottest PRIVATE -Wall -Wextra) add_test(NAME slot COMMAND vmsig_slottest) add_executable(vmsig_discoverytest src/test/test_discovery.c) target_link_libraries(vmsig_discoverytest PRIVATE vmsig) target_include_directories(vmsig_discoverytest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/discovery/include) target_compile_options(vmsig_discoverytest PRIVATE -Wall -Wextra) add_test(NAME discovery COMMAND vmsig_discoverytest) add_executable(vmsig_daemoncfgtest src/test/test_daemoncfg.c src/daemon/config.c src/daemon/admission.c) target_link_libraries(vmsig_daemoncfgtest PRIVATE vmsig) target_include_directories(vmsig_daemoncfgtest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/daemon/include ${CMAKE_CURRENT_SOURCE_DIR}/src/discovery/include) target_compile_options(vmsig_daemoncfgtest PRIVATE -Wall -Wextra) add_test(NAME daemoncfg COMMAND vmsig_daemoncfgtest) add_executable(vmsig_authztest src/test/test_authz.c) target_link_libraries(vmsig_authztest PRIVATE vmsig) target_compile_options(vmsig_authztest PRIVATE -Wall -Wextra) add_test(NAME authz COMMAND vmsig_authztest) add_executable(vmsig_memctxtest src/test/test_memctx.c) target_link_libraries(vmsig_memctxtest PRIVATE vmsig Threads::Threads) target_include_directories(vmsig_memctxtest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/memctx/include) target_compile_options(vmsig_memctxtest PRIVATE -Wall -Wextra) add_test(NAME memctx COMMAND vmsig_memctxtest) add_executable(vmsig_vmhosttest src/test/test_vmhost.c) target_link_libraries(vmsig_vmhosttest PRIVATE vmsig Threads::Threads) target_include_directories(vmsig_vmhosttest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/vmhost/include) target_compile_options(vmsig_vmhosttest PRIVATE -Wall -Wextra) add_test(NAME vmhost COMMAND vmsig_vmhosttest) add_executable(vmsig_leasetest src/test/test_lease.c) target_link_libraries(vmsig_leasetest PRIVATE vmsig Threads::Threads) target_include_directories(vmsig_leasetest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/core/include ${CMAKE_CURRENT_SOURCE_DIR}/src/ctx/include) target_compile_options(vmsig_leasetest PRIVATE -Wall -Wextra) add_test(NAME lease COMMAND vmsig_leasetest) add_executable(vmsig_inputobstest src/test/test_inputobs.c) target_link_libraries(vmsig_inputobstest PRIVATE vmsig Threads::Threads) target_compile_options(vmsig_inputobstest PRIVATE -Wall -Wextra) add_test(NAME inputobs COMMAND vmsig_inputobstest) add_executable(vmsig_memwritetest src/test/test_memwrite.c) target_link_libraries(vmsig_memwritetest PRIVATE vmsig Threads::Threads) target_include_directories(vmsig_memwritetest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/adapter/memctx/include) target_compile_options(vmsig_memwritetest PRIVATE -Wall -Wextra) add_test(NAME memwrite COMMAND vmsig_memwritetest) # the demonstrator doubles as an end-to-end seam test (self-terminates rc=0) add_test(NAME cli COMMAND vmsig_cli) # ---- install rules (for the .deb stage) ------------------------------------- option(VMSIG_INSTALL "Generate install() rules (daemon/lib/headers/unit/config)" OFF) if(VMSIG_INSTALL) include(GNUInstallDirs) install(TARGETS vmsigd RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) install(TARGETS vmsig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(TARGET vgpu-perception) # armed builds ship the host vgpu S-lib alongside install(TARGETS vgpu-perception LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() # public contracts (signaling + absorbed SI host headers) under include/vmsig/ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vmsig FILES_MATCHING PATTERN "vmsig*.h" PATTERN "vmctl.h" PATTERN "vgpu_stream.h" PATTERN "vgpu_perception.h") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/systemd/vmsigd.service DESTINATION lib/systemd/system) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/tmpfiles/vmsig.conf DESTINATION lib/tmpfiles.d) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/config/vmsigd.conf DESTINATION /etc/vmsig) endif()