Windows配置GSL简明教程

不用编译,只需安装。本文的方法是直接通过安装MSYS2来安装GSL,不需要自己再编译。

一、安装MSYS2与GSL

1. 了解MSYS2

官网:http://www.msys2.org/
百科:https://baike.baidu.com/item/MSYS2/17190550?fr=aladdin

2. 安装MSYS2

打开官网,下载MSYS2的64位安装包(圈出来了):
在这里插入图片描述
然后安装。注意:安装路径不能有中文!我的安装路径为“D:\msys64”,后文教程中以这个路径为例。
在这里插入图片描述
安装完之后,打开安装目录,发现目录结构如下:
在这里插入图片描述
发现了“dev”、“home”、“usr”等文件夹,这些文件夹一般是Linux系统才有的,可以理解为MSYS2“模拟”了一个Linux系统。“mingw64”则是一些软件包的安装目录,比如GSL,就会被安装到其中。

3. 配置MSYS2

这一步的目的修改MSYS2的源,也就是下载镜像,使得下载包的速度更快。参考链接(下面的图):https://mirror.tuna.tsinghua.edu.cn/help/msys2/
在这里插入图片描述
“/etc/pacman.d/mirrorlist.mingw32”等文件在你的MSYS2安装目录之下,比如我的就在“D:\msys64”。

4. 安装一些常用软件包

参考链接:https://www.jianshu.com/p/21eb5274d2da
在这里插入图片描述
在开始菜单内找到“MSYS2 MinGW 64-bit”,并点击运行;然后:
* 输入pacman -Syuu升级系统.最后卡住, 关闭掉重新打开
* 再次输入pacman -Syuu 升级其他软件.
* pacman -S gcc openssh vim dos2unix perl ruby winpty cmake tar make git 安装一堆软件

MSYS2安装包的命令简介:https://blog.csdn.net/qiuzhiqian1990/article/details/56671839

5. 安装GSL

在上面的窗口中,输入命令pacman -S mingw-w64-x86_64-gsl,安装GSL的预编译包,gsl就会被安装到目录“D:/msys64/mingw64”之下。打开“D:/msys64/mingw64”:
在这里插入图片描述
可以看到“bin”等文件夹,其中“bin”包含了运行时需要用到的dll文件,“include”里面时头文件,”lib“里面当然是库文件。

二、在VS2015中使用GSL

使用VS新建一个项目”gsl_test“,然后在”gsl_test“右键单击,弹出下面的菜单:
在这里插入图片描述
然后选择”属性“,弹出属性配置页。在此处打开的属性配置页只属于当前项目,在“属性管理器”配置的属性是全局属性。
在这里插入图片描述
“平台”一定得选“x64”,因为我们在之前安装的是64位的gsl库。“Release”和“Debug”的配置是相互独立的,都需要配置。首先配置包含目录和库文件目录(按照你自己的安装路径来修改路径):
在这里插入图片描述
然后配置库:
在这里插入图片描述
打开“D:/msys64/mingw64/lib”,可以发现:
在这里插入图片描述
有四个文件,这里只需要把“libgsl.dll.a”和“libgslcblas.dll.a”添加到项目的依赖项就行,其余两个是完整的静态库,用不到。
最后一步,把“D:/msys64/mingw64/bin”,加入到环境变量“Path”;然后重启VS。新建一个代码文件,输入下面的代码:

#include <stdlib.h>
#include <stdio.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_multiroots.h>

int main() {
	const size_t n = 2;
	gsl_vector *x = gsl_vector_alloc(n);
	double x_init[2] = { -10.0, -5.0 };
	gsl_vector_set(x, 0, x_init[0]);
	gsl_vector_set(x, 1, x_init[1]);
	gsl_vector_free(x);
	printf("测试成功,按回车退出!\n");
	getchar();
}

编译运行,如果没报错,说明配置成功了。

三、解决在使用GSL求根时遇到的bug

“错误 LNK2001 无法解析的外部符号 gsl_multiroot_fsolver_hybrids”,类似的错误还有“错误 LNK2001 无法解析的外部符号 gsl_multiroot_fsolver_dnewton”、“错误 LNK2001 无法解析的外部符号 gsl_multiroot_fsolver_broyden”、“错误 LNK2001 无法解析的外部符号 gsl_multiroot_fsolver_hybrid”。这些应该都是WIndows版本编译的时候把相关的源文件弄丢了,没有链接到库里面去。
gsl_multiroot_fsolver_hybrids等都是求根的算法(猜测)。解决办法就是在gsl的源码中找到这些算法的源文件,加入到我们的项目中去。接下来以解决“错误 LNK2001 无法解析的外部符号 gsl_multiroot_fsolver_hybrids”为例,说明解决的过程。

  1. 打开gsl的Github项目页:https://github.com/ampl/gsl
    上面的项目好像不是官方的实现,不过没关系,基本和gsl官网的项目会保持同步。
  2. 在Github搜索框中输入:gsl_multiroot_fsolver_hybrids

在这里插入图片描述
然后选择“gsl_multir… In this repository”,也就是在本仓库中搜索,搜索结果页部分如下:

在这里插入图片描述
其中,“multiroots/hybrid.c”就是我们要找的算法源文件。点一下“multiroots/hybrid.c”,进入“multiroots/hybrid.c”的源码页面;然后再VS中新建“hybrid.c”,把之前的代码复制到“hybrid.c”中,并注释掉#include <config.h>:
在这里插入图片描述
发现“hybrid.c”依赖于"dogleg.c",于是在VS中新建"dogleg.c",在“hybrid.c”的同级目录中找到"dogleg.c",把"dogleg.c"的源码页复制到VS的"dogleg.c"中。然后又发现"dogleg.c"依赖于“enorm.c”,于是以同样的步骤,把“enorm.c”也添加到项目里面去;在“enorm.c”中,发现没有gsl相关的头文件,所以报了一些错,于是,把gsl相关的头文件也加进去,从:

static double enorm(const gsl_vector * f);

static double enorm(const gsl_vector * f) {
	double e2 = 0;
	size_t i, n = f->size;
	for (i = 0; i < n; i++) {
		double fi = gsl_vector_get(f, i);
		e2 += fi * fi;
	}
	return sqrt(e2);
}

变为:

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <float.h>

#include <gsl/gsl_math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_multiroots.h>
#include <gsl/gsl_linalg.h>

static double enorm(const gsl_vector * f);

static double enorm(const gsl_vector * f) {
	double e2 = 0;
	size_t i, n = f->size;
	for (i = 0; i < n; i++) {
		double fi = gsl_vector_get(f, i);
		e2 += fi * fi;
	}
	return sqrt(e2);
}

编译运行,应该就可以了。其他类似的问题,也可以通过上面的方法来解决。

发布了88 篇原创文章 · 获赞 132 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/DumpDoctorWang/article/details/94624029
今日推荐