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

Windows11下用自定义MinGW工具链通过Bazel构建链接.dll的问题

MinGW ucrt64 + Bazel 动态库构建链接问题解决

问题简述

在Windows 11 Pro上用自定义MinGW ucrt64 GCC工具链,通过Bazel构建DLL和依赖它的可执行文件时,碰到两个棘手问题:

  1. cc_shared_library默认输出.so后缀的库,但Windows下的ld根本不认.so,手动改成.dll后链接就正常了。
  2. 改工具链的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 17:50:40