Bazel动态链接第三方DLL并打包至最终bin目录的问题咨询
Bazel构建时自动将第三方DLL输出到bin目录的可行方案
不要通过全局配置linkstatic=0配合cc_import实现DLL拷贝,该方案会强制全项目动态链接,不仅不符合构建预期,还会触发MinGW环境的链接兼容问题,以下两种方案无副作用可直接使用:
方案1:零依赖通用方案(适配所有Bazel版本、MinGW环境)
不需要引入额外外部规则,通过Bazel原生规则即可实现,完全不改动原有链接策略:
- 首先在第三方库存放目录的BUILD文件中,将所有需要拷贝的DLL收拢为文件组:
filegroup( name = "vendor_dlls", srcs = glob(["*.dll"]), # 替换为实际DLL的存放路径匹配规则 visibility = ["//visibility:public"], )
- 在你的可执行文件目标同目录的BUILD文件中,添加拷贝规则并绑定到可执行目标的data依赖:
cc_binary( name = "your_main_app", srcs = ["main.cpp"], # 原有deps配置完全保留,不需要修改任何linkstatic相关参数 deps = ["//third_party/your_vendor_lib:lib_target"], data = [":copy_vendor_dlls"], ) genrule( name = "copy_vendor_dlls", srcs = ["//third_party/your_vendor_lib:vendor_dlls"], outs = [".copied_dll_marker"], cmd = """ cp $(SRCS) $(RULEDIR) touch $@ """, )
参数说明:$(RULEDIR)就是Bazel最终输出可执行文件的bin目录,构建cc_binary时会自动触发该genrule,将所有DLL拷贝到可执行文件同目录,整个过程不会修改任何链接参数,MinGW链接流程不受影响。
方案2:多可执行文件场景的自动关联方案
如果项目中有多个可执行目标依赖这批DLL,不想逐个配置data依赖,可以用封装第三方库的方式实现自动关联:
- 封装第三方库时,将DLL文件配置到动态库参数中,不要设置全局
linkstatic=0 - MinGW环境下额外添加编译参数
-static-libgcc -static-libstdc++,即可规避动态链接导致的标准库符号不兼容问题 - 所有依赖该第三方库目标的cc_binary,构建时会自动将关联的DLL拷贝到输出bin目录,不需要额外配置
避坑说明:
cc_import的linkstatic=0参数是库级别的动态链接标记,一旦在上层依赖传递时开启,会强制整条依赖链上的目标都优先走动态链接,不仅会生成大量不必要的so/dll文件,还会和MinGW默认静态链接标准库的配置冲突,出现未定义引用的链接错误。
内容的提问来源于stack exchange,提问作者NightShade
相关产品推荐
相关产品推荐

