BCU项目CMake 构建管理

一、先看文件结构

左图:工程目录

右图:core文件夹目录

二、理解 CMakeLists.txt

复制代码
##########1. 项目基本配置
cmake_minimum_required(VERSION 3.10) #指定 CMake 的最低版本为 3.10
project(BMS_Core) #定义项目名称为 BMS_Core
set(CMAKE_C_STANDARD 11) #强制使用 C11 标准编译 C 代码
set(CMAKE_CXX_STANDARD 17)#强制使用 C++17 标准编译 C++ 代码

##########2. 安装路径和目录创建
#设置安装根目录为当前源码目录(${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}") 
set(BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin") #可执行文件安装目录(<源码根>/bin)
set(LOG_DIR "${CMAKE_INSTALL_PREFIX}/logs") #日志文件目录(<源码根>/logs)
set(RUN_DIR "${CMAKE_INSTALL_PREFIX}/run") #运行时 PID 文件等目录(<源码根>/run)
file(MAKE_DIRECTORY ${BIN_DIR} ${LOG_DIR} ${RUN_DIR})#创建这三个目录(如果不存在)
#set指令是给某一变量赋值,这个变量可以是内部变量也可以自行创建的变量

##########3. 查找依赖库
#[[
find_package:CMake 命令,用于查找并加载外部软件包。
PkgConfig:是一个特殊的 CMake 包(模块名 PkgConfig),它提供了与 pkg-config 工具交互的能力。
REQUIRED:表示该包是必需的,如果找不到 CMake 会报错并终止配置
作用:启用 pkg_check_modules() 和 pkg_search_module() 两个函数,使得 CMake 能通过 pkg-config 来查找普通的 .pc 库
]]
find_package(PkgConfig REQUIRED) 

#[[
pkg_check_modules:由上面的 find_package(PkgConfig) 提供的函数
语法:pkg_check_modules(<prefix> [REQUIRED] [QUIET] <module> ...),例如:
GPIOD_FOUND -- 是否找到
GPIOD_INCLUDE_DIRS -- 头文件路径
GPIOD_LIBRARIES -- 库文件路径
GPIOD_LIBRARY_DIRS -- 库目录
GPIOD_CFLAGS -- 编译选项
GPIOD_LDFLAGS -- 链接选项

GPIOD:前缀(prefix)
REQUIRED:如果找不到 libgpiod 的 .pc 文件,CMake 会报错
libgpiod:要查找的 pkg-config 模块名称
]]
pkg_check_modules(GPIOD REQUIRED libgpiod) 
pkg_check_modules(SQLITE3 REQUIRED sqlite3) 
pkg_check_modules(LIBMODBUS REQUIRED libmodbus)


################4. 公共库定义
#[[
定义了一个变量 COMMON_LIBS,包含所有目标都需要链接的库:
pthread:POSIX 线程库
rt:实时库(clock_gettime, shm_open 等)
m:数学库
${SQLITE3_LIBRARIES}:sqlite3 库
]]
set(COMMON_LIBS pthread rt m ${SQLITE3_LIBRARIES})


################5. 构建 bcu_shared 可执行文件
#[[
源文件:../SQlite/bcu_shared.c。
链接:公共库。
编译选项:-Wall -Wextra(开启常见警告
]]
add_executable(bcu_shared ../SQlite/bcu_shared.c) 
target_link_libraries(bcu_shared ${COMMON_LIBS}) 
target_compile_options(bcu_shared PRIVATE -Wall -Wextra)

###############6. 构建 com_run 可执行文件
# ------------------------- # 🔥 只留 Linux,排除所有报错目录 # -------------------------
#[[
GLOB_RECURSE:递归收集 ../COM/iec104/ 下所有 .c 文件,存入 IEC104_SOURCES。
CONFIGURE_DEPENDS:如果添加/删除文件,CMake 会在构建时重新扫描(但非实时,建议手动重新配置)。
然后用 list(FILTER ... EXCLUDE REGEX ...) 过滤掉包含 win32, bsd, tls, mbedtls 路径的文件,排除 Windows/BSD 和 TLS 相关实现(因为目标平台为 Linux,且未启用 TLS)。
]]
file(GLOB_RECURSE IEC104_SOURCES CONFIGURE_DEPENDS ../COM/iec104/*.c ) 
list(FILTER IEC104_SOURCES EXCLUDE REGEX "win32") 
list(FILTER IEC104_SOURCES EXCLUDE REGEX "bsd") 
list(FILTER IEC104_SOURCES EXCLUDE REGEX "tls") 
list(FILTER IEC104_SOURCES EXCLUDE REGEX "mbedtls")

add_executable(com_run ../COM/rs485/rtu.c
    ../COM/can/can_thread.c
    ../COM/eth/eth_thread.c
    ../COM/global.c
    ../COM/iec104_adapter.c
    ${IEC104_SOURCES} )

#头文件搜索路径
target_include_directories(com_run PRIVATE ../COM
    ../COM/rs485
    ../COM/can
    ../COM/eth
    ../SQlite
    ../COM/iec104
    ../COM/iec104/inc
    ../COM/iec104/inc/api )

#[[
链接:公共库 + libmodbus。
编译选项:
-g:调试信息
-O0:关闭优化(便于调试)
-Wall -Wextra:开启警告,但后续用 -Wno-... 屏蔽了一些常见但无大碍的警告。

预定义宏:
CONFIG_USE_THREADS=1:启用线程支持。
CONFIG_USE_SEMAPHORES=1:启用信号量。
CONFIG_CS104_SUPPORT_TLS=0:禁用 TLS(传输层安全,因为未使用)。
]]
target_link_libraries(com_run ${COMMON_LIBS} ${LIBMODBUS_LIBRARIES}) target_compile_options(com_run PRIVATE -g -O0 -Wall -Wextra
    -Wno-unused-function
    -Wno-format
    -Wno-unused-variable
    -Wno-unused-parameter ) 
target_compile_definitions(com_run PRIVATE CONFIG_USE_THREADS=1
    CONFIG_USE_SEMAPHORES=1
    CONFIG_CS104_SUPPORT_TLS=0 )

###############7. 构建 asw 可执行文件(应用软件 Simulink 模型)
set(ASW_SOURCES ../ASW/ASW.cpp
    ../ASW/ASW_ert_rtw/ASW_data.c
    ../ASW/ASW_ert_rtw/ASW.c
    ../ASW/ASW_ert_rtw/rt_nonfinite.c
    ../ASW/ASW_ert_rtw/rtGetInf.c
    ../ASW/ASW_ert_rtw/rtGetNaN.c
    ../ASW/ASW_ert_rtw/SOX_Common.c ) 
add_executable(asw ${ASW_SOURCES}) 
target_include_directories(asw PRIVATE ../ASW ../ASW/ASW_ert_rtw) target_link_libraries(asw ${COMMON_LIBS}) 
target_compile_options(asw PRIVATE -pthread)


##################8. 构建 bs(BasicService)
add_executable(bs ../Service/BasicServices.cpp) 
target_link_libraries(bs ${COMMON_LIBS}) 
target_compile_options(bs PRIVATE -pthread)


##################9. 构建 collect(硬件采集)
add_executable(collect ../Collect/Collect.cpp) 
target_include_directories(collect PRIVATE ../SQlite ${GPIOD_INCLUDE_DIRS}) target_link_libraries(collect ${COMMON_LIBS} ${GPIOD_LIBRARIES}) target_compile_options(collect PRIVATE -std=c++11 -pthread)

##################10. 安装可执行文件
#将所有可执行文件安装到 ${BIN_DIR}(即源码根下的 bin 目录)。
install(TARGETS bcu_shared com_run asw bs collect RUNTIME DESTINATION ${BIN_DIR})

##################11. 配置并安装运行/停止脚本
#[[
configure_file:将 run_all.sh.in 和 stop_all.sh.in 模板文件中的 @VAR@ 替换为当前 CMake 变量值,生成 run_all.sh 和 stop_all.sh。
execute_process:给生成的脚本添加可执行权限。
]]
configure_file(run_all.sh.in run_all.sh @ONLY) 
configure_file(stop_all.sh.in stop_all.sh @ONLY) 
execute_process(COMMAND chmod +x run_all.sh) 
execute_process(COMMAND chmod +x stop_all.sh)


##################12. 准备 systemd 服务文件
set(SERVICE_DIR "/etc/systemd/system") 
configure_file(bcu_shared.service.in bcu_shared.service @ONLY) configure_file(com_run.service.in com_run.service @ONLY) 
configure_file(asw.service.in asw.service @ONLY) 
configure_file(bs.service.in bs.service @ONLY) 
configure_file(collect.service.in collect.service @ONLY)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bcu_shared.service
    ${CMAKE_CURRENT_BINARY_DIR}/com_run.service
    ${CMAKE_CURRENT_BINARY_DIR}/asw.service
    ${CMAKE_CURRENT_BINARY_DIR}/bs.service
    ${CMAKE_CURRENT_BINARY_DIR}/collect.service
    DESTINATION ${SERVICE_DIR} )
#[[
SERVICE_DIR:systemd 服务文件安装目录(/etc/systemd/system)。
对每个 .service.in 模板执行 configure_file,替换变量生成真正的 .service 文件。
然后通过 install(FILES ... DESTINATION ...) 将这些 .service 文件安装到 systemd 服务目录。
这样,执行 make install 后,所有服务文件就会复制到 /etc/systemd/system,之后可以用 systemctl enable/start 管理进程。
]]
相关推荐
Yunzenn9 小时前
深度解析字节前沿研究-Cola DLM第 04 章:Cola DLM 架构全景 —— 三层解耦的设计哲学
java·linux·python·深度学习·面试·github·transformer
皆圥忈9 小时前
Linux 进程从入门到实战(三)
linux
Bert.Cai10 小时前
Linux sort命令详解
linux·运维·服务器
开开心心就好10 小时前
免费无广告的批量卸载与系统清理工具
linux·服务器·网络·智能手机·rabbitmq·excel·memcached
艾莉丝努力练剑10 小时前
【Linux网络】Linux 网络编程:HTTP(五)HTTP收尾,从Cookie会话保持、抓包问题到 HTTPS 初识
linux·运维·服务器·网络·c++
时夜_Ryan10 小时前
JumpServer堡垒机:一键部署运维安全审计
linux·运维·服务器·网络·安全·centos
薛定猫AI10 小时前
【深度解析】用行为约束提升 AI Coding Agent:从 nine arm skills 看工程化智能体工作流设计
linux·运维·人工智能
charlie11451419110 小时前
嵌入式Linux驱动开发——Pinctrl 子系统架构深度解析
linux·驱动开发·系统架构
风曦Kisaki10 小时前
# Linux运维Day04:集群与 LVS 负载均衡(LVS-NAT 集群,LVS-DR 集群)
linux·运维·lvs