Windows 下使用 gcc/g++ 编译器
MSVC:从入门到放弃
从一开始修改 JincResize 代码到现在,代码编译后 dll 运行缓慢的问题一直困扰着我。虽然原作者说运行速度慢,但我自己编译的也太慢了(1.5 fps vs 9 fps)。改了一些代码(主要是涉及 C 语言和 C++ 的区别),但对速度无肉眼可见的影响。这样下去,代码重构也没有动力。
思考了一下,做了一下对照实验。使用原作者代码,直接在 VS2019 中编译(除了为在 VS2019 中编译通过,修改了一处代码外,其余代码均未改动),也很慢,也是约9s/帧。这样让我明确了一点,就是编译方面的问题,导致运行速度缓慢的。
我又仿照 HomeOfVapourSynthEvolution 的预处理设置,并在编译中尽量使用加快代码速度的优化参数,但最终的编译结果仍没有什么改善。
所以我有理由判断,是编译器的锅。(也许是现在的代码,虽然做了从 C 到 C++ 的迁移,但仍有 C 的风格,导致和 VS 的纯 C++ 编译器八字不合?)
不管怎么说,改用 gcc/g++。
使用 gcc 编译 C 语言代码
前两天用了一次 gcc 编译 C 语言代码,但不知道怎么自行设置头文件和库文件路径,所以就放弃了。
今天明白了,库文件不一定需要,而反正我所需要的头文件就两个,直接复制过来就好了。
直接编译原作者代码。
1 |
|
能编译通过,但 VapourSynth 中无法调用。想了一下,这里的 gcc 是 32 位,和 64 位的 VapourSynth 不搭,于是换用64位的gcc,并打开-O2
优化。
1 |
|
VapourSynth 成功运行,而且速度也和原作者的差不多了!Dll 体积也差不多,我感觉原作者就是这么编译的。
使用 g++ 编译 C++ 代码
动态编译
虽说 gcc 也不是不能编译 C++,但毕竟…还是用专业的 g++ 吧。
1 |
|
编译出来的 dll,VapourSynth 无法调用。我怀疑是没有配置库文件的锅,因为在 CSDN 上看到一篇博文,说需要库文件却没有配置时,这样也能编译通过、不报错。也就是默认编译模式下,看不见缺失库文件的问题
于是我照这篇博文的方法,加上了-Wl,--no-undefined
参数,这样就能暴露缺失库文件问题。
1 |
|
但我试了一次,仍没有报错,正常地编译通过。
在这篇博文的帮助下,我明白了 g++ 是动态编译,编译好的 dll 依赖于其他 dll。想起了之前安装MXNet的踩坑经历,(我也能自引了,积累是有用的)。使用 Visual Studio 的 dumpbin 工具查到了依赖的两个dll。
但与博文中把 dll 放到程序目录就 OK 不同的是,这两个 dll 我无论是放到 VapourSynth 的文件(VapourSynth 下各种文件夹都试过了),还是System32
中,都依然无法调用我编译的 dll。只得另寻他法。
(况且就算这种方法能行,我也不能这么干,我不可能在发布时再“顺带”发布两个依赖,这也太蛋疼了)
静态编译
这篇博文告诉我,可以通过静态编译的方式避免上述依赖的问题。
只加上-static-libgcc
和-static-libstdc++
这两个参数,还是不行。于是干脆使用-static
,全局静态编译。
1 |
|
终于成功了。(dll 大小:63kb -> 415kb -> 451kb)
Dll 运行速度也是和原作者的相似(所以我增加模板函数和其他修改并没有拖垮速度嘛)。
这样后续的代码重构也有动力了!
后记
这半天加晚上的折腾过程,从一开始的毫无头绪,到折腾 CodeBlocks 和 MinGW,从第一次使用 gcc 编译成功 C 语言代码、获得能用的 dll,到动态编译 C++ 虽缺少依赖,但能平静地寻找解决办法。真的是很棒的经历。
加油吧,相信自己。