获取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,虽然版本不一样,但是修改方法却是一样的,因此要在理解的基础上进行内容的修改,不能照搬,谨记!!!
Glib库在RHEL 5.8下的编译安装与错误解决
Compiling GLib from source version 2-32.4
四、编译成功后,执行安装命令。
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
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头文件,查找后发现这个头文件所在的路径为:/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参数,但是加上也无妨。
【参考】
简述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库来进行应用程序的开发工作了。