QDAirPortTestSystemBackend/CMakeLists.txt
2026-02-04 10:22:05 +08:00

259 lines
8.8 KiB
CMake
Raw Permalink 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.14...3.27)
# 设置 CMake 策略(移除非必要的新策略)
cmake_policy(SET CMP0074 NEW) # 保留必要的包根目录策略
# 包含 FetchContent 模块
include(FetchContent)
# 生成 compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(collision_avoidance)
# 静态链接选项:
# - 优先静态链接 Boost以及可选的 libcurl取决于系统是否提供静态库
# - 同时静态链接 libstdc++/libgcc减少目标机运行时依赖
option(LINK_STATIC_DEPS "Prefer static linking for third-party deps when available" OFF)
option(FULL_STATIC "Link fully static binary (-static). Requires static libs (glibc-static, libcurl.a, etc.)" OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# 检查编译器版本
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
message(FATAL_ERROR "GCC 版本需要 >= 7.0 以支持 C++17")
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
message(FATAL_ERROR "Clang 版本需要 >= 5.0 以支持 C++17")
endif()
endif()
# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# 设置 Boost
set(Boost_NO_WARN_NEW_VERSIONS 1)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
if(LINK_STATIC_DEPS)
set(Boost_USE_STATIC_LIBS ON)
# libcurl 静态库在 CentOS 7 上可能需要额外的 -devel/-static 包支持若不存在FindCURL 仍会回退到动态库
set(CURL_USE_STATIC_LIBS ON)
endif()
if(NOT APPLE)
# 允许外部通过 -DBOOST_ROOT/-DBOOST_LIBRARYDIR 覆盖(例如容器内自编译 Boost 到 /opt/boost-1.69
if(NOT DEFINED BOOST_ROOT)
# 旧环境默认(若存在 boost169 包)
set(BOOST_ROOT "/usr/include/boost169")
endif()
if(NOT DEFINED BOOST_LIBRARYDIR)
set(BOOST_LIBRARYDIR "/usr/lib64/boost169")
endif()
else()
# 在 macOS 上使用 Homebrew 安装的 Boost同样允许外部覆盖
if(NOT DEFINED BOOST_ROOT)
set(BOOST_ROOT "/opt/homebrew/Cellar/boost/1.87.0")
endif()
if(NOT DEFINED BOOST_LIBRARYDIR)
set(BOOST_LIBRARYDIR "/opt/homebrew/Cellar/boost/1.87.0/lib")
endif()
endif()
# 设置 CMake 策略(在 find_package(Boost) 前添加)
if(POLICY CMP0167)
cmake_policy(SET CMP0167 OLD) # 强制使用传统 FindBoost 模块
endif()
find_package(Boost 1.69.0 REQUIRED COMPONENTS
system
filesystem
thread
chrono
date_time
atomic
regex # 添加缺失的 regex 组件
)
# 添加 libcurl
find_package(CURL REQUIRED)
# JSON 库:优先使用系统包;若离线环境无法 FetchContent则允许用户提供本地源码路径
# 用法:
# -DLOCAL_NLOHMANN_JSON_SOURCE_DIR=/path/to/json (包含 CMakeLists.txt)
# 或安装系统包提供 nlohmann_json::nlohmann_json
set(LOCAL_NLOHMANN_JSON_SOURCE_DIR "" CACHE PATH "Local nlohmann/json source dir (offline fallback). Should contain CMakeLists.txt")
# 若仓库内已带 json 子目录,则默认优先使用它(避免 FetchContent 联网/卡住)
if(NOT LOCAL_NLOHMANN_JSON_SOURCE_DIR AND EXISTS "${CMAKE_SOURCE_DIR}/json/CMakeLists.txt")
set(LOCAL_NLOHMANN_JSON_SOURCE_DIR "${CMAKE_SOURCE_DIR}/json")
endif()
find_package(nlohmann_json QUIET)
if(NOT TARGET nlohmann_json::nlohmann_json)
if(LOCAL_NLOHMANN_JSON_SOURCE_DIR)
if(EXISTS "${LOCAL_NLOHMANN_JSON_SOURCE_DIR}/CMakeLists.txt")
message(STATUS "Using local nlohmann/json from: ${LOCAL_NLOHMANN_JSON_SOURCE_DIR}")
add_subdirectory("${LOCAL_NLOHMANN_JSON_SOURCE_DIR}" "${CMAKE_BINARY_DIR}/_deps/nlohmann_json-local")
else()
message(FATAL_ERROR "LOCAL_NLOHMANN_JSON_SOURCE_DIR is set but CMakeLists.txt not found under: ${LOCAL_NLOHMANN_JSON_SOURCE_DIR}")
endif()
else()
FetchContent_Declare(
nlohmann_json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.3
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(nlohmann_json)
endif()
endif()
if(NOT TARGET nlohmann_json::nlohmann_json)
message(FATAL_ERROR "nlohmann_json::nlohmann_json not available. Install a system package providing it or set -DLOCAL_NLOHMANN_JSON_SOURCE_DIR=<path-to-nlohmann-json-source>.")
endif()
# 源文件列表
set(LIB_SOURCES
src/collector/DataCollector.cpp
src/collector/DataSourceConfig.cpp
src/core/System.cpp
src/detector/CollisionDetector.cpp
src/detector/SafetyZone.cpp
src/network/HTTPDataSource.cpp
src/network/WebSocketServer.cpp
src/network/HTTPClient.cpp
src/network/TrafficLightHttpServer.cpp
src/network/TrafficLightTcpServer.cpp
src/network/ConfigHttpServer.cpp
src/spatial/CoordinateConverter.cpp
src/types/BasicTypes.cpp
src/types/VehicleData.cpp
src/vehicle/ControllableVehicles.cpp
src/config/AirportBounds.cpp
src/config/SystemConfig.cpp
src/config/IntersectionConfig.cpp
src/detector/TrafficLightDetector.cpp
)
# 创建主库
add_library(${PROJECT_NAME}_lib ${LIB_SOURCES})
target_include_directories(${PROJECT_NAME}_lib
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${Boost_INCLUDE_DIRS}
${CURL_INCLUDE_DIRS}
)
target_link_libraries(${PROJECT_NAME}_lib
PUBLIC
Boost::system
Boost::filesystem
Boost::thread
Boost::chrono
Boost::date_time
Boost::atomic
Boost::regex
nlohmann_json::nlohmann_json
Threads::Threads
-pthread
)
# CURL 链接:全静态时优先使用 CURL_LIBRARY/CURL_LIBRARIES避免使用可能指向错误路径的导入目标
if(FULL_STATIC)
if(CURL_INCLUDE_DIR)
target_include_directories(${PROJECT_NAME}_lib PUBLIC ${CURL_INCLUDE_DIR})
endif()
if(CURL_LIBRARY)
target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${CURL_LIBRARY})
else()
target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${CURL_LIBRARIES})
endif()
else()
if(TARGET CURL::libcurl)
target_link_libraries(${PROJECT_NAME}_lib PUBLIC CURL::libcurl)
else()
target_link_libraries(${PROJECT_NAME}_lib PUBLIC ${CURL_LIBRARIES})
endif()
endif()
if(LINK_STATIC_DEPS)
# FindCURL 在静态场景下通常不会把 libcurl 的传递依赖带出来;这里补充常见依赖。
# 若链接仍报缺库,可用你自编的 curl: `curl-config --static-libs` 得到完整列表再补齐。
target_link_libraries(${PROJECT_NAME}_lib PUBLIC dl z ssl crypto rt resolv)
endif()
# 创建主可执行文件
add_executable(${PROJECT_NAME} src/main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJECT_NAME}_lib)
if(LINK_STATIC_DEPS)
target_link_options(${PROJECT_NAME} PRIVATE -static-libstdc++ -static-libgcc)
endif()
if(FULL_STATIC)
target_link_options(${PROJECT_NAME} PRIVATE -static)
endif()
# 添加一个选项来控制是否编译测试
if(APPLE)
option(BUILD_TESTS "Build test cases" ON)
else()
option(BUILD_TESTS "Build test cases" OFF)
endif()
# 添加测试
if(BUILD_TESTS AND EXISTS "${CMAKE_SOURCE_DIR}/tests")
if(APPLE)
# macOS 使用 FetchContent 下载 googletest
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.15.2
)
FetchContent_MakeAvailable(googletest)
else()
# CentOS 也使用 FetchContent 下载 googletest
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.15.2
)
FetchContent_MakeAvailable(googletest)
endif()
# 添加 tests 子目录
add_subdirectory(tests)
endif()
# 打印配置信息
message(STATUS "CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
message(STATUS "PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARIES: ${Boost_LIBRARIES}")
message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
message(STATUS "CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
# 复制配置文件到构建目录
configure_file(${CMAKE_SOURCE_DIR}/config/system_config.json ${CMAKE_BINARY_DIR}/config/system_config.json COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/intersections.json ${CMAKE_BINARY_DIR}/config/intersections.json COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/airport_bounds.json ${CMAKE_BINARY_DIR}/config/airport_bounds.json COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/config/unmanned_vehicles.json ${CMAKE_BINARY_DIR}/config/unmanned_vehicles.json COPYONLY)
# 查找 Threads 包
find_package(Threads REQUIRED)
if(NOT APPLE)
target_link_libraries(collision_avoidance
PRIVATE
${PROJECT_NAME}_lib
)
endif()