【Windows】Windows 平台使用 MinGW 编译程序遇到报错 cannot execute binary file: Exec format error 的一种原因

3 篇文章 0 订阅
2 篇文章 0 订阅

最近使用 vscode + MinGW 在 Windows 平台编译了一个在 Linux 平台开发的 SDK,做了一些代码上的适配,依赖库的重新编译,未定义的参考的解决,之后,终于 link 成功,兴奋之际,直接运行 ./bin/example.exe ,却发现:

在这里插入图片描述
遇到了报错: cannot execute binary file: Exec format error。
由于是最近才开始做 Windows 开发,不确定这种使用 vscode + MinGW 的编译方案,是否能在 Windows 上可行,也不确定 Windows 平台使用 MinGW 编译出来的 .a 静态库是否可行。因此,遇到这个问题之后,做了很多搜索,但都没有得到比较确切的答案。

cmake + MinGW 可行

首先,为了确定 cmake + MinGW 的方案在 Windows 上可行,重新创建了一个新的工程,写了个简单的 “Hello world” Demo,并用 CMakeLists 和 MinGW 编译运行,发现是没有问题的。
在这里插入图片描述
所以,这确定了使用 cmake + MinGW 在 Windows 上开发是完全没问题的。

.a 静态库可行

那么,是否是因为 SDK Demo 这个用了 .a 静态库链接,所以导致了可执行文件格式不正确呢?所以,又在上面的 小 Demo 上链接了一个 SDK Demo 使用的静态库 libavutil.a,并尝试调用了一下它的 api。编译成功后,也能正常运行,上图 “Operation not permitted” 就是调用 av_strerror(-1. str, 256) 得到的结果,错误码 -1 的含义。
所以,这也确定了 Windows 上使用 .a 静态库也是没有问题的。

文件格式一致

使用 file 命令查看两个 exe 的文件格式,发现,这两个可执行文件,虽然一个可执行,一个格式错误,但两个文件的格式文件是一模一样的。
在这里插入图片描述
在这里插入图片描述
而 ldd 也无法查看 example.exe 的依赖,同样返回 exec format error。

真实原因

导致 example.exe 无法运行的真实原因在于,example 依赖了较多的第三方静态依赖库,其中一个 freetype 在编译过程中存在问题。
排查的过程如下,在 linktest 项目上不断新增 example 项目中依赖的那些依赖库,并且调用依赖库中的一个简单的方法来确定依赖库的确被使用到了,每新增一个依赖库,就编译一次、运行一次。
直到新增 freetype 静态库时,发现 freetype 还进一步依赖 brotlidec 库,而 brotlidec 库又依赖 brotlicommon 库,直到三个都加上之后,都能链接成功了,但是执行时就发生了 exec format error 了。
由于 freetype 依赖 brotlidec,所以,先将 freetype 去掉,只添加 brotlidec brotlicommon 库并调用 brotlidec 里面的一个简单接口 BrotliDecoderVersion(),链接成功,执行成功。因此,问题就定位成功了,就是 freetype 库存在问题。
检查了一下 freetype 的编译脚本,想来可能是之前是使用 MSYS 系统编译的,所以重新使用 CMakeLists + MinGW 的方法编译了一遍,然后把新编译出来的 .a 静态库替换原来的 .dll.a 静态库和 .dll 就没有问题了。
在这里插入图片描述
这也同样确定了,使用 cmake + MinGW,使用 vscode 集成 git bash 终端命令就可以完成完整的较大型 C++ 程序 Windows 开发和调试。可以像 Linux 开发那样开发 Windows 软件。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深海Enoch

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值