CentOS7.6 源码安装 zeromq-4.2.5

获取ZeroMQ

ZeroMQ官网:https://zeromq.org/

下载ZeroMQ源码包链接1:https://github.com/zeromq/libzmq/releases

下载ZeroMQ源码包链接2:https://zeromq.org/download/

ZeroMQ历史版本下载链接:http://download.zeromq.org/

《说明》ZeroMQ支持多种编程语言,包括C、C++、Java、C#、Python、Go、Ruby、NodeJS等主流编程语言。你可以进入链接2下载对应编程语言的ZMQ版本。

本人下载的是ZeroMQ的C语言版本libzmq,包文件名为:zeromq-4.2.5.tar.gz。

《注意》安装需要有root权限,最好是在root用户下进行,如果不是root用户,执行编译安装操作时需要在命令前加上 sudo 。本人是在root用户下进行操作的。

安装步骤

一、解压缩 zeromq-4.2.5.tar.gz 文件。

tar -xzvf zeromq-4.2.5.tar.gz

解压缩成功后,进入zeromq-4.2.5目录,执行version.sh脚本,会打印出当前zeromq的版本信息。

[root@centos7 zeromq-4.2.5]# ./version.sh
4.2.5[root@centos7 zeromq-4.2.5]#

二、配置 zeromq 的安装环境

1、这个是执行 configure 脚本文件,可以执行 ./configure --help 来查看配置选项和安装路径。如果不加任何选项的话,默认是安装在 /usr/local 路径下,使用 make install 命令安装后,所有文件都是在 `/usr/local/bin', `/usr/local/lib' etc。我们这里自定义一下zeromq的安装路径。

./configure --prefix=/usr/local/zeromq

报错:configure: error: Unable to find a working C++ compiler。提示没有C++编译器,所以首先需要安装g++编译器。

** 在CentOS上使用yum安装C++开发环境:
安装gcc的命令:sudo yum install gcc
安装g++的命令:sudo yum install gcc-c++

安装成功后,执行 g++ -v 命令,正确打印出 g++编译器的版本信息表示安装成功了。

2、配置脚本执行成功后,使用make命令进行编译。

make

3、编译通过后,使用 make install 命令开始安装。

make install

执行成功后,进入/usr/local,查看zeromq目录的树形结构:

[root@centos7 local]# tree -L 3 zeromq/
zeromq/
├── bin
│   └── curve_keygen
├── include
│   ├── zmq.h
│   └── zmq_utils.h
├── lib
│   ├── libzmq.a
│   ├── libzmq.la
│   ├── libzmq.so -> libzmq.so.5.1.5
│   ├── libzmq.so.5 -> libzmq.so.5.1.5
│   ├── libzmq.so.5.1.5
│   └── pkgconfig
│       └── libzmq.pc
└── share
    └── man
        ├── man3
        └── man7

可以看到,zeromq目录下的一级子目录有4个目录文件:bin/、include/、lib/、share,下面分别作简要说明:

bin/:存放的可执行文件。

include/:存放的是头文件。

lib/:存放的是一些库文件。

.a文件:为静态库,是好多个.o文件合在一起,用于静态连接。.la文件:为libtool工具自动生成的一些共享库,主要记录了一些配置信息,是一个文本文件,可以用vi/vim命令打开查看其内容。可以用如下命令查看*.la文件的格式:

# file *.la
libzmq.la: libtool library file, ASCII text

libzmq.so.5.1.5:为共享库文件,是shared object,用于动态连接的,类似于Windows系统中的.dll库文件。

libzmq.so、libzmq.so.5:都为软链接文件(又称为符号链接),它们链接的源文件是libzmq.so.5.1.5。

[root@centos7 lib]# ll *.so*
lrwxrwxrwx 1 root root 15 Jun 2 11:25 libzmq.so -> libzmq.so.5.1.5
lrwxrwxrwx 1 root root 15 Jun 2 11:25 libzmq.so.5 -> libzmq.so.5.1.5
-rwxr-xr-x 1 root root 9224352 Jun 2 11:25 libzmq.so.5.1.5

share/:share目录下存放的是man,它存放的是帮助手册文件,有man3、man7,可以使用man命令来查看。man3是库调用函数,man7是宏命令包和约定。

由于zeromq是我们自定义的安装路径,而man命令的默认搜索路径是:/usr/local/share/man:/usr/share/man。可以使用 man -w 查看man查找手册的路径。我们可以修改man命令搜索配置文件man_db.conf来添加zeromq的帮助手册搜索路径。vim /etc/man_db.conf,由于我这里只是添加zeromq的API函数的搜索路径,找到MANDATORY_MANPATH的位置,在下面添加如下内容:

MANDATORY_MANPATH                /usr/local/zeromq/share/man

然后,保存退出。于是,我们就可以使用man命令来查看zeromq的API函数的用法信息了,如:man zmq_socket,下面是部分内容的打印信息。

# man zmq_socket
ZMQ_SOCKET(3)                                                          0MQ Manual                                                         ZMQ_SOCKET(3)

NAME
       zmq_socket - create 0MQ socket

SYNOPSIS
       void *zmq_socket (void *context, int type);

DESCRIPTION
       The zmq_socket() function shall create a 0MQ socket within the specified context and return an opaque handle to the newly created socket. The
       type argument specifies the socket type, which determines the semantics of communication over the socket.

也可以使用命令:man 3 zmq_socket,3表示man只会在man3目录下去查找对应的函数名。

<备注> 如果要使用man 命令查找bin/目录下的Linux命令的用法的话,同样可以在man_db.conf文件中配置MANPATH_MAP关键字的路径。

【参考】

linux下configure命令详细介绍:https://www.cnblogs.com/xuezhileikaku/articles/5343107.html

Linux man命令详细介绍:https://www.cnblogs.com/DataArt/p/10010673.html

4、设置共享库的搜索路径

  我们知道,要使用zeromq三方库,在编译的时候需要添加 -lzmq 选项,在编译的链接阶段会连接静态库,在运行的时候会加载zeromq的共享库,这就需要知道这些库文件所在的路径。

  一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于在默认库搜索路径之外的库,需要将库的位置添加到库的搜索路径之中。设置库文件的搜索路径有下列两种方式,可任选其一使用:

(1)在 /etc/ld.so.conf 文件中添加库的搜索路径。或者在 /etc/ld.so.conf.d 目录下添加 *.conf文件,添加的内容是库文件的绝对路径。这种方式是全局设置,对所有用户有效,因此不建议使用这种方式设置三方库的搜索路径。推荐使用第二种方式。

(2)在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。一般的用法是在当前用户的主目录(cd ~)下,在 .bash_profile配置文件中设置该环境变量。添加内容如下:

# Add third_lib path
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/zeromq/lib

修改保存后,执行如下操作:

$ source ~/.bash_profile        #让修改生效
$ echo $LD_LIBRARY_PATH         #打印出环境变量的值
/usr/local/lib:/usr/local/lib64::/usr/local/zeromq/lib

** 实例:编译一个zmq_version.c源文件,源码如下:

#include <zmq.h>
#include <stdio.h>
int main()
{
  int major,minor,patch;
  zmq_version(&major,&minor,&patch);	//返回ZMQ链接库的版本
  printf("Current ZMQ version is %d.%d.%d\n",major,minor,patch); //输出版本号
  return 0;
}

编译命令:

$ gcc zmq_version.c -o zmq_version -lzmq
zmq_version.c:1:17: fatal error: zmq.h: No such file or directory
#include <zmq.h>
^
compilation terminated.

可以看到,编译报错了,找不到头文件,所以,我们还需要设置zmq的头文件搜索路径,我们可以通过设置C头文件环境变量C_INCLUDE_PATH 的值,对应的C++头文件环境变量是CPLUS_INCLUDE_PATH

5、设置头文件的搜索路径

同样是在当前用户主目录下的 .bash_profile文件下设置。

$ vim ~/.bash_profile,添加如下内容:

#Add C header file path
export C_INCLUDE_PATH=/usr/local/zeromq/include:$C_INCLUDE_PATH

$ source ~/.bash_profile

$ echo $C_INCLUDE_PATH
/usr/local/zeromq/include:

然后,继续编译。

$ gcc zmq_version.c -o zmq_version -lzmq
/usr/bin/ld: cannot find -lzmq
collect2: error: ld returned 1 exit status

还是报错了,找不到-lzmq的共享库。但是如果编译时通过-L参数加上链接库的搜索路径却可以编译通过:gcc zmq_version.c -o zmq_version -L/usr/local/zeromq/lib -lzmq

查看一下生成的可执行文件zmq_version所依赖的共享库列表:

$ ldd zmq_version
linux-vdso.so.1 => (0x00007fff26546000)
libzmq.so.5 => /usr/local/zeromq/lib/libzmq.so.5 (0x00007f02e4476000)
libc.so.6 => /lib64/libc.so.6 (0x00007f02e40a9000)
librt.so.1 => /lib64/librt.so.1 (0x00007f02e3ea1000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f02e3c85000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f02e3a81000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f02e377a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f02e3478000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f02e3262000)
/lib64/ld-linux-x86-64.so.2 (0x00007f02e4704000)

可以看到,其所依赖的zeromq的共享库文件是 /usr/local/zeromq/lib/libzmq.so.5。让我疑惑的是,我已经设置了环境变量LD_LIBRARY_PATH的值,添加了zeromq的共享库路径了,并且修改生效了,编译时还是提示无法找到zmq的依赖库文件。去网上寻找了下解决办法,发现博客都是千篇一律地认为是没有安装第三方库所导致的,但是我的库已经安装成功了,国内的技术博客质量有时真是让人无语啊,汗颜!!!

经过多次的尝试,只能说提供了一个不算完美的解决方案,方法如下:

]# cd /usr/local/lib
]# ln -s /usr/local/zeromq/lib/libzmq.so.5.1.5 /usr/local/lib/libzmq.so

通过在系统默认搜索共享库路径下创建软连接,然后使用编译命令:gcc zmq_version.c -o zmq_version -lzmq 编译通过了。但总觉得这是多此一举,因为在/usr/local/zeromq/lib路径下是有软连接文件的,上面的介绍中我也提到过的。

这个问题总算是找到原因了,除了要设置LD_LIBRARY_PATH环境变量,还需要设置LIBRARY_PATH环境变量。在 ~/.bash_profile文件中添加如下内容:

export LIBRARY_PATH=/usr/local/zeromq/lib:$LIBRARY_PATH

然后使用gcc zmq_version.c -o zmq_version -lzmq 命令编译就可以通过了。这两个环境变量还是有所区别的。

【参考】

1、 环境变量:LIBRARY_PATH 和 LD_LIBRARY_PATH的区别

6、使用 pkgconfig 方式来自动配置头文件和文件的搜索路径

在ZeroMQ的安装路径下的/usr/local/zeromq/lib下有一个pkgconfig目录,有一个libzmq.pc文件,内容如下:

# more libzmq.pc
prefix=/usr/local/zeromq
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: libzmq
Description: 0MQ c++ library
Version: 4.2.5
Libs: -L${libdir} -lzmq
Libs.private: -lstdc++
Cflags: -I${includedir}

这个libzmq.pc文件描述了ZMQ库的安装路径、库文件路径、头文件路径等相关信息。

pkg-config功能简介

  一般来说,如果库的头文件不在/usr/include目录中,那么在编译的时候需要用-I参数指定其路径。由于同一个库在不同系统上可能位于不同的目录下,用户安装库的时候也可以将库安装在不同的目录下,所以即使使用同一个库,由于库的路径的不同,造成了用-I参数指定的头文件的路径和在连接时使用-L参数指定lib库的路径都可能不同,其结果就是造成了编译命令界面的不统一。可能由于编译,连接的不一致,造成同一份程序从一台机器copy到另一台机器时就可能会出现问题。

  pkg-config 就是用来解决编译连接界面不统一问题的一个工具。

它的基本思想:pkg-config是通过库提供的一个.pc文件获得库的各种必要信息的,包括版本信息、编译和连接需要的参数等。需要的时候可以通过pkg-config提供的参数(–cflags, –libs),将所需信息提取出来供编译和连接使用。这样,不管库文件安装在哪,通过库对应的.pc文件就可以准确定位,可以使用相同的编译和连接命令,使得编译和连接界面统一。

  它提供的主要功能有:

  <1> 检查库的版本号。如果所需库的版本不满足要求,打印出错误信息,避免连接错误版本的库文件。
  <2> 获得编译预处理参数,如宏定义,头文件的路径。
  <3> 获得编译参数,如库及其依赖的其他库的位置,文件名及其他一些连接参数。
  <4> 自动加入所依赖的其他库的设置。

使用pkg-config工具提取库的编译和连接参数有两个基本的前提:

  <1> 库本身在安装的时候必须提供一个相应的.pc文件。不这样做的库说明不支持pkg-config工具的使用。
  <2> pkg-config必须知道要到哪里去寻找此.pc 文件。

环境变量PKG_CONFIG_PATH

  环境变量PKG_CONFIG_PATH是用来设置xxx.pc文件的搜索路径的,pkg-config按照设置路径的先后顺序进行搜索,直到找到指定的.pc 文件为止。这样,库的头文件的搜索路径的设置实际上就变成了对xxx.pc文件搜索路径的设置。设置环境变量PKG_CONFIG_PATH的步骤如下:

1、vim .bash_profile,添加如下内容:

#Add pkg-config path
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

source ~/.bash_profile  //使修改生效

$ echo $PKG_CONFIG_PATH
/usr/local/lib/pkgconfig:

2、将zeromq安装路径下的libzmq.pc文件复制到指定的目录下

cp /usr/local/zeromq/lib/pkgconfig/libzmq.pc /usr/local/lib/pkgconfig

3、编译源文件命令

]$ gcc `pkg-config --cflags --libs libzmq` zmq_version.c -o zmq_version

--cflags参数:可以给出在编译时所需要的头文件路径。

--libs参数:可以给出在编译时所需要的共享库文件路径。

libzmq:这个是库名称,对应libzmq.pc文件。因此,如果有多个.pc文件的情况下,pkg-config可以正确地找到所需要的.pc文件了。

如果安装的三方库自动提供了.pc文件,建议在编写Makefile文件的时候,使用这种方式来配置程序编译时所依赖的头文件和库文件,这样就能保证连接的头文件和库文件是统一的版本。

【参考】

1、简述configure、pkg-config、pkg_config_path三者的关系

2、pkg-config原理及用法

总结

  至此,zeromq-4.2.5三方库的源码安装和环境配置已经弄好了,可以使用zeromq库进行应用程序的开发工作了。

 

posted @ 2020-06-03 16:39  Kugle  阅读(2212)  评论(0编辑  收藏  举报