CentOS7.6 源码安装 glib-2.30.3

获取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

<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库来进行应用程序的开发工作了。