2025-08-22 16:57:29 +08:00
|
|
|
|
cmake_minimum_required(VERSION 3.22.0)
|
|
|
|
|
|
|
|
|
|
|
|
project(cmvr_es)
|
|
|
|
|
|
|
2026-07-23 12:52:30 +08:00
|
|
|
|
include(CTest)
|
|
|
|
|
|
|
2025-08-22 16:57:29 +08:00
|
|
|
|
# 设置C++标准
|
|
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
|
|
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
2026-01-14 14:04:07 +08:00
|
|
|
|
#set(CMAKE_CXX_FLAGS -pthread)
|
|
|
|
|
|
#set(CMAKE_CXX_STANDARD_REQUIRED True)
|
2025-08-22 16:57:29 +08:00
|
|
|
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
|
|
|
|
|
2026-01-16 15:06:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 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")
|
|
|
|
|
|
|
2026-07-23 12:52:30 +08:00
|
|
|
|
# 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()
|
|
|
|
|
|
|
2026-01-16 15:06:12 +08:00
|
|
|
|
# Use RUNPATH (new dtags) generally preferable
|
|
|
|
|
|
set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
|
|
|
|
|
|
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
|
|
|
|
|
|
2025-08-22 16:57:29 +08:00
|
|
|
|
###########################################################
|
|
|
|
|
|
## DEPENDENCIES
|
|
|
|
|
|
#############################################################
|
2026-01-14 14:04:07 +08:00
|
|
|
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
|
|
|
|
|
include(FindExternalLib)
|
2026-07-23 12:52:30 +08:00
|
|
|
|
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}")
|
2026-01-14 14:04:07 +08:00
|
|
|
|
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}")
|
2025-08-22 16:57:29 +08:00
|
|
|
|
find_package(protobuf REQUIRED)
|
|
|
|
|
|
find_package(gRPC REQUIRED)
|
2025-12-05 16:33:11 +08:00
|
|
|
|
|
2026-07-23 12:52:30 +08:00
|
|
|
|
option(CMVR_ENABLE_MSQUIC_BACKEND
|
|
|
|
|
|
"Enable the MsQuic backend for the QUIC edge service when available"
|
|
|
|
|
|
ON)
|
2026-07-24 12:35:04 +08:00
|
|
|
|
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)
|
2026-07-23 12:52:30 +08:00
|
|
|
|
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()
|
2026-07-24 12:35:04 +08:00
|
|
|
|
elseif(CMVR_REQUIRE_MSQUIC)
|
|
|
|
|
|
message(FATAL_ERROR
|
|
|
|
|
|
"CMVR_REQUIRE_MSQUIC=ON requires CMVR_ENABLE_MSQUIC_BACKEND=ON")
|
2026-07-23 12:52:30 +08:00
|
|
|
|
endif()
|
|
|
|
|
|
|
2025-08-22 16:57:29 +08:00
|
|
|
|
############################################################
|
2026-01-27 11:38:07 +08:00
|
|
|
|
# PROTO , 遇到proto 的生成问题,现在build 目录执行 cmake --install . --verbose ,然后编译即可
|
2025-08-22 16:57:29 +08:00
|
|
|
|
############################################################
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
2025-12-15 17:01:32 +08:00
|
|
|
|
|
2026-01-27 11:38:07 +08:00
|
|
|
|
|
|
|
|
|
|
set(Protobuf_PROTOC_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bin/protoc" CACHE FILEPATH "" FORCE)
|
2026-07-02 12:30:07 +08:00
|
|
|
|
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"
|
2026-01-27 11:38:07 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2025-12-15 17:01:32 +08:00
|
|
|
|
# 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)
|
2025-08-22 16:57:29 +08:00
|
|
|
|
|
|
|
|
|
|
protobuf_generate(
|
|
|
|
|
|
TARGET proto-objects
|
|
|
|
|
|
IMPORT_DIRS ${PROTO_IMPORT_DIR}
|
|
|
|
|
|
PROTOC_OUT_DIR ${PROTO_BINARY_DIR}
|
2025-12-15 17:01:32 +08:00
|
|
|
|
USAGE_REQUIREMENT PRIVATE
|
2025-08-22 16:57:29 +08:00
|
|
|
|
)
|
|
|
|
|
|
protobuf_generate(
|
|
|
|
|
|
TARGET proto-objects
|
|
|
|
|
|
LANGUAGE grpc
|
|
|
|
|
|
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
|
2026-01-21 16:30:13 +08:00
|
|
|
|
PLUGIN "protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
|
2025-08-22 16:57:29 +08:00
|
|
|
|
IMPORT_DIRS ${PROTO_IMPORT_DIR}
|
|
|
|
|
|
PROTOC_OUT_DIR ${PROTO_BINARY_DIR}
|
2025-12-15 17:01:32 +08:00
|
|
|
|
USAGE_REQUIREMENT PRIVATE
|
2025-08-22 16:57:29 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2025-12-15 17:01:32 +08:00
|
|
|
|
# 2) 把 OBJECT 打包成一个“唯一的”共享库(关键)
|
|
|
|
|
|
add_library(proto SHARED $<TARGET_OBJECTS:proto-objects>)
|
2026-01-14 14:04:07 +08:00
|
|
|
|
target_include_directories(proto PUBLIC ${PROTO_BINARY_DIR} ${PROTO_IMPORT_DIR} ${Protobuf_INCLUDE_DIRS})
|
2025-12-15 17:01:32 +08:00
|
|
|
|
target_link_libraries(proto PUBLIC protobuf::libprotobuf gRPC::grpc++ gRPC::grpc++_reflection)
|
|
|
|
|
|
add_library(cmvr_es::proto ALIAS proto)
|
2026-01-27 11:38:07 +08:00
|
|
|
|
#install(TARGETS proto RUNTIME DESTINATION bin)
|
|
|
|
|
|
install(TARGETS proto LIBRARY DESTINATION lib)
|
2025-08-22 16:57:29 +08:00
|
|
|
|
############################################################
|
|
|
|
|
|
# include
|
|
|
|
|
|
############################################################
|
|
|
|
|
|
include_directories(
|
|
|
|
|
|
/usr/local/include/
|
|
|
|
|
|
${PROTO_BINARY_DIR}
|
|
|
|
|
|
${PROJECT_SOURCE_DIR}/include
|
2026-01-14 14:04:07 +08:00
|
|
|
|
${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
|
2025-08-22 16:57:29 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
############################################################
|
|
|
|
|
|
# subdirectory
|
|
|
|
|
|
############################################################
|
|
|
|
|
|
|
2026-01-14 14:04:07 +08:00
|
|
|
|
add_subdirectory(cmvr-es)
|
2025-08-22 16:57:29 +08:00
|
|
|
|
|
|
|
|
|
|
############################################################
|
|
|
|
|
|
# executables
|
|
|
|
|
|
############################################################
|
|
|
|
|
|
|
2026-01-14 14:04:07 +08:00
|
|
|
|
add_executable(cmvr_es cmvr-es/main.cpp)
|
2025-08-22 16:57:29 +08:00
|
|
|
|
target_include_directories(cmvr_es PRIVATE ${GLOG_INCLUDE_DIRS})
|
|
|
|
|
|
target_link_libraries(cmvr_es PRIVATE
|
2025-12-15 17:01:32 +08:00
|
|
|
|
cmvr_es::proto
|
2026-06-24 15:45:54 +08:00
|
|
|
|
cmvr_es::logging
|
2026-07-23 12:52:30 +08:00
|
|
|
|
cmvr_es::quic_edge_task
|
2025-08-22 16:57:29 +08:00
|
|
|
|
${GLOG_LIBRARIES}
|
2026-01-14 14:04:07 +08:00
|
|
|
|
jsoncpp
|
2025-08-22 16:57:29 +08:00
|
|
|
|
cmvr_es::service
|
|
|
|
|
|
cmvr_es::hardware
|
|
|
|
|
|
cmvr_es::device::canbus
|
|
|
|
|
|
cmvr_es::device::ti5motor
|
2026-06-24 15:45:54 +08:00
|
|
|
|
cmvr_es::algorithms::controller
|
2025-11-10 16:54:06 +08:00
|
|
|
|
cmvr_es::ik_solver
|
2026-06-24 15:45:54 +08:00
|
|
|
|
cmvr_es::base_motion
|
2026-01-21 16:30:13 +08:00
|
|
|
|
cmvr_es::common
|
2026-06-24 15:45:54 +08:00
|
|
|
|
cmvr_es::task
|
|
|
|
|
|
cmvr_es::task_manager
|
|
|
|
|
|
ccd
|
|
|
|
|
|
fcl
|
2026-01-14 14:04:07 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
2026-01-16 15:06:12 +08:00
|
|
|
|
install(TARGETS cmvr_es RUNTIME DESTINATION bin)
|
2026-07-24 12:35:04 +08:00
|
|
|
|
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()
|