QT5使用mingw64和mingw32编译数学库GSL
1、工具准备
QT5.12.9版本,之前自己编译的mingw64的gsl库,正常使用,在后续版本升级维护过程中,有需要使用32位,本想着直接编译一下直接使用,但是结果出人意料,出现了一些意料之外的问题。下面记录一下,正确的编译方法,方便后面的学习与积累。
我下载的QT5.12.9在安装时已经安装了mingw64和mingw32的编辑器,没有安装的可以自己安装一下,mingw64和mingw32对应的版本都是mingw7.3.0 。
我是用的GSL版本为GSL2.7,大家可以到GSL官网去下载源代码。下载后解压到工作路径下,不要有中文的路径,以待后续的编译。
在编译之前需要下载msys,msys是minGW开源项目开发的一款在windows下模拟Unix命令窗口的工具,我们可以在命令行中使用mingw来快速编译程序。msys的下载网址为:MinGW-builds - Browse /external-binary-packages at SourceForge.net 。我使用的为2013-05-15版本的。
2、编译环境配置
2.1 mingw环境配置
将mingw的bin目录添加进系统的环境变量,安装QT时自带的mingw安装路径在QT安装路径里,我的为:C:\Qt\Qt5.12.9\5.12.9\mingw73_64\bin和C:\Qt\Qt5.12.9\5.12.9\mingw73_32\bin。同时还需要将C:\Qt\Qt5.12.9\Tools\mingw730_64\bin和C:\Qt\Qt5.12.9\Tools\mingw730_32\bin,一起放入环境变量。关于环境变量的设置,网上一大堆。
2.2 msys的配置
将下载的msys解压到C:\Qt\Qt5.12.9\Tools\mingw730_32和C:\Qt\Qt5.12.9\Tools\mingw730_64下,每个编译器一份,这样以后使用不需要来回设置了。并在文件夹下新建mingw空文件夹,并修改msys下的/etc/fstab文件,内容分别如下: 注意根据不同的位数来编写对应的文件。
C:/Qt/Qt5.12.9/Tools/mingw730_64 /mingw
C:/Qt/Qt5.12.9/Tools/mingw730_32 /mingw
3、编译GSL数学库
以mingw64位为例,打开对应目录下的msys.bat,输入g++ -v指令查看一下是否为对应位数的编译器。输出如下说明配置正确。
进入下载的GSL源码目录
输入 ./configure 对源码进行配置
配置结束后对源码经行编译 make -j16
编译结束,没有错误,则直接进行安装 make install 。
等待安装结束后,会在msys/local文件夹下生成对应的文件。分别如下:
出现上述文件说明编译成功,并生成的对应的库文件。
使用mingw32的一样的编译方式,只需要确认编译的位数是否对应。
所有的编译完成后,在工作目录下新建2个文件夹,分别为gsl32和gsl64用来存放编译生成的文件,方便后续在QT开发过程中的使用。
在对应的文件中,将msys/local文件夹下生成对应的文件考入对应的文件夹,并且编写了一份gsl**.pri,用来在QT开发中的引用。目录如下:
在gsl64文件夹中一样,只不过为gsl64.pri。这两个文件的内容相同,只是名称不同,内容如下图所示。
DEFINES += GSL_DLL
HEADERS +=
#指定头文件路径
INCLUDEPATH += $$PWD\include
#指明依赖关系以及依赖库路径
LIBS += -L$$PWD\lib -llibgsl
LIBS += -L$$PWD\lib -llibgslcblas
SOURCES +=
得到上述的2个文件夹后,就可以在QT中引用来进行开发了,新建一个QT项目,在qt的pro文件中添加如下代码:
contains(QT_ARCH, x86_64){
message("64-bit")
include($$PWD/gsl64/gsl64.pri)
}else{
message("32-bit")
include($$PWD/gsl32/gsl32.pri)
}
然后编译该项目,右键项目,选择重新构建,正常来说应该编译成功,但是没想到编译出错了,错误如下:
刚开始我以为是编译器的原因,或者编译的环境有问题,32位和64位的混肴了,导致链接不到库,最后重新配置环境,选择编辑器等都没有解决。我也在网上参考了其他网友的编译方法,大同小异。他们的可以正常运行,为什么我编译的不能运行,感觉很奇怪。最后确认编译没有出错,那就找源码的问题,既然说没有找到定义,就去源码中找_imp__gsl_rng_default和_imp__gsl_multifit_nlinear_trust相关的定义,在头文件中找到了关于这2个变量的定义,分别在gsl_multifit_nliner和gsl_rng.h中。以gsl_rng.h中的gsl_rng_default为例:打开文件,找到定义,既然提示找不到,就给他extern一下,如下所示:
然后重新构建,发现错误减少了,有戏,继续修改gsl_multifit_nlinear.h
修改后的gsl_multifit_nlinear.h如下
右键项目,重新构建,编译正确,没有红色报错信息,成功搞定。同理32位和64位的都需要修改。
结束语:
很奇怪我之前编译的为什么能够使用,再次编译的就不能使用了?带着疑问和已经得到的解决方法,打开了之前的编译库文件,查找gsl_multifit_nliner和gsl_rng.h中相关变量的定义,结果发现,what the f**k ,是使用的extern的,原来之前已经有遇到过,也解决了,害的自己又花了2天的时间来找问题。在此做一下记录,也提示自己一定要有做笔记的习惯,这样后面遇到同类型的问题就可以参考来解决,会省下很多时间。