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=.") 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()