不用編譯,只需安裝。本文的方法是直接通過安裝MSYS2來安裝GSL,不需要自己再編譯。
一、安裝MSYS2與GSL
-
瞭解MSYS2
官網:http://www.msys2.org/
百科:https://baike.baidu.com/item/MSYS2/17190550?fr=aladdin -
安裝
打開官網,下載MSYS2的64位安裝包(圈出來了):
然後安裝。注意:安裝路徑不能有中文!我的安裝路徑爲“D:\msys64”,後文教程中以這個路徑爲例。
安裝完之後,打開安裝目錄,發現目錄結構如下:
發現了“dev”、“home”、“usr”等文件夾,這些文件夾一般是Linux系統纔有的,可以理解爲MSYS2“模擬”了一個Linux系統。“mingw64”則是一些軟件包的安裝目錄,比如GSL,就會被安裝到其中。 -
配置MSYS2
這一步的目的修改MSYS2的源,也就是下載鏡像,使得下載包的速度更快。參考鏈接(下面的圖):https://mirror.tuna.tsinghua.edu.cn/help/msys2/
“/etc/pacman.d/mirrorlist.mingw32”等文件在你的MSYS2安裝目錄之下,比如我的就在“D:\msys64”。 -
安裝一些常用軟件包
參考鏈接: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
安裝一堆軟件
- 輸入
-
安裝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”爲例,說明解決的過程。
- 打開gsl的Github項目頁:https://github.com/ampl/gsl
上面的項目好像不是官方的實現,不過沒關係,基本和gsl官網的項目會保持同步。 - 在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);
}
編譯運行,應該就可以了。其他類似的問題,也可以通過上面的方法來解決。