You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Bazel中使用C++共享库时遇静态变量实例重复问题求助

问题分析:共享库中静态变量多副本导致值不一致

问题现象

构建两个共享库lib1.so、lib2.so及可执行文件main后,运行main时:

  • lib2的全局初始化函数向Services::vs()返回的静态vector中添加了2个元素,调用printvs()输出2
  • 但main中调用printvs()却输出0,不符合“所有调用共享同一个静态vector实例”的预期

根本原因

问题出在Bazel的构建配置上,导致同一个静态变量出现了多个独立副本:

  1. lib2.so打包了lib1的代码:lib2是用cc_binary(linkshared=1)构建的共享库,但其依赖的是lib1_lib(静态库目标),Bazel会将lib1_lib的代码静态打包进lib2.so,而非让lib2.so动态依赖lib1.so。这意味着lib2.so内部有一份独立的Services::vs()静态vector实例。
  2. main可执行文件又链接了一份lib1的代码:main的srcs直接包含:lib1和:lib2,同时deps依赖lib1_lib,这导致main自身也链接了一份lib1_lib的代码,拥有另一个独立的Services::vs()静态vector实例。

运行时,lib2初始化操作的是自己内部的vector副本,而main调用的是自身链接的vector副本,两者完全独立,因此出现输出不一致的情况。

解决方案:确保所有模块动态共享lib1.so的符号

调整BUILD配置,让lib2.so动态依赖lib1.so,同时让main动态链接这两个共享库,保证整个进程中只有一份Services::vs()的静态变量实例。

修改后的BUILD文件:

cc_library(
    name = "lib1_lib",
    srcs = ["lib1.cc"],
    hdrs = ["lib1.h"],
    visibility = ["//visibility:public"],
)

# 构建共享库lib1.so,动态导出符号
cc_binary(
    name = "lib1",
    deps = [":lib1_lib"],
    visibility = ["//visibility:public"],
    linkshared = 1,
)

cc_library(
    name = "lib2_lib",
    srcs = ["lib2.cc"],
    deps = [":lib1_lib"],
    visibility = ["//visibility:public"],
)

# 构建lib2.so,动态依赖lib1.so,避免静态打包lib1的代码
cc_binary(
    name = "lib2",
    deps = [":lib2_lib", ":lib1"],
    visibility = ["//visibility:public"],
    linkshared = 1,
)

# main仅依赖共享库,动态链接lib1.so和lib2.so
cc_binary(
    name = "main",
    srcs = ["main.cc"],
    deps = [":lib1_lib", ":lib2"],
)

修改说明

  • lib1的构建:将srcs改为deps,确保lib1.so是基于lib1_lib编译的共享库,正确导出所有符号。
  • lib2的构建:添加:lib1到deps中,让lib2.so动态链接lib1.so,而非将lib1的代码静态打包进去。
  • main的构建:移除srcs中的:lib1和:lib2,改为通过deps依赖共享库,确保main动态链接这两个共享库,所有调用都指向lib1.so中的同一个静态变量实例。

修改后运行main,lib2初始化时输出2,main中调用printvs()也会输出2,符合预期。

内容的提问来源于stack exchange,提问作者Steffen Roeber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:22:30