# cpp/okvis2/CMakeLists.txt — OKVIS2 wrapper for C1 VIO (AZ-332). # # Builds the vendored OKVIS2 upstream (cpp/okvis2/upstream/, git submodule) # plus a pybind11 binding that exposes the estimator to the Python facade # at src/gps_denied_onboard/components/c1_vio/okvis2.py. # # Gating: BUILD_OKVIS2=ON only on linux production binaries (deployment + # research matrix kinds in .github/workflows/ci.yml). macOS dev builds # default BUILD_OKVIS2=OFF; unit tests use a fake pybind11 binding fixture # installed at sys.modules boundary (tests/unit/c1_vio/conftest.py). # # Bundled OKVIS2 deps (DBoW2, brisk, ceres-solver, opengv) are NOT pulled # into this clone — see ci.yml step that installs them via apt # (libceres-dev libsuitesparse-dev etc.) and the USE_SYSTEM_* flags below. if(NOT BUILD_OKVIS2) return() endif() message(STATUS "[okvis2] BUILD_OKVIS2=ON — building OKVIS2 upstream + pybind11 binding") # Tell OKVIS2 to use system-installed dependencies instead of its bundled # external/ submodules (which we do not initialise — saves ~hundreds of MB # and matches the Linux apt-deps approach in ci.yml). set(USE_SYSTEM_BRISK ON CACHE BOOL "AZ-332: use apt libbrisk-dev" FORCE) set(USE_SYSTEM_DBOW2 ON CACHE BOOL "AZ-332: use apt libdbow2-dev" FORCE) set(USE_SYSTEM_CERES ON CACHE BOOL "AZ-332: use apt libceres-dev" FORCE) # Trim OKVIS2's build surface — we link the estimator libs only. set(BUILD_APPS OFF CACHE BOOL "AZ-332: skip OKVIS2 demo apps" FORCE) set(BUILD_TESTS OFF CACHE BOOL "AZ-332: skip OKVIS2 gtests" FORCE) set(BUILD_ROS2 OFF CACHE BOOL "AZ-332: ROS 2 rejected at Plan time (D-C1-1-SUB-A)" FORCE) set(HAVE_LIBREALSENSE OFF CACHE BOOL "AZ-332: no realsense pipeline" FORCE) set(USE_NN OFF CACHE BOOL "AZ-332: drop LibTorch dep (keyframe arch OK per Fact #39)" FORCE) set(DO_TIMING OFF CACHE BOOL "AZ-332: disable per-frame timing prints" FORCE) set(BUILD_SHARED_LIBS OFF CACHE BOOL "AZ-332: link OKVIS as static into the .so" FORCE) # pybind11 (vendored at cpp/pybind11/upstream/) — guarded so a sibling # native binding (gtsam_bindings, faiss_index) cannot double-add the # subdirectory. if(NOT TARGET pybind11::module) add_subdirectory( ${CMAKE_SOURCE_DIR}/cpp/pybind11/upstream ${CMAKE_BINARY_DIR}/pybind11_build ) endif() # Vendored OKVIS2 upstream — EXCLUDE_FROM_ALL keeps unused targets out of # the default build graph; we depend on the okvis_* libs we explicitly # link below. add_subdirectory(upstream EXCLUDE_FROM_ALL) # pybind11 binding source — per module-layout.md rule #4 the binding code # lives next to the Python facade, not under cpp/. set(OKVIS2_BINDING_SRC ${CMAKE_SOURCE_DIR}/src/gps_denied_onboard/components/c1_vio/_native/okvis2_binding.cpp ) pybind11_add_module(okvis2_binding ${OKVIS2_BINDING_SRC}) # OKVIS2 export targets — exact list confirmed by walking upstream # CMakeLists in cpp/okvis2/upstream/okvis_*/. If a target name changes # upstream, the linker error on first CI run pinpoints which one. target_link_libraries(okvis2_binding PRIVATE okvis_ceres okvis_frontend okvis_multisensor_processing okvis_kinematics okvis_cv okvis_common okvis_time okvis_util ) target_compile_features(okvis2_binding PRIVATE cxx_std_17) # Install the .so next to the Python facade so the lazy import inside # okvis2.py (`from . import _native; _native.okvis2_binding`) resolves at # runtime without a sys.path shim. install(TARGETS okvis2_binding LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gps_denied_onboard/components/c1_vio/_native/ )