返回

在 Windows 11 中使用自定义 MinGW 工具链构建和链接 .dll 的常见问题解答

windows

在 Windows 11 中使用自定义 MinGW 工具链构建和链接 .dll

前言

本文档将指导您如何在 Windows 11 上使用自定义 MinGW 工具链构建和链接动态链接库(.dll)。我们还将解决您在构建可执行文件时可能遇到的错误,例如找不到 -lmath_d_shared 库。

问题

在使用 Bazel 构建 .dll 并将其链接到可执行文件时,可能会出现以下错误:

C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmath_d_shared: No such file or directory

解决方法

方法 1:修改工具链

  1. 修改工具链的 artifact_name_patterns 字段,添加以下内容:
artifact_name_pattern(
    category_name = "dynamic_library",
    prefix = "lib",
    extension = ".dll",
)
  1. 这样做会强制 Bazel 为所有动态库生成 .dll 扩展名。

方法 2:重命名 .so 为 .dll

  1. 创建一个 Bazel 规则(dll_library.bzl)来重命名库文件:
def dll_library(
        name,
        srcs = [],
        deps = [],
        hdrs = [],
        visibility = None,
        **kwargs):               
    static_library_name = name + "_static"
    dll_lib_name = name + "_shared"
    
    cc_library(
        name = static_library_name,
        srcs = srcs,
        hdrs = hdrs,
        deps = deps,        
        **kwargs
    )
    
    cc_shared_library(
        name = dll_lib_name,                        
        deps = [":" + static_library_name] 
    )
    
    native.genrule(
        name = name + "_rename_so_to_dll",
        srcs = [dll_lib_name + ".so"],
        outs = [dll_lib_name + ".dll"],
        cmd = "mv $(SRCS) $(OUTS)"
    )
  1. 在 BUILD 文件中使用此规则:
load("//main:dll_library.bzl", "dll_library")

...

dll_library(
    name = "math_d.dll",
    srcs = ["math_dll_interface.cpp"],
    hdrs = DLL_HDRS,
    deps = [":math"],
    defines = ["MATH_DLL"]
)

...

cc_binary(
    name = "sum_numbers_mingw",
    srcs = ["main.cpp"] + DLL_HDRS, 
    dynamic_deps = [":math_d.dll"]                   
)

结论

通过使用这些方法之一,您可以解决在 Windows 11 中使用 MinGW 工具链构建和链接 .dll 时遇到的错误。方法 1 更简单,因为它只需要对工具链进行一次性修改。方法 2 需要创建自定义 Bazel 规则,但它提供了更灵活的解决方案。

常见问题解答

  1. 为什么我需要修改工具链或重命名库文件?

    • Bazel 默认生成 .so 库,而 Windows 使用 .dll。
  2. 这是否会影响其他构建目标?

    • 否,这些方法只影响动态库的构建和链接。
  3. 我可以使用其他工具来重命名库文件吗?

    • 当然,您可以使用您喜欢的任何工具,例如 mv 命令或第三方重命名实用程序。
  4. 这些方法是否可以在其他操作系统上使用?

    • 方法 1 应该可以在其他操作系统上使用,但方法 2 可能需要修改以适应不同的平台。
  5. 是否有其他方法来解决此错误?

    • 如果可能,您可以尝试切换到另一种工具链或编译器,例如 Visual Studio。