獲取Glib
Glib官網:https://developer.gnome.org/glib/
Glib源碼包下載地址:http://ftp.gnome.org/pub/gnome/sources/glib/
本人下載的是 glib-2.30.3版本的源碼包,源碼包文件名為:glib-2.30.3.tar.xz。獲取源碼包命令如下:
wget http://saimei.ftp.acc.umu.se/pub/gnome/sources/glib/2.30/glib-2.30.3.tar.xz
《注意》安裝需要有root權限,最好是在root用戶下進行,如果不是root用戶,執行編譯安裝操作時需要在命令前加上 sudo 。本人的所有操作是在root用戶下進行的。
安裝步驟
一、解壓縮源碼包。
1、首先需要安裝 xz 包(如果沒有的話),安裝命令:yum install xz
2、解壓縮glib-2.30.3.tar.xz壓縮包。查看xz命令的用法:xz --help 或者 xz -H,顯示的內容比前者跟詳細。
xz -d -k glib-2.30.3.tar.xz
-d:表示解壓的參數。
-k:保留輸入文件,亦即glib-2.30.3.tar.xz文件,如果不加該參數,解壓后,glib-2.30.3.tar.xz文件就被刪除了。
解壓成功后,會生成glib-2.30.3.tar文件,需要使用tar命令來解壓了,命令如下:
tar -xvf glib-2.30.3.tar
解壓成功后,會生成glib-2.30.3目錄。至此,解壓源碼包完成。
<說明> 后面,我發現了解壓xxx.tar.xz文件不需要這么復雜的過程,可以直接使用tar命令解壓,命令:tar xvfJ glib-2.30.3.tar.xz,解壓成功后,會在當前路徑下生成glib-2.30.3目錄。
二、進入glib-2.30.3目錄,執行 configure 配置腳本。
1、查看configure 腳本的使用幫助及其選項,可以執行命令:./configure --help 查看使用方法。
如果直接執行:./configure,那么默認安裝路徑是/usr/local,對應的頭文件、可執行文件和庫文件分別對應的目錄是:'/usr/local/include'、'/usr/local/bin','/usr/local/lib'。
2、我本人設置了自定義安裝路徑,執行命令如下:
./configure --prefix=/usr/local/glib
執行報錯了:
configure: error: Package requirements (libffi >= 3.0.0) were not met:
No package 'libffi' found
缺少libffi庫,所以首先需要安裝這個庫。
源碼安裝libffi
1、源碼包下載鏈接:https://sourceware.org/libffi/
2、本人下載的源碼包名為:libffi-3.3.tar.gz,解壓:tar xzvf libffi-3.3.tar.gz
3、編譯安裝,命令如下:
./configure
make
make install
安裝libffi依賴庫成功后,繼續執行configure腳本,仍然報上面同樣的錯誤,查找了一下原因,還需要配置libffi庫的環境變量,在/root目錄下編輯.bash_profile配置文件。
vim /root/.bash_profile //添加內容如下:
export LIBFFI_CFLAGS=/usr/local/include
export LIBFFI_LIBS=/usr/local/lib64/libffi.la
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
LIBFFI_CFLAGS環境變量:配置的是libffi三方庫的頭文件路徑,我查看了一下,其頭文件是在/usr/local/include目錄下。
LIBFFI_LIBS環境變量:配置的是libffi三方庫的動態庫路徑,上面也查找出來了,其庫文件是在/usr/local/lib64/目錄下。
PKG_CONFIG_PATH環境變量:配置的是xxx.pc文件的搜索路徑,用於pkg-config工具的環境變量。
保存修改,執行:source ~/.bash_profile,令修改生效。重新執行configure腳本,執行成功了。
<Warnning> 安裝glib三方庫,還需要安裝zlib庫的,由於我在安裝其他三方庫的時候已經安裝過了,所以沒有報zlib庫無法找到的錯誤,僅此說明一下。
三、第2步執行成功后,會生成Makefile文件,然后使用make命令進行源碼編譯。
make
編譯報錯了,錯誤信息如下:
make[4]: Entering directory `/home/joe/Downloads/glib-2.32.4/gobject' CCLD gobject-query ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_pointer' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_float' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_void' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint64' ./.libs/libgobject-2.0.so: undefined reference to `ffi_prep_cif' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint32' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_double' ./.libs/libgobject-2.0.so: undefined reference to `ffi_call' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint32' ./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint64' collect2: ld returned 1 exit status make[4]: *** [gobject-query] Error 1 make[4]: Leaving directory `/home/joe/Downloads/glib-2.32.4/gobject' make[3]: *** [all-recursive] Error 1 make[3]: Leaving directory `/home/joe/Downloads/glib-2.32.4/gobject' make[2]: *** [all] Error 2 make[2]: Leaving directory `/home/joe/Downloads/glib-2.32.4/gobject' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/joe/Downloads/glib-2.32.4' make: *** [all] Error 2
libffi庫安裝成功后,編譯報的這個錯誤,上網查找了一下原因,發現是由於glib庫的gobject、gio目錄下的Makefile.in文件某些宏定義遺漏了$(LIBFFI_LIB)造成鏈接的時侯出錯。這就麻煩了!經過手動修改gobject、gio目錄下的Makefile.in文件,添加了$(LIBFFI_LIBS),最終總算是編譯通過了。所以,建議還是安裝最新版的glib庫,老版本的源碼包(我安裝的是glib-2.30.3版本)竟然出現這樣的低級錯誤,實屬不該呀!我是借鑒了下面鏈接的博文修改了對應的Makefile.in文件內容,鏈接中使用的glib版本是glib-2.32.4,雖然版本不一樣,但是修改方法卻是一樣的,因此要在理解的基礎上進行內容的修改,不能照搬,謹記!!!
Compiling GLib from source version 2-32.4
<Warnning> 建議安裝較新的glib庫版本,最好是從2.40版本開始的,舊版本的glib存在我上面描述的問題,需要手動修改源碼包中gobject、gio下的Makefile.in文件,添加$(LIBFFI_LIB)。雖然修改后可以解決編譯不通過的問題,但總歸還是有Bug啊,並且是很嚴重的Bug!
四、編譯成功后,執行安裝命令。
make install
<Tips> 要卸載glib庫,命令為:make uninstall
五、安裝成功后,可以看到/usr/local目錄下多了一個glib目錄,查看一下這個目錄的樹形結構。
]# tree -L 2 glib/
glib/
├── bin
│ ├── gdbus
│ ├── gdbus-codegen
│ ├── gio-querymodules
│ ├── glib-compile-schemas
│ ├── glib-genmarshal
│ ├── glib-gettextize
│ ├── glib-mkenums
│ ├── gobject-query
│ ├── gsettings
│ ├── gtester
│ └── gtester-report
├── etc
│ └── bash_completion.d
├── include
│ ├── gio-unix-2.0
│ └── glib-2.0
├── lib
│ ├── gdbus-2.0
│ ├── gio
│ ├── glib-2.0
│ ├── libgio-2.0.la
│ ├── libgio-2.0.so -> libgio-2.0.so.0.3000.3
│ ├── libgio-2.0.so.0 -> libgio-2.0.so.0.3000.3
│ ├── libgio-2.0.so.0.3000.3
│ ├── libglib-2.0.la
│ ├── libglib-2.0.so -> libglib-2.0.so.0.3000.3
│ ├── libglib-2.0.so.0 -> libglib-2.0.so.0.3000.3
│ ├── libglib-2.0.so.0.3000.3
│ ├── libgmodule-2.0.la
│ ├── libgmodule-2.0.so -> libgmodule-2.0.so.0.3000.3
│ ├── libgmodule-2.0.so.0 -> libgmodule-2.0.so.0.3000.3
│ ├── libgmodule-2.0.so.0.3000.3
│ ├── libgobject-2.0.la
│ ├── libgobject-2.0.so -> libgobject-2.0.so.0.3000.3
│ ├── libgobject-2.0.so.0 -> libgobject-2.0.so.0.3000.3
│ ├── libgobject-2.0.so.0.3000.3
│ ├── libgthread-2.0.la
│ ├── libgthread-2.0.so -> libgthread-2.0.so.0.3000.3
│ ├── libgthread-2.0.so.0 -> libgthread-2.0.so.0.3000.3
│ ├── libgthread-2.0.so.0.3000.3
│ └── pkgconfig
└── share
├── aclocal
├── gdb
├── glib-2.0
├── gtk-doc
├── locale
└── man
glib目錄下有5個一級子目錄:bin etc include lib share。這里就不再詳細介紹這些子目錄的具體內容了。接下來就是配置glib庫的開發環境了。
配置glib庫的開發環境
一、配置PATH環境變量
PATH環境變量對應的可執行文件(一般設置的是Linux命令的路徑)。這里我設置glib庫的bin目錄下的路徑為對所有用戶生效,因此需要在/etc/profile文件中配置PATH環境變量的值。
]# vim /etc/profile //添加內容如下
export PATH=/usr/local/glib/bin:$PATH
保存修改,執行:source /etc/profile,使修改生效,下同。我們嘗試執行一個glib/bin/目錄下的gtester命令,打印出glib三方庫的版本信息:
]# gtester -v
gtester version 2.30.3
二、配置glib三方庫的C頭文件搜索路徑
C頭文件搜索路徑對應的環境變量是C_INCLUDE_PATH,這里我們只在當前用戶的主目錄下的.bash_profile文件中配置。
]$ vim ~/.bash_profile //添加內容如下
#Add C header file path
export C_INCLUDE_PATH=/usr/local/glib/include/glib-2.0:/usr/local/glib/lib/glib-2.0/include:$C_INCLUDE_PATH
為了優化一下,我們可以進行如下設置:
C_GLIB_PATH=/usr/local/glib/include/glib-2.0:/usr/local/glib/lib/glib-2.0/include
export C_INCLUDE_PATH=$C_GLIB_PATH:$C_INCLUDE_PATH
三、配置glib三方庫的鏈接庫文件搜索路徑
]$ vim ~/.bash_profile //添加內容如下
# Add third_lib path
export LD_LIBRARY_PATH=/usr/local/glib/lib:$LD_LIBRARY_PATH
export LIBRARY_PATH=/usr/local/glib/lib:$LIBRARY_PATH
至於,為什么要同時配置LIBRARY_PATH、LD_LIBRARY_PATH 這兩個環境變量,請參考下面鏈接中的博客說明。
【參考】
環境變量:LIBRARY_PATH 和 LD_LIBRARY_PATH的區別
四、嘗試編譯一個glib程序,源文件名為:glib_version.c,源碼如下:
/*
**程序描述:獲取glib庫的版本號。
*/
#include <glib.h>
int main()
{
const gchar *str;
str=glib_check_version(GLIB_MAJOR_VERSION,GLIB_MINOR_VERSION,GLIB_MICRO_VERSION);
if(str!=NULL)
g_print("%s\n",str);
g_print("Current Glib Version: %u.%u.%u\n", GLIB_MAJOR_VERSION,GLIB_MINOR_VERSION,GLIB_MICRO_VERSION);
return 0;
}
編譯命令:]$ gcc glib_version.c -o glib_version -lglib-2.0
In file included from /usr/local/glib/include/glib-2.0/glib/galloca.h:34:0,
from /usr/local/glib/include/glib-2.0/glib.h:32,
from glib_version.c:4:
/usr/local/glib/include/glib-2.0/glib/gtypes.h:34:24: fatal error: glibconfig.h: No such file or directory
#include <glibconfig.h>
可以看到,報了錯誤,找不到glibconfig.h頭文件,查找后發現這個頭文件所在的路徑為:/usr/local/glib/lib/glib-2.0/include,因此我們還需要在C_INCLUDE_PATH環境變量中添加這個頭文件的搜索路徑,修改后的內容請參見上面的C_INCLUDE_PATH環境變量的配置值。修改成功后,編譯成功通過。
運行結果:]$ ./glib_version
Current Glib Version: 2.30.3
使用 pkg-config 方式配置三方庫的搜索路徑
使用pkg-config方式配置三方庫的搜索路徑,主要是用於Makefile文件中編寫程序的編譯命令。對應的環境變量是PKG_CONFIG_PATH,配置值為xxx.pc文件的搜索路徑。
]$ vim ~/.bash_profile //添加內容如下
#Add pkg-config path
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
在glib/lib目錄下有一個子目錄pkgconfig,查看下該目錄下的內容:
]# tree -L 1 pkgconfig/
pkgconfig/
├── gio-2.0.pc
├── gio-unix-2.0.pc
├── glib-2.0.pc
├── gmodule-2.0.pc
├── gmodule-export-2.0.pc
├── gmodule-no-export-2.0.pc
├── gobject-2.0.pc
└── gthread-2.0.pc
這些.pc文件的內容是描述了glib三方庫各個模塊的頭文件和庫文件的搜索路徑,以glib-2.0.pc為例,查看該文件內容:
]# cat glib-2.0.pc
prefix=/usr/local/glib
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums
Name: GLib
Description: C Utility Library
Version: 2.30.3
Libs: -L${libdir} -lglib-2.0
Libs.private:
Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include
可以看到,這個文件里面設置的頭文件、庫文件搜索路徑跟我們上面自己配置的路徑是一致的,只不過這個是它自動生成的,這就是pkg-config工具的優勢所在。
在開發過程中,我自己只需要用到:glib-2.0、gthread-2.0,這兩個模塊,因此我只將glib-2.0.pc、gthread-2.0.pc復制到PKG_CONFIG_PATH環境變量所設置的路徑下。
]# cd /usr/local/glib/lib/pkgconfig;ls -1
gio-2.0.pc
gio-unix-2.0.pc
glib-2.0.pc
gmodule-2.0.pc
gmodule-export-2.0.pc
gmodule-no-export-2.0.pc
gobject-2.0.pc
gthread-2.0.pc
]# cp glib-2.0.pc gthread-2.0.pc /usr/local/lib/pkgconfig
設置完成后,我們使用pkg-config 的方式來編譯一下glib_version.c這個源程序,編譯命令如下:
]$ gcc `pkg-config --cflags --libs glib-2.0` glib_version.c -o glib_version
測試結果是編譯通過。
<說明> --cflags 參數,可以給出編譯時所需的頭文件搜索路徑。--libs 參數,可以給出編譯時所需的庫文件搜索路徑。glib-2.0對應的是/usr/local/lib/pkgconfig目錄下的glib-2.0.pc文件。同時,可以注意到我們的編譯命令並沒有加 -lglib-2.0參數,但是加上也無妨。
<Tips> 建議在編寫Makefile文件中,使用 pkg-config 的方式來設置三方庫的開發環境,這樣可以減少和規避潛在的開發風險。
【參考】
簡述configure、pkg-config、pkg_config_path三者的關系
配置glib庫的幫助手冊(man)搜索路徑
在glib的安裝路徑下,有一個share子目錄,而share目錄下又有一個man目錄,這個目錄下存放的就是幫助手冊文件。CentOS7.6系統是在/etc/man_db.conf下進行配置的。
一、配置glib三方庫的API函數的幫助手冊。對應的變量名為MANDATORY_MANPATH。找到MANDATORY_MANPATH,在其下面添加如下內容:
MANDATORY_MANPATH /usr/local/glib/share/man
二、配置glib三方庫的Linux命令的幫助手冊。對應的變量名為MANPATH_MAP。找到MANPATH_MAP,在其下面添加如下內容:
MANPATH_MAP /usr/local/glib/bin /usr/local/glib/share/man
保存修改。
三、測試man幫助命令。
3.1、使用man命令查看glib API函數的使用幫助。例如,
]# man glib_check_version
No manual entry for glib_check_version
測試結果表明好像不支持,cd /usr/local/glib/share/man/man1目錄下查看,並沒有glib-2.0.1文件,所以無法查找出API函數的用法幫助。
3.2、使用man命令查看glib 的Linux命令的使用幫助。
]# man gtester GTESTER(1) User Commands GTESTER(1) NAME gtester - test running utility SYNOPSIS gtester [option...] [testprogram] DESCRIPTION gtester is a utility to run unit tests that have been written using the GLib test framework. When called with the -o option, gtester writes an XML report of the test results, which can be converted into HTML using the gtester-report utility. Options -h, --help print help and exit -v, --version print version information and exit --g-fatal-warnings make warnings fatal -k, --keep-going continue running after tests failed -l list paths of available test cases -m=MODE run test cases in MODE, which can be perf, slow, thorough or quick. The default mode is quick.
可以看到,使用man命令查看glib下的Linux命令是可以的。如上所示,我們查閱到了gtester命令的用法信息。
總結
至此,glib-2.30.3三方庫的源碼安裝和開發環境配置就完成了,接下來就可以使用glib庫來進行應用程序的開發工作了。