cmvr-es/CMakeLists.txt
xtkuang 428ee328de feat: complete QUIC edge integration
Vendor MsQuic with build and install support, add DeviceManager status to configurable heartbeats, and report only enabled devices.

Add the local QUIC gateway, protocol coverage, real MsQuic E2E tests, process smoke tests, and updated integration documentation.
2026-07-24 12:35:04 +08:00

225 lines
8.2 KiB
CMake
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

cmake_minimum_required(VERSION 3.22.0)
project(cmvr_es)
include(CTest)
# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
#set(CMAKE_CXX_FLAGS -pthread)
#set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Install to <source>/output
set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/output" CACHE PATH "" FORCE)
# Make build-tree binaries runnable without LD_LIBRARY_PATH
set(CMAKE_BUILD_RPATH "\$ORIGIN:\$ORIGIN/../lib")
set(CMAKE_INSTALL_RPATH "\$ORIGIN:\$ORIGIN/../lib")
# Some vendor SDK directories contain an obsolete private libstdc++.so.6. They
# are still needed in the build RUNPATH for their own shared objects, but must
# not shadow the C++ runtime selected by the active compiler.
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=libstdc++.so.6
OUTPUT_VARIABLE CMVR_COMPILER_LIBSTDCXX
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(IS_ABSOLUTE "${CMVR_COMPILER_LIBSTDCXX}" AND EXISTS "${CMVR_COMPILER_LIBSTDCXX}")
# Do not put the whole system library directory first: that can mix the
# system FFmpeg with the repository's bundled FFmpeg. A one-library shim
# fixes only the vendor libstdc++ collision.
set(CMVR_COMPILER_RUNTIME_DIR "${CMAKE_BINARY_DIR}/cmvr_compiler_runtime")
file(MAKE_DIRECTORY "${CMVR_COMPILER_RUNTIME_DIR}")
file(CREATE_LINK
"${CMVR_COMPILER_LIBSTDCXX}"
"${CMVR_COMPILER_RUNTIME_DIR}/libstdc++.so.6"
SYMBOLIC COPY_ON_ERROR
RESULT CMVR_COMPILER_RUNTIME_LINK_RESULT)
if(CMVR_COMPILER_RUNTIME_LINK_RESULT STREQUAL "0")
list(PREPEND CMAKE_BUILD_RPATH "${CMVR_COMPILER_RUNTIME_DIR}")
else()
message(WARNING
"Could not prepare compiler libstdc++ build shim: "
"${CMVR_COMPILER_RUNTIME_LINK_RESULT}")
endif()
endif()
# Use RUNPATH (new dtags) generally preferable
set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
###########################################################
## DEPENDENCIES
#############################################################
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(FindExternalLib)
set(CMVR_ARCH "" CACHE STRING "Dependency architecture directory (x86 or arm)")
if(NOT CMVR_ARCH)
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" _cmvr_system_processor)
if(_cmvr_system_processor MATCHES "^(aarch64|arm64|arm)")
set(CMVR_ARCH "arm")
else()
set(CMVR_ARCH "x86")
endif()
endif()
set_property(CACHE CMVR_ARCH PROPERTY STRINGS x86 arm)
if(NOT CMVR_ARCH STREQUAL "x86" AND NOT CMVR_ARCH STREQUAL "arm")
message(FATAL_ERROR "CMVR_ARCH must be either 'x86' or 'arm', got: ${CMVR_ARCH}")
endif()
set(ARCH "${CMVR_ARCH}")
setup_external_libs(${ARCH})
# 在调用 setup_external_libs 之后
message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
message(STATUS "CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}")
find_package(protobuf REQUIRED)
find_package(gRPC REQUIRED)
option(CMVR_ENABLE_MSQUIC_BACKEND
"Enable the MsQuic backend for the QUIC edge service when available"
ON)
set(CMVR_MSQUIC_VERSION "2.5.9" CACHE STRING
"Exact MsQuic version expected by cmvr-es")
set(CMVR_MSQUIC_ROOT "" CACHE PATH
"Explicit MsQuic installation prefix")
option(CMVR_ALLOW_SYSTEM_MSQUIC
"Allow MsQuic discovery outside the repository or CMVR_MSQUIC_ROOT"
OFF)
option(CMVR_REQUIRE_MSQUIC
"Fail configuration when the requested MsQuic backend is unavailable"
OFF)
set(CMVR_HAS_MSQUIC OFF)
if(CMVR_ENABLE_MSQUIC_BACKEND)
find_package(MsQuic QUIET)
if(MsQuic_FOUND)
set(CMVR_HAS_MSQUIC ON)
message(STATUS "MsQuic found: ${MsQuic_LIBRARY}")
else()
message(STATUS "MsQuic not found; building QUIC edge in unavailable/stub mode")
endif()
elseif(CMVR_REQUIRE_MSQUIC)
message(FATAL_ERROR
"CMVR_REQUIRE_MSQUIC=ON requires CMVR_ENABLE_MSQUIC_BACKEND=ON")
endif()
############################################################
# PROTO , 遇到proto 的生成问题现在build 目录执行 cmake --install . --verbose ,然后编译即可
############################################################
set(PROTO_IMPORT_DIR ${PROJECT_SOURCE_DIR}/protos)
set(PROTO_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/_protobuf)
file(MAKE_DIRECTORY ${PROTO_BINARY_DIR})
file(GLOB_RECURSE PROTO_FILES ${PROTO_IMPORT_DIR}/*.proto)
set(Protobuf_PROTOC_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bin/protoc" CACHE FILEPATH "" FORCE)
set_target_properties(gRPC::grpc_cpp_plugin
PROPERTIES
IMPORTED_LOCATION "${CMAKE_INSTALL_PREFIX}/bin/grpc_cpp_plugin"
IMPORTED_LOCATION_RELEASE "${CMAKE_INSTALL_PREFIX}/bin/grpc_cpp_plugin"
)
# 1) 先做 OBJECT只负责生成/编译 pb.cc
add_library(proto-objects OBJECT)
target_sources(proto-objects PRIVATE ${PROTO_FILES})
set_target_properties(proto-objects PROPERTIES POSITION_INDEPENDENT_CODE ON)
protobuf_generate(
TARGET proto-objects
IMPORT_DIRS ${PROTO_IMPORT_DIR}
PROTOC_OUT_DIR ${PROTO_BINARY_DIR}
USAGE_REQUIREMENT PRIVATE
)
protobuf_generate(
TARGET proto-objects
LANGUAGE grpc
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
PLUGIN "protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
IMPORT_DIRS ${PROTO_IMPORT_DIR}
PROTOC_OUT_DIR ${PROTO_BINARY_DIR}
USAGE_REQUIREMENT PRIVATE
)
# 2) 把 OBJECT 打包成一个“唯一的”共享库(关键)
add_library(proto SHARED $<TARGET_OBJECTS:proto-objects>)
target_include_directories(proto PUBLIC ${PROTO_BINARY_DIR} ${PROTO_IMPORT_DIR} ${Protobuf_INCLUDE_DIRS})
target_link_libraries(proto PUBLIC protobuf::libprotobuf gRPC::grpc++ gRPC::grpc++_reflection)
add_library(cmvr_es::proto ALIAS proto)
#install(TARGETS proto RUNTIME DESTINATION bin)
install(TARGETS proto LIBRARY DESTINATION lib)
############################################################
# include
############################################################
include_directories(
/usr/local/include/
${PROTO_BINARY_DIR}
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/cmvr-es/devices
${PROJECT_SOURCE_DIR}/cmvr-es/utils
${PROJECT_SOURCE_DIR}/cmvr-es
${PROJECT_SOURCE_DIR}/dependency/${ARCH}/third_party
${PROJECT_SOURCE_DIR}/dependency/${ARCH}/third_party/osqp/v0.6.3/include/osqp
)
############################################################
# subdirectory
############################################################
add_subdirectory(cmvr-es)
############################################################
# executables
############################################################
add_executable(cmvr_es cmvr-es/main.cpp)
target_include_directories(cmvr_es PRIVATE ${GLOG_INCLUDE_DIRS})
target_link_libraries(cmvr_es PRIVATE
cmvr_es::proto
cmvr_es::logging
cmvr_es::quic_edge_task
${GLOG_LIBRARIES}
jsoncpp
cmvr_es::service
cmvr_es::hardware
cmvr_es::device::canbus
cmvr_es::device::ti5motor
cmvr_es::algorithms::controller
cmvr_es::ik_solver
cmvr_es::base_motion
cmvr_es::common
cmvr_es::task
cmvr_es::task_manager
ccd
fcl
)
install(TARGETS cmvr_es RUNTIME DESTINATION bin)
option(CMVR_INSTALL_DEFAULT_RUNTIME_ASSETS
"Install default config/model and replace their existing output copies"
ON)
if(CMVR_INSTALL_DEFAULT_RUNTIME_ASSETS)
install(CODE [[
file(REMOVE_RECURSE
"${CMAKE_INSTALL_PREFIX}/bin/config"
"${CMAKE_INSTALL_PREFIX}/bin/model")
]])
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmvr-es/config DESTINATION bin)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/model DESTINATION bin)
endif()
option(CMVR_BUILD_QUIC_TEST_GATEWAY
"Build the development-only QUIC gateway and real MsQuic integration tests"
${BUILD_TESTING})
if(CMVR_BUILD_QUIC_TEST_GATEWAY)
if(CMVR_HAS_MSQUIC)
add_subdirectory(test)
else()
message(WARNING
"CMVR_BUILD_QUIC_TEST_GATEWAY is ON, but no MsQuic backend was "
"found; the real QUIC gateway and integration tests are skipped")
endif()
endif()