Windows11下用自定义MinGW工具链通过Bazel构建链接.dll的问题
MinGW ucrt64 + Bazel 动态库构建链接问题解决
问题简述
在Windows 11 Pro上用自定义MinGW ucrt64 GCC工具链,通过Bazel构建DLL和依赖它的可执行文件时,碰到两个棘手问题:
cc_shared_library默认输出.so后缀的库,但Windows下的ld根本不认.so,手动改成.dll后链接就正常了。- 改工具链的
artifact_name_patterns强制生成.dll后缀后,Bazel给ld传-l参数时居然带着.dll后缀,变成-lmath_d_shared.dll,ld转头就去找libmath_d_shared.dll.dll,直接报错找不到。
解决方案
方案1:自定义规则自动重命名动态库
修改你的dll_library.bzl规则,增加重命名步骤,把生成的.so转成.dll,同时包装成正确的库目标让Bazel传递正确的链接参数:
load("@rules_cc//cc:defs.bzl", "cc_library") load("@rules_cc//examples:experimental_cc_shared_library.bzl", "cc_shared_library") load("@bazel_skylib//rules:run_binary.bzl", "run_binary") def dll_library( name, srcs = [], deps = [], hdrs = [], visibility = None, **kwargs): static_library_name = name + "_static" raw_shared_lib_name = name + "_raw_shared" dll_lib_name = name + "_shared" # 先生成原始的.so格式动态库 cc_library( name = static_library_name, srcs = srcs, hdrs = hdrs, deps = deps, **kwargs ) cc_shared_library( name = raw_shared_lib_name, deps = [":" + static_library_name] ) # 把.so重命名为.dll run_binary( name = "rename_" + dll_lib_name, tool = "@bazel_tools//tools/bash/runfiles", args = [ "mv", "$(location :" + raw_shared_lib_name + ")", "$(location :" + raw_shared_lib_name + ").dll", ], srcs = [":" + raw_shared_lib_name], outs = [dll_lib_name + ".dll"], visibility = visibility, ) # 包装成cc_library,让Bazel链接时传递不带后缀的库名 cc_library( name = dll_lib_name, srcs = [dll_lib_name + ".dll"], hdrs = hdrs, deps = deps, linkstatic = False, **kwargs )
方案2:调整工具链的链接参数逻辑
直接修改自定义MinGW工具链的配置,让Bazel在生成-l链接参数时自动剥离.dll后缀:
在你的工具链定义文件(比如mingw_toolchain.bzl)中,调整cc_toolchain_config的linker_flag_sets部分,添加参数处理规则:
load("@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", "cc_toolchain_config", "artifact_name_pattern", "linker_flag_set", "linker_flag") def _mingw_cc_toolchain_config_impl(ctx): # ... 保留原有工具链配置 ... # 设置动态库的命名规则为libxxx.dll artifact_name_patterns = [ artifact_name_pattern( category_name = "dynamic_library", prefix = "lib", extension = ".dll", ), # ... 其他artifact配置 ... ] # 添加链接器参数处理逻辑,自动剥离-l参数后的.dll后缀 linker_flag_sets = [ linker_flag_set( actions = ["link"], flags = [ # 针对所有-l参数,移除后缀部分 "-l%s" % lib.split(".")[0] for lib in ctx.attr.libraries_to_link ], ), # ... 保留原有linker_flag_set配置 ... ] return cc_toolchain_config( # ... 保留原有配置 ... artifact_name_patterns = artifact_name_patterns, linker_flag_sets = linker_flag_sets, # ... 保留原有配置 ... ) mingw_cc_toolchain_config = rule( implementation = _mingw_cc_toolchain_config_impl, attrs = { # ... 保留原有属性 ... }, provides = [CcToolchainConfigInfo], )
验证方法
修改完成后执行构建命令:
bazel build //:sum_numbers_mingw
检查ld的调用参数,确认传递的是-lmath_d_shared而非-lmath_d_shared.dll,同时构建目录中生成的动态库为libmath_d_shared.dll,可执行文件能正常链接并运行。
内容的提问来源于stack exchange,提问作者Viktor Kustov
相关产品推荐
相关产品推荐

