1. 程式人生 > >glib:windows下基於MSYS2環境編譯glib2的過程

glib:windows下基於MSYS2環境編譯glib2的過程

如果用MSVC編譯開源庫實在是麻煩,主要的麻煩在於第三方的開源庫本身還需要一些依賴庫,這些依賴庫在windows多數並不提供編譯好的二進位制版本,所以要先編譯安裝各種依賴庫,比如glib
我也曾想用官方提供的二進位制庫(http://ftp.gnome.org/pub/gnome/binaries/win64/glib/),但官方的伺服器上從2010年以後就不再提供二進位制版本,只提供原始碼。所以如果要用glib的新版本,只能自己編譯,glib github上也有用MSVC編譯glib的說明(參見《Compiling the GTK+ (and Clutter) stack using Visual C++ 2008 and later》

),但前提就是要提供依賴庫(pcre,intltool),想想都麻煩。在網上反覆找了很多次,找到這篇官方的說明《Download for Windows》,在這個說明中我只得到一個資訊:windows下編譯gtk+ (包括glib)最容易的方式就是在MSYS2。MSYS2為windows提供了一個類似unix的開發環境,在這個環境下,安裝各種依賴庫那都不是事兒。
對MSYS2我還是比較熟悉的,既然官方的建議也是在MSYS,那就在MSYS2下搞吧,MSYS2安裝很簡單,網上有教程,請自行百度。

安裝依賴庫

有了MSYS2安裝依賴庫就非常簡單了,以下是通過pacman安裝所有編譯glib所需要的工具和依賴庫。

# 安裝依賴庫和必須的工具
pacman --needed --noconfirm -S automake autoconf make libtool unzip glib2-devel intltool pcre-devel   \
            mingw-w64-x86_64-toolchain mingw-w64-x86_64-pcre

# 可選工具用於生成文件
#pacman --needed --noconfirm -S gtk-doc

下載glib

# 從github上下載2.54.3版本的原始碼
wget https://github.com/GNOME/glib/archive/2.54
.3.zip -O glib-2.54.3.zip # 原始碼解壓縮 unzip glib-2.54.3.zip || exit -1

編譯

cd glib-2.54.3
# 第一次要執行autogen.sh才會生成./configure,後續可以直接執行./configure來修改編譯配置
./autogen.sh --prefix=/your/install/path
# 編譯並安裝到prefix指定的位置
make install -j8

生成MSVC import library (.lib)

問題來了,在MSYS2下編譯用的是MinGW編譯器,生成的匯入庫(import library)都字尾是.dll.a,MSVC怎麼使用呢?其實MinGW生成的import library,MSVC是可以直接用的,直接新增到msvc工程就可以。
但如果你是用cmake來組織專案,在MSVC編譯環境下cmake的find_library是找不到字尾為.dll.a的import library.
怎麼辦呢?
其實glib的Makefile是支援在編譯時生成MSVC的 .lib .def檔案的。隨便開啟一個glib的Makefile(比如glib/Makefile),就可以找到生成.lib的程式碼:

glib-2.0.lib: libglib-2.0.la glib.def
    $(AM_V_GEN) lib.exe -machine:X64 -name:libglib-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:$(builddir)/glib.def -out:$@

可以看到Makefile生成 .lib 是呼叫MSVC的lib.exe(在MSVC bin資料夾下)程式來完成的。而預設情況下,MSYS2環境中搜索路徑($PATH)中沒有MSVC編譯器的安裝位置(bin).所以這一條命令不能執行,不能生成lib。
解決的辦法就是執行編譯之前將MSVC 編譯器的安裝位置(bin)加入$PATH:

# 以Visual Studio 2015為例
PATH="/C/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin":$PATH

make install安裝後的目錄結構.dll.a.lib都有了。

glib-2.54.3-x86_64
  ├── bin
  │   ├── gdbus.exe
  │   ├── gdbus-codegen
  │   ├── gio.exe
  │   ├── gio-querymodules.exe
  │   ├── glib-compile-resources.exe
  │   ├── glib-compile-schemas.exe
  │   ├── glib-genmarshal
  │   ├── glib-gettextize
  │   ├── glib-mkenums
  │   ├── gobject-query.exe
  │   ├── gresource.exe
  │   ├── gsettings.exe
  │   ├── gspawn-win64-helper.exe
  │   ├── gspawn-win64-helper-console.exe
  │   ├── libgio-2.0-0.dll
  │   ├── libglib-2.0-0.dll
  │   ├── libgmodule-2.0-0.dll
  │   ├── libgobject-2.0-0.dll
  │   └── libgthread-2.0-0.dll
  ├── include
  │   ├── gio-win32-2.0
  │   └── glib-2.0
  ├── lib
  │   ├── charset.alias
  │   ├── gio
  │   ├── gio-2.0.lib
  │   ├── glib-2.0
  │   ├── glib-2.0.lib
  │   ├── gmodule-2.0.lib
  │   ├── gobject-2.0.lib
  │   ├── gthread-2.0.def
  │   ├── gthread-2.0.lib
  │   ├── libgio-2.0.dll.a
  │   ├── libgio-2.0.la
  │   ├── libglib-2.0.dll.a
  │   ├── libglib-2.0.la
  │   ├── libgmodule-2.0.dll.a
  │   ├── libgmodule-2.0.la
  │   ├── libgobject-2.0.dll.a
  │   ├── libgobject-2.0.la
  │   ├── libgthread-2.0.dll.a
  │   ├── libgthread-2.0.la
  │   └── pkgconfig
  └── share
      ├── aclocal
      ├── bash-completion
      ├── gdb
      ├── gettext
      ├── glib-2.0
      └── locale

參考資料