# ============================================================================= # 项目名称: HyperLPR3-LinuxAPP # 功能: 车牌识别应用程序 # 优化目标: 减小可执行文件体积、提升编译效率、增强可移植性 # ============================================================================= # ----------------------------------------------------------------------------- # 1. CMake 最低版本要求 # 说明: 3.10.2 是 Ubuntu 18.04 默认版本,如需使用新特性可提高到 3.16+ # ----------------------------------------------------------------------------- #cmake_minimum_required(VERSION 3.10.2) #cmake_minimum_required(VERSION 3.16.2) #cmake_minimum_required(VERSION 3.28) #当前CMake 3.25.1 cmake_minimum_required(VERSION 3.25.1) # ----------------------------------------------------------------------------- # 2. 项目定义 # ----------------------------------------------------------------------------- project(HyperLPR3-LinuxAPP VERSION 1.0.0 DESCRIPTION "HyperLPR3 车牌识别 Linux 应用" LANGUAGES CXX C ) # ----------------------------------------------------------------------------- # 3. C++ 标准设置 # 说明: 使用 C++17 标准,启用标准强制检查 # ----------------------------------------------------------------------------- set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 强制要求编译器支持 C++17,不支持则报错 set(CMAKE_CXX_EXTENSIONS OFF) # 禁用编译器扩展(如 GNU++17),确保跨平台兼容 # ----------------------------------------------------------------------------- # 4. 构建类型设置 # 说明: # - Release: 发布模式,启用优化,去除调试信息,体积最小 # - Debug: 调试模式,保留调试信息,便于开发调试 # - RelWithDebInfo: 带调试信息的发布模式 # - MinSizeRel: 最小体积发布模式(比 Release 更激进优化体积) # ----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) endif() # 设置可选的构建类型(供 cmake-gui 或 ccmake 使用) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") # ----------------------------------------------------------------------------- # 5. 编译器优化标志(Release 模式专用) # 说明: 这些标志专门用于减小编译后的可执行文件体积 # ----------------------------------------------------------------------------- if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") # -O3: 最高级别优化(速度优先) # -Os: 优化代码大小(体积优先,推荐用于嵌入式) # -s: 去除符号表信息(strip) # -fvisibility=hidden: 隐藏符号,减少导出表大小 # -fvisibility-inlines-hidden: 隐藏内联函数符号 # -ffunction-sections -fdata-sections: 为每个函数/数据创建独立段 # -Wl,--gc-sections: 链接时删除未使用的段 # -Wl,--strip-all: 链接时去除所有符号 # -flto: 链接时优化(Link Time Optimization),可显著减小体积 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -s") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -s") # 可选: 启用 LTO(链接时优化)- 需要编译器支持,可减小 10-30% 体积 # 注意: 会增加编译时间,某些编译器可能有兼容性问题 # set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) # 可选: 最小体积模式(比 Release 更激进) # set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -s -fvisibility=hidden -fvisibility-inlines-hidden") endif() # ----------------------------------------------------------------------------- # 6. 优先使用动态链接库(减小可执行文件体积的关键) # 说明: # - ON: 优先查找动态库(.so),体积最小,但部署时需确保目标机有对应库 # - OFF: 优先查找静态库(.a),体积大但独立性强 # 建议: 开发/测试用动态库,发布时根据部署环境决定 # ----------------------------------------------------------------------------- option(USE_STATIC_LIBS "使用静态库链接(体积大但独立性强)" OFF) if(NOT USE_STATIC_LIBS) set(BUILD_SHARED_LIBS ON) # 设置动态库查找优先级 set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".so.1" ".so.0" ".a") else() set(BUILD_SHARED_LIBS OFF) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so") endif() # ----------------------------------------------------------------------------- # 7. 查找 PkgConfig 模块 # 说明: pkg-config 用于自动查找系统安装的库的头文件和链接参数 # ----------------------------------------------------------------------------- find_package(PkgConfig REQUIRED) # ----------------------------------------------------------------------------- # 8. 查找第三方库 # ----------------------------------------------------------------------------- # 8.1 FreeType2 - 字体渲染库 # 用途: 在图像上绘制中文字符 pkg_check_modules(FREETYPE REQUIRED freetype2) # 8.2 SQLite3 - 轻量级数据库 # 用途: 存储车牌识别记录 pkg_check_modules(SQLITE3 REQUIRED sqlite3) # 8.3 cURL - HTTP 客户端库 # 用途: 网络请求(如上传识别结果到服务器) find_package(CURL REQUIRED) # 8.4 OpenCV - 计算机视觉库(体积大户!) # 说明: 如果只需要核心模块,可以指定 COMPONENTS 减少依赖 # 例如: find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs highgui) find_package(OpenCV REQUIRED) # 8.5 OpenSSL - 加密/SSL 库 # 用途: HTTPS 请求、数据加密 find_package(OpenSSL REQUIRED) # 8.6 FFmpeg - 视频解码库(v43新增) # 用途: RTSP流解码,HEVC DRM硬件解码,H.264软解 pkg_check_modules(AVFORMAT REQUIRED libavformat) pkg_check_modules(AVCODEC REQUIRED libavcodec) pkg_check_modules(AVUTIL REQUIRED libavutil) pkg_check_modules(SWSCALE REQUIRED libswscale) # 8.7 libcrypt - 密码哈希库(fix24 auth系统新增) # 用途: bcrypt 密码哈希(通过系统 libcrypt 的 crypt_r) find_library(CRYPT_LIBRARY crypt PATHS /usr/lib /usr/lib/aarch64-linux-gnu /usr/lib/x86_64-linux-gnu /usr/local/lib DOC "libcrypt path" ) if(NOT CRYPT_LIBRARY) message(WARNING "libcrypt not found, auth system will not work. Install libcrypt-dev.") else() message(STATUS "Found libcrypt: ${CRYPT_LIBRARY}") endif() # ----------------------------------------------------------------------------- # 9. 查找 cJSON 库 # 说明: cJSON 可能没有 .pc 文件,使用多种方式查找 # ----------------------------------------------------------------------------- # 方法1: 尝试使用 pkg-config 查找(某些系统可能安装了 cjson.pc) pkg_check_modules(CJSON cjson) if(CJSON_FOUND) # 使用 pkg-config 找到的结果 message(STATUS "通过 pkg-config 找到 cJSON") set(CJSON_LIBRARY ${CJSON_LIBRARIES}) set(CJSON_INCLUDE_DIR ${CJSON_INCLUDE_DIRS}) else() # 方法2: 手动查找库文件 message(STATUS "pkg-config 未找到 cJSON,尝试手动查找...") # 查找库文件(优先动态库) find_library(CJSON_LIBRARY NAMES cjson PATHS /usr/lib /usr/lib/aarch64-linux-gnu /usr/lib/x86_64-linux-gnu /usr/local/lib /opt/cjson/lib DOC "cJSON library path" ) # 查找头文件 find_path(CJSON_INCLUDE_DIR NAMES cJSON.h PATHS /usr/include /usr/include/cjson /usr/local/include /usr/local/include/cjson /opt/cjson/include DOC "cJSON header path" ) endif() # 检查是否找到 cJSON if(NOT CJSON_LIBRARY) message(WARNING "未找到 cJSON 库,尝试使用默认路径...") # 尝试常见默认路径 if(EXISTS "/usr/lib/aarch64-linux-gnu/libcjson.so") set(CJSON_LIBRARY "/usr/lib/aarch64-linux-gnu/libcjson.so") elseif(EXISTS "/usr/lib/x86_64-linux-gnu/libcjson.so") set(CJSON_LIBRARY "/usr/lib/x86_64-linux-gnu/libcjson.so") elseif(EXISTS "/usr/lib/libcjson.so") set(CJSON_LIBRARY "/usr/lib/libcjson.so") elseif(EXISTS "/usr/local/lib/libcjson.so") set(CJSON_LIBRARY "/usr/local/lib/libcjson.so") else() message(FATAL_ERROR "无法找到 cJSON 库!请安装: sudo apt install libcjson-dev") endif() endif() if(NOT CJSON_INCLUDE_DIR) # 如果找不到头文件目录,使用系统默认包含路径 # 并假设头文件直接在 /usr/include 下 if(EXISTS "/usr/include/cJSON.h") set(CJSON_INCLUDE_DIR "/usr/include") elseif(EXISTS "/usr/include/cjson/cJSON.h") set(CJSON_INCLUDE_DIR "/usr/include/cjson") else() message(WARNING "未找到 cJSON 头文件目录,使用系统默认路径") set(CJSON_INCLUDE_DIR "") # 空表示使用系统默认路径 endif() endif() # 验证找到的文件 message(STATUS "cJSON 库路径: ${CJSON_LIBRARY}") message(STATUS "cJSON 头文件路径: ${CJSON_INCLUDE_DIR}") if(NOT EXISTS ${CJSON_LIBRARY}) message(FATAL_ERROR "cJSON 库文件不存在: ${CJSON_LIBRARY}") endif() # ----------------------------------------------------------------------------- # 10. HyperLPR3 SDK 设置 # 说明: 车牌识别核心库,可能包含大型模型数据 # ----------------------------------------------------------------------------- set(HYPERLPR3_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/hyperlpr3") set(HYPERLPR3_INCLUDE_DIR "${HYPERLPR3_ROOT}/include") set(HYPERLPR3_LIB_DIR "${HYPERLPR3_ROOT}/lib") # 检查 SDK 是否存在 if(NOT EXISTS ${HYPERLPR3_INCLUDE_DIR}) message(FATAL_ERROR "HyperLPR3 SDK 头文件目录不存在: ${HYPERLPR3_INCLUDE_DIR}") endif() if(NOT EXISTS ${HYPERLPR3_LIB_DIR}) message(FATAL_ERROR "HyperLPR3 SDK 库目录不存在: ${HYPERLPR3_LIB_DIR}") endif() # 添加 SDK 库目录到链接器搜索路径 link_directories(${HYPERLPR3_LIB_DIR}) # ----------------------------------------------------------------------------- # 11. 包含目录设置 # 说明: 使用 target_include_directories 替代全局 include_directories(现代 CMake 推荐) # ----------------------------------------------------------------------------- # 源文件列表 set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/common.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/config.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rtsp_capture.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/plate_recognizer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/station_lock.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/database.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/network_client.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/feishu_client.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/web_server.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/monitor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/weight_scale.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/mqtt_client.cpp # ✅ fix24 功能一:登录认证系统 ${CMAKE_CURRENT_SOURCE_DIR}/src/bcrypt/bcrypt.c ${CMAKE_CURRENT_SOURCE_DIR}/src/auth_crypto.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/auth_db.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/auth_session.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/auth_middleware.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/auth_api.cpp # fix24 v24: Web管理功能 ${CMAKE_CURRENT_SOURCE_DIR}/src/system_monitor.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/frpc_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/ssh_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/log_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/system_metrics_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cvxFont.cpp ${CMAKE_CURRENT_SOURCE_DIR}/third_party/md5ex1.c ${CMAKE_CURRENT_SOURCE_DIR}/third_party/ini.c ) # 创建可执行文件 add_executable(PlateRecApp ${SOURCES}) # 为目标设置包含目录(PRIVATE 表示仅本目标使用) set(INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src # 模块头文件 ${PROJECT_SOURCE_DIR}/third_party # 第三方头文件 ${PROJECT_SOURCE_DIR} # 项目根目录 ${HYPERLPR3_INCLUDE_DIR} # HyperLPR3 SDK 头文件 ${OpenCV_INCLUDE_DIRS} # OpenCV 头文件 ${FREETYPE_INCLUDE_DIRS} # FreeType 头文件 ${SQLITE3_INCLUDE_DIRS} # SQLite3 头文件 ${AVFORMAT_INCLUDE_DIRS} # FFmpeg libavformat 头文件(v43新增) ${AVCODEC_INCLUDE_DIRS} # FFmpeg libavcodec 头文件(v43新增) ${AVUTIL_INCLUDE_DIRS} # FFmpeg libavutil 头文件(v43新增) ${SWSCALE_INCLUDE_DIRS} # FFmpeg libswscale 头文件(v43新增) ) # 只有当找到有效的 cJSON 头文件目录时才添加 if(CJSON_INCLUDE_DIR AND NOT CJSON_INCLUDE_DIR STREQUAL "") list(APPEND INCLUDE_DIRS ${CJSON_INCLUDE_DIR}) endif() target_include_directories(PlateRecApp PRIVATE ${INCLUDE_DIRS}) # ----------------------------------------------------------------------------- # 12. 链接库设置 # 说明: 链接顺序很重要!被依赖的库放在后面 # 顺序原则: 目标 <- 直接依赖 <- 间接依赖 <- 系统库 # ----------------------------------------------------------------------------- target_link_libraries(PlateRecApp PRIVATE # 1. HyperLPR3 SDK(车牌识别核心,可能包含模型数据) hyperlpr3 # 2. 数据库和配置库 ${SQLITE3_LIBRARIES} # SQLite3 # 3. 图像/字体处理库 ${FREETYPE_LIBRARIES} # FreeType2(字体渲染) ${OpenCV_LIBS} # OpenCV(计算机视觉,体积较大) # 4. 网络/加密库 CURL::libcurl # cURL(HTTP 客户端) ${OPENSSL_LIBRARIES} # OpenSSL(加密/HTTPS) mosquittopp # MQTT C++客户端(fix20新增) mosquitto # MQTT C库(fix20新增) ${CRYPT_LIBRARY} # libcrypt(密码哈希,fix24 auth系统新增) # 5. 数据格式库 ${CJSON_LIBRARY} # cJSON(JSON 解析) # 6. FFmpeg 视频解码库(v43新增) ${AVFORMAT_LIBRARIES} # libavformat(容器解封装) ${AVCODEC_LIBRARIES} # libavcodec(视频解码,含DRM硬解) ${AVUTIL_LIBRARIES} # libavutil(工具函数) ${SWSCALE_LIBRARIES} # libswscale(像素格式转换) # 7. 系统线程库(通常自动链接,显式指定更安全) pthread # 8. 数学库(某些平台需要) m # 9. 实时库(某些平台需要) rt ) # ----------------------------------------------------------------------------- # 13. 链接选项设置(体积优化) # ----------------------------------------------------------------------------- if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") # --as-needed: 只链接实际使用的符号(避免过度链接) # --gc-sections: 删除未使用的段 # -O1: 链接时优化级别 target_link_options(PlateRecApp PRIVATE "LINKER:--as-needed" "LINKER:--gc-sections" ) endif() # ----------------------------------------------------------------------------- # 14. 编译后处理(Release 模式) # 说明: 使用 strip 去除符号表,进一步减小体积 # ----------------------------------------------------------------------------- if(CMAKE_BUILD_TYPE STREQUAL "Release") add_custom_command(TARGET PlateRecApp POST_BUILD COMMAND ${CMAKE_STRIP} $ COMMENT "去除符号表以减小程序体积..." ) endif() # ----------------------------------------------------------------------------- # 15. 安装规则(可选) # 说明: 定义 make install 时的安装路径 # ----------------------------------------------------------------------------- install(TARGETS PlateRecApp RUNTIME DESTINATION bin # 可执行文件 LIBRARY DESTINATION lib # 动态库 ARCHIVE DESTINATION lib/static # 静态库 ) # ----------------------------------------------------------------------------- # 16. 输出配置信息(便于调试) # ----------------------------------------------------------------------------- message(STATUS "========================================") message(STATUS "项目配置信息:") message(STATUS " 项目名称: ${PROJECT_NAME}") message(STATUS " 项目版本: ${PROJECT_VERSION}") message(STATUS " C++ 标准: C++${CMAKE_CXX_STANDARD}") message(STATUS " 构建类型: ${CMAKE_BUILD_TYPE}") message(STATUS " 使用静态库: ${USE_STATIC_LIBS}") message(STATUS "----------------------------------------") message(STATUS "库路径信息:") message(STATUS " OpenCV: ${OpenCV_INCLUDE_DIRS}") message(STATUS " OpenCV 库: ${OpenCV_LIBS}") message(STATUS " HyperLPR3: ${HYPERLPR3_INCLUDE_DIR}") message(STATUS " cJSON 库: ${CJSON_LIBRARY}") message(STATUS " cJSON 头文件: ${CJSON_INCLUDE_DIR}") message(STATUS " libcrypt: ${CRYPT_LIBRARY}") message(STATUS "========================================") # ----------------------------------------------------------------------------- # 17. 体积优化建议(构建时提示) # ----------------------------------------------------------------------------- if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT USE_STATIC_LIBS) message(STATUS "") message(STATUS "【体积优化提示】") message(STATUS " 1. 当前使用动态链接,确保目标机安装以下库:") message(STATUS " - OpenCV: libopencv-core, libopencv-imgproc, ...") message(STATUS " - OpenSSL: libssl, libcrypto") message(STATUS " - SQLite3: libsqlite3") message(STATUS " - cJSON: libcjson") message(STATUS " - FreeType2: libfreetype") message(STATUS " - cURL: libcurl") message(STATUS " - libcrypt: libcrypt (密码哈希)") message(STATUS "") message(STATUS " 2. 如需静态链接(独立运行但体积大):") message(STATUS " cmake -DUSE_STATIC_LIBS=ON ..") message(STATUS "") message(STATUS " 3. 如需进一步减小体积,启用 LTO:") message(STATUS " 取消注释第 56 行的 set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)") message(STATUS "") endif()