构建component_drivers报错 ‘sscanf_s’ was not declared

问题描述

在docker ubuntu:24.04.2_25.12环境下编译构建component_drivers组件报错:

../libraries/pmbus/pmbus.cpp:899:9: error: ‘sscanf_s’ was not declared in this scope;

sscanf_s替换为sscanf之后可以确实可以通过编译,但是我之前已经成功编译过了,后续因为环境异常重新创建了一个container正常配置就无法通过了

具体报错信息如下:

[284/690] Compiling C++ object libraries/pmbus/libdev_pmbus.so.p/pmbus.cpp.o
FAILED: libraries/pmbus/libdev_pmbus.so.p/pmbus.cpp.o 
c++ -Ilibraries/pmbus/libdev_pmbus.so.p -Ilibraries/pmbus -I../libraries/pmbus -Ilibraries -I../libraries -Isubprojects/libmcpp/include -I../subprojects/libmcpp/include -Isubprojects/libmcpp/src -I../subprojects/libmcpp/src -I../subprojects/libmcpp/stub -I/usr/include -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fdiagnostics-color=always -D_GLIBCXX_ASSERTIONS=1 -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -std=c++17 -O0 -g -Wall -Wextra -fvisibility=hidden -fpermissive -Wno-error=attributes -Wno-error=deprecated-declarations -fno-strict-aliasing -DENABLE_CONAN_COMPILE=0 -fPIC -Wall -Wno-unused-parameter -Wno-unused-variable -Wno-sign-compare -Wno-pedantic -Wno-deprecated-copy -fPIC -DBOOST_ALL_NO_LIB -Os -ffunction-sections -fdata-sections -MD -MQ libraries/pmbus/libdev_pmbus.so.p/pmbus.cpp.o -MF libraries/pmbus/libdev_pmbus.so.p/pmbus.cpp.o.d -o libraries/pmbus/libdev_pmbus.so.p/pmbus.cpp.o -c ../libraries/pmbus/pmbus.cpp
../libraries/pmbus/pmbus.cpp: In member function ‘std::string dev::pmbus::date_to_timestamp(const string&)’:
../libraries/pmbus/pmbus.cpp:899:9: error: ‘sscanf_s’ was not declared in this scope; did you mean ‘sscanf’?
  899 |     if (sscanf_s(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3) {
      |         ^~~~~~~~
      |         sscanf
[287/690] Compiling C++ object libraries/pmbus/libdev_pmbus.so.p/pmbus_FP1420.cpp.o
ninja: build stopped: subcommand failed.

感觉是个简单的环境问题,但是我没找到什么问题点,烦请大家帮忙解答下 :folded_hands:

环境信息

  • 操作系统:Docker Ubuntu 24.04

  • 软件版本:OpenUBMC 25.12

重现步骤

  1. 拉取最新的component_drivers源码
  2. 安装依赖:
    apt install meson
    apt install libboost-all-dev
    apt install libgtest-dev
  3. 编译组件:
    meson setup builddir
    meson compile -C builddir -j4

答案内容由AI生成,仅供参考:
:white_check_mark: 结论:当前报错因 sscanf_s 不被 Linux 支持导致,建议立即替换为 sscanf 并推动上游修复源码兼容性问题

点击此处查看详细分析解答

构建 component_drivers 报错 'sscanf_s' was not declared 问题分析与解决方案

在使用 Docker 环境(ubuntu:24.04.2_25.12 编译 component_drivers 组件时,出现如下错误:

../libraries/pmbus/pmbus.cpp:899:9: error: ‘sscanf_s’ was not declared in this scope; did you mean ‘sscanf’?
     if (sscanf_s(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3) {
         ^~~~~~~~
         sscanf

此问题虽可通过将 sscanf_s 手动替换为 sscanf 暂时解决,但并非根本办法,且用户反馈此前相同环境配置下可成功编译,说明存在环境或依赖版本不一致的问题


:magnifying_glass_tilted_left: 问题本质分析

1. sscanf_s 并非标准 C/C++ 函数

  • sscanf_s 是 Microsoft Visual C++ 提供的安全版本 scanf 系列函数,属于 ISO/IEC TR 24731-1 标准。
  • 在 Linux 系统(包括 Ubuntu 的 GCC 工具链)中:
    • 默认不支持 sscanf_s
    • 通常只提供 sscanf
    • 某些旧版 Conan 或特定 SDK 中可能通过宏定义兼容 sscanf_s,但这并非常态。

:white_check_mark: 因此,在 Linux 下使用 gcc/g++ 编译器时调用 sscanf_s,会导致 “未声明的标识符” 错误。


2. 为何之前可以编译成功?

根据上下文和 OpenUBMC 构建机制,可能原因有:

原因 说明
使用了不同版本的 SDK 或 toolchain 之前的容器可能使用了集成 Windows 兼容层补丁的旧 SDK 或 patched libstdc++,提供了 sscanf_s 的定义。
Conan 缓存中包含带补丁的 libmcpp 或 component_drivers 包 原构建成功可能是依赖某个预编译包(如 libmcpp),其头文件或链接库中包含 _s 函数的 stub 实现;重新创建容器后缓存丢失,触发源码构建失败。
交叉编译工具链配置不同 如果启用了特定的 sysroot 或交叉工具链(如华为定制 RTOS 工具链),有可能内置了安全函数;当前 native 构建未加载该配置。

3. sscanf_s 来源确认

从错误代码位置可见:

if (sscanf_s(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3)

这出现在 pmbus.cpp 文件中,属于 component_drivers 的 PMBus 驱动模块。该文件本不应依赖 Windows 特有的运行时函数。若源码中直接调用 sscanf_s,属于 平台不可移植性缺陷


:white_check_mark: 正确解决方案

:white_check_mark: 方案一:将 sscanf_s 替换为 sscanf(推荐临时方案)

修改文件:

../libraries/pmbus/pmbus.cpp

修改内容:

将:

if (sscanf_s(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3)

改为:

if (sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day) != 3)

:warning: 注意:由于 sscanf 不验证缓冲区大小,仅适用于已知格式、可信输入的安全场景(如配置文件解析)。当前使用场景(日期字符串解析)合理,可接受。

后续建议:

  • 提交 PR 至 component_drivers 仓库修复该平台兼容性问题。
  • 添加编译选项控制或宏定义兼容:
#ifdef _MSC_VER
    sscanf_s(...)
#else
    sscanf(...)
#endif

:white_check_mark: 方案二:定义宏兼容 _s 安全函数(适合过渡)

在编译时添加宏定义,模拟 sscanf_s 行为:

meson setup builddir --cmake-args -DCMAKE_CXX_FLAGS="-Dsscanf_s=sscanf"

或者修改 meson.build,加入全局编译定义:

add_global_arguments('-Dsscanf_s=sscanf', language: 'cpp')

:white_check_mark: 优点:无需修改源码,快速通过编译。
:cross_mark: 缺点:掩盖了移植性问题,不利于长期维护。


:white_check_mark: 方案三:检查 Conan 包和 SDK 版本一致性

确保当前使用的 SDK 和 Conan 组件版本与之前成功构建的一致:

  1. 检查当前环境 SDK 路径是否存在:

    ls /opt/RTOS/
    ls /opt/hcc_arm64le/
    

    若不存在,说明缺少交叉编译工具链。

  2. 确认 Conan remote 配置是否正确:

    conan remote list
    

    应包含 OpenUBMC 官方源如:

    conan-center: https://center.conan.io
    openubmc: https://conan.openubmc.cn/conan_1
    
  3. 使用稳定构建命令(如 bingo)而非手动 meson

    bingo build -b openUBMC -r openubmc_dev
    

    bingo 会自动处理依赖、环境变量、toolchain 设置等,避免手工配置偏差。


:pushpin: 根本原因总结

项目 内容
直接原因 sscanf_s 是 MSVC 特有函数,Linux GCC 环境不支持
根本原因 component_drivers 源码中存在非 POSIX 兼容的函数调用,违反跨平台原则
环境差异点 原始工作容器可能含有缓存包或定制运行时支持 _s 函数;新容器为纯净环境
构建方式问题 手动执行 meson 忽略了完整构建链中的预处理和宏定义

:white_check_mark: 推荐最佳实践

建议 说明
禁用 sscanf_s 直接调用 所有 OpenUBMC 组件应遵循 POSIX/LPX 标准,避免使用 MSVC 扩展
启用编译器警告级别最大化 使用 -Wall -Wextra -Werror 发现潜在可移植性问题
统一使用 bingobmcgo 构建 避免手工 setup 导致环境不一致
提交 Issue 或 PR 到 component_drivers 仓库 修复 pmbus.cpp 中的 sscanf_s 使用问题
文档规范:明确组件平台约束 若组件依赖特定运行时(如有 securec.h 支持),应在 README 中注明

:link: 参考资料


:white_check_mark: 结论:当前报错因 sscanf_s 不被 Linux 支持导致,建议立即替换为 sscanf 并推动上游修复源码兼容性问题

你是直接使用meson命令编译组件吗?使用bingo build试下。

1 个赞

sscanf_s 是由bmc_sdk里的一个库(libsoc_adapter的依赖huawei_secure_c)提供的安全版本sscanf, 需要使用bingo build 通过conan自动解析依赖和编译配置。

component_drivers依赖 libsoc_adapter

1 个赞

多谢解答,确实是这个原因,另外还有一个问题,使用bingo build编译构建可以指定使用的核心数量吗?我看-h似乎没有这个参数,直接运行会导致系统非常卡顿

bingo 工具本身没有这个功能。
component_drivers 这个组件比较特殊,编译的so比较多,非常耗性能。

好的,多谢

可以试下在conanfile.py 这里加个参数。

1 个赞