Windows配置GSL簡明教程

不用編譯,只需安裝。本文的方法是直接通過安裝MSYS2來安裝GSL,不需要自己再編譯。

一、安裝MSYS2與GSL

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

  2. 安裝
    打開官網,下載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 安裝一堆軟件
  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);
}

編譯運行,應該就可以了。其他類似的問題,也可以通過上面的方法來解決。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章