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

Linux下使用MinGW交叉编译Windows程序无法链接指定库问题

问题根因

你遇到的链接失败问题,基本是几个交叉编译的常见操作错误导致的:

  • 手动从MSYS2下载预编译包、直接复制到系统MinGW目录的操作兼容性很差:MSYS2的预编译包是适配它自身运行时环境的,和你通过系统源安装的x86_64-w64-mingw32工具链不一定ABI匹配,手动复制还很容易漏文件、混放不同版本的库
  • 之前写-I头文件搜索路径时路径写错了:代码里写的是#include <curl/curl.h>,编译器会在你指定的-I目录下找curl子目录里的curl.h,你直接把-I指到/usr/x86_64-w64-mingw32/include/curl/,编译器实际会去找.../curl/curl/curl.h,自然会报头文件内部的编译错误
  • 你之前直接把.h头文件路径当源文件传给g++的操作是完全错误的,头文件不需要直接传入编译命令,这也是之前出奇怪未定义报错的诱因之一
  • 手动复制库文件时很容易放错链接器的搜索路径,或者把Linux原生库、Windows库混放,导致链接器扫到错误的文件找不到对应符号
正确解决步骤

方法1:用系统源直接装对应MinGW版本的依赖(最省事,优先选)

绝大多数发行版的官方源已经打包好了适配系统MinGW工具链的Windows版curl和fmt,根本不用自己下包手动复制:

  • Debian/Ubuntu系直接执行:
sudo apt install mingw-w64-x86-64-dev libcurl4-mingw-w64-dev libfmt-mingw-w64-dev
  • Arch系直接执行:
sudo pacman -S mingw-w64-gcc mingw-w64-curl mingw-w64-fmt

装完之后直接用下面的命令编译就行,不用自己加-I、-L参数,工具链会自动找到对应路径的头文件和库:

x86_64-w64-mingw32-g++ *.cpp -std=c++2a -O2 -DNDEBUG -Werror -lcurl -lfmt -o main.exe

编译出来的exe如果是动态链接版本,把对应MinGW路径下的libcurl-4.dll、fmt.dll、libwinpthread-1.dll等依赖dll和exe放同一目录就能在Windows上运行。

方法2:如果必须用MSYS2的预编译包,注意正确配置路径

如果你确实要用自己下载的MSYS2包,不要把文件直接复制到系统MinGW的目录里,单独放一个独立文件夹,比如/opt/mingw-deps/,把压缩包里的include、lib、bin目录都解压到这个文件夹下,然后编译的时候显式指定正确的搜索路径,注意-I参数要指到include根目录,不要指到子目录:

x86_64-w64-mingw32-g++ *.cpp -std=c++2a -O2 -DNDEBUG -Werror \
  -I/opt/mingw-deps/include \
  -L/opt/mingw-deps/lib \
  -lcurl -lfmt \
  -o main.exe

如果还是报未定义引用,先检查你下载的MSYS2包是UCRT版本还是MSVCRT版本,要和你自己用的MinGW工具链的运行时版本匹配:如果你系统装的MinGW是默认MSVCRT的,就不能用UCRT分支的包,ABI不兼容会直接找不到符号。

方法3:交叉编译依赖库(最稳定,不会有ABI问题)

如果源里没有对应包,也不想用MSYS2的预编译包,可以直接用MinGW工具链自己编译curl和fmt的静态版本,编译的时候指定安装前缀到独立目录,之后编译自己的代码的时候链接静态库,连附带dll的步骤都省了,兼容性最好。

常见踩坑提醒
  • 永远不要把头文件路径直接作为编译参数传给g++,g++只会把传入的.cpp/.c/.s等源文件做编译处理,直接传.h会出各种无意义的错误
  • 写-I参数的时候永远指到存放头文件的根目录,比如你头文件路径是xxx/include/curl/curl.h,那-I就写-Ixxx/include,不要写到curl子目录那一层
  • 交叉编译的时候不能混用Linux原生的库和Windows版的库,你系统/usr/lib下的libcurl.so、libfmt.so是给Linux原生g++用的,MinGW链接器根本识别不了
  • 如果链接的时候还是找不到库,可以加-v参数看链接器的搜索路径列表,确认你放库的目录确实在搜索路径里,同时库文件名是链接器能识别的格式:比如Windows动态库对应的导入库应该是libcurl.dll.a,静态库是libcurl.a,不要把Linux的.so文件放进去。

内容的提问来源于stack exchange,提问作者surrealcereal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:18:25