集成构建xxxxx

1.解析 Conan 依赖

mds/service.json 里声明了构建依赖 libmc4lua/[>=1.1.0]。Conan 安装后会在构建目录的 generators/ 生成 libmc4lua-config.cmake 等文件;find_package 会加载它们。

2.注册可用的 CMake 目标(现代用法)

加载后可以使用 imported target,例如:

libmc4lua::libcutils --- 在 sml_base、sml_histore、platform 等里链接

libmc4lua::libmc4lua --- 在 l_sml/CMakeLists.txt 里链接(聚合了 libcutils)

设置传统变量(兼容旧写法)

同时会设置如 libmc4lua_INCLUDE_DIRS、libmc4lua_LIBRARIES 等,供仍用变量方式的 CMake 使用。

拉取传递依赖

生成的 config 还会 find_dependency 其依赖(如 json、huawei_secure_c、boost、liblogger 等),保证链接 libmc4lua 时依赖链完整。

set_target_properties(${L_SML_LIB} PROPERTIES PREFIX "") 用来去掉共享库文件名前面的默认 lib 前缀。

背景

第 4 行用 add_library(sml SHARED ...) 建的是共享库。在 Linux 上,CMake 默认会给共享库加 lib 前缀,产物一般是:

默认:libsml.so

设置 PREFIX "" 后:sml.so

为什么要这样

第 37 行把它安装到 opt/bmc/luaclib,这是 Lua 的 C 模块目录。Lua 用 require("sml") 加载时,会按 package.cpath 去找名为 sml.so 的模块,不会去找 libsml.so

若不加这句,编译出来是 libsml.so,运行时 require("sml") 会找不到模块。

小结

设置 产物文件名 Lua 能否 require("sml")

不写(默认)

libsml.so

通常不行

PREFIX ""

sml.so

可以

这是构建 Lua C 扩展(luaclib) 时的常见写法:让生成的 .so 文件名与 require 的模块名一致

pkg_search_module(GLIB REQUIRED glib-2.0) 通过 pkg-config 查找系统里的 GLib 2.0,并把结果放进以 GLIB_ 为前缀的 CMake 变量,供后面编译、链接使用。

会生成哪些变量

典型包括:

GLIB_INCLUDE_DIRS --- 头文件目录(如 /usr/include/glib-2.0)

GLIB_LIBRARIES --- 链接库(如 glib-2.0)

GLIB_CFLAGS / GLIB_LDFLAGS 等

使用:

target_include_directories(${L_SML_LIB}

...

PUBLIC GLIBINCLUDEDIRS)targetlinklibraries({GLIB_INCLUDE_DIRS} ) target_link_libraries(GLIBINCLUDEDIRS)targetlinklibraries({L_SML_LIB}

PUBLIC ${GLIB_LIBRARIES}

和 find_package(libmc4lua) 的区别

pkg_search_module:查系统/构建环境里通过 pkg-config 安装的库(GLib 一般由系统或 Conan 的 PkgConfigDeps 提供)

find_package(libmc4lua):查 Conan 包提供的 CMake 配置

service.json 的 dependencies:给 Conan 构建系统 用

在 MDS / 应用元数据 层声明:storage 构建时需要哪些 Conan 包。

会和 conanbase.py 里的 requirements() 一起参与依赖解析、安装、生成 CMake 配置。

conanbase.py 里也有类似声明:

def requirements(self):

self.requires("libmc4lua/[>=1.1.0]@openubmc/stable")

self.requires("mctpd/[>=0.0.1]@openubmc/stable")

self.requires("libmgmt_protocol/[>=1.70.6, include_prerelease=True]@openubmc/stable")

dependencies / requirements 负责 把包装进构建环境;find_package 负责 让 CMake 在编译时能用这些包。

对 libmc4lua、libmgmt_protocol 这类包,两边通常都要出现(一个拉包,一个链接)。

l_array.h的作用:

这是一个 纯静态工具类(无实例成员),职责只有两件事:

register_to:在模块加载时,把 SML_ARRAY_INFO_S 注册进 sml_core 导出表。

def_properties:声明该结构体在 Lua 里有哪些字段/属性(实现藏在 .cpp)。

和同目录的 l_ld、l_pd、l_ctrl 完全同一套模式:一个 C 结构体 ↔ 一个 l_xxx 类 ↔ 一个 register_to。

模块入口在 l_sml.cpp 里统一汇总:

LUA_EXPORT int luaopen_sml_core(lua_State *L)

{

...

l_array::register_to(L, t);

l_pd::register_to(L, t);

l_ld::register_to(L, t);

...

return 1;

}

编译产物是 sml.so(require 时模块名 sml_core),l_array 只是其中的一个子注册单元。

l_sml.h: 提供了2个模板函数

// 把结构体清空

template

void reset_zero(T *o) { ... }

// 把C的定长数组,如pd_ids[10] 转化成lua table

template

int push_array(lua_State *L, T *arr, size_t n)

{

auto t = luawrap::stack::new_table(L, n);

for (size_t i = 0; i < n; ++i) {

t.set(i + 1, arr[i]); // Lua 下标从 1 开始

}

return 1;

}

flowchart LR

A["require 'sml.core'"] --> B["luaopen_sml_core(L)"]

B --> C["创建空 table t"]

C --> D["各 l_xxx::register_to 往 t 填内容"]

D --> E["t.set 常量"]

E --> F["return 1 → Lua 得到模块表"]

F --> G["init.lua / cmds.lua 使用 sml_core.xxx"]








一句话

动态链接下:编译时必须靠头文件知道 debug_log 长什么样;libpd_log_parse_open.so 里只有调用和"依赖 liblogging.so"的记录;真正执行时由系统加载 liblogging.so 并提供实现------这就是 target_link_libraries(liblogger::liblogger) + #include 的标准分工。


相关推荐
Co_Hui3 小时前
Java: 集合
java·开发语言
ch.ju3 小时前
Java程序设计(第3版)第四章——动态部分
java·开发语言
_Evan_Yao3 小时前
从 select 到 epoll,再到 Agent 循环:如何用 I/O 多路复用撑起千军万马?
java·数据库·人工智能·后端
代码不停3 小时前
记忆化搜索题目练习
java·算法
长谷深风1113 小时前
SpringBoot开发秘籍【个人八股】
java·spring boot·后端·spring·八股
ch.ju3 小时前
Java Programming Chapter 4——Dynamic part
java·开发语言
隔窗听雨眠4 小时前
RPA + Java构建高并发智能抢票系统的完整实践
java·rpa·抢票·12306
Chase_______4 小时前
【Java基础核心知识点全解·第0篇】Java开发环境搭建指南:JDK + IDEA 从安装配置到运行 HelloWorld
java·开发语言·intellij-idea
布吉岛的石头4 小时前
Java 程序员第 19 阶段:大模型Agent智能体入门:拆解自主任务编排原理
java·开发语言·人工智能