在Bazel中使用C++共享库时遇静态变量实例重复问题求助
问题分析:共享库中静态变量多副本导致值不一致
问题现象
构建两个共享库lib1.so、lib2.so及可执行文件main后,运行main时:
lib2的全局初始化函数向Services::vs()返回的静态vector中添加了2个元素,调用printvs()输出2- 但
main中调用printvs()却输出0,不符合“所有调用共享同一个静态vector实例”的预期
根本原因
问题出在Bazel的构建配置上,导致同一个静态变量出现了多个独立副本:
- lib2.so打包了lib1的代码:
lib2是用cc_binary(linkshared=1)构建的共享库,但其依赖的是lib1_lib(静态库目标),Bazel会将lib1_lib的代码静态打包进lib2.so,而非让lib2.so动态依赖lib1.so。这意味着lib2.so内部有一份独立的Services::vs()静态vector实例。 - 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
相关产品推荐
相关产品推荐

