在编写 rdma 代码时,有时候需要使用 gdb 进行调试,或者需要修改 rdma-core 自身的代码进行代码分析,或者需要使用新版本进行测试,在这些场景下通常有必要在本地对 rdma-core 进行构建。

由于这里我们只考虑在本地的编译、调试,因此,不会涉及 rpm 包之类的构建,这些会在独立的文档中进行描述。

构建

rdma-core 的构建体系使用的是 CMake,因此构建起来非常的容易,和其它的 CMake 工程构建没有什么差异:

1
2
3
4
5
6
$ git clone https://github.com/linux-rdma/rdma-core.git
$ cd rdma-core/
$ mkdir build
$ cd build/
$ cmake -DIN_PLACE=1 ..
$ make

注意 cmake 命令行中的 IN_PLACE 宏定义,这样本地构建的命令行程序才会使用 build/etc/ 目录下的配置文件(否则需要定义 CMAKE_INSTALL_PREFIX 为 /usr,这样命令行程序会加载系统目录下配置),默认构建(既不定义 IN_PLACE,也不定义 CMAKE_INSTALL_PREFIX)会报如下的告警(并且最终的执行结果会出错):

1
libibverbs: Warning: couldn't open config directory '/usr/local/etc/libibverbs.d'.

当然,如果最后执行 make install 将本地构建的结果安装到系统目录也可以,只不过这种方式不是太优雅。

构建的输出物如下,显然这些都是我们所熟悉的哪些命令、库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ls bin
check_lft_balance.pl ib_acme ibhosts ibportstate ibstatus ibv_devinfo iwpmd rdma-ndd rping smpquery umad_compile_test
cmtime ibaddr ibidsverify.pl ibqueryerrors ibswitches ibv_rc_pingpong mckey rdma_rename rstream srp_daemon umad_reg2
dump_fts ibcacheedit iblinkinfo ibroute ibsysstat ibv_srq_pingpong mcm_rereg_test rdma_server run_tests.py testleaks umad_register2
dump_lfts.sh ibccconfig ibnetdiscover ibrouters ibtracert ibv_uc_pingpong perfquery rdma_xclient saquery ucmatose umad_sa_mcm_rereg_test
dump_mfts.sh ibccquery ibnodes ibsendtrap ibv_asyncwatch ibv_ud_pingpong rcopy rdma_xserver sminfo udaddy vendstat
ibacm ibfindnodesusing.pl ibping ibstat ibv_devices ibv_xsrq_pingpong rdma_client riostream smpdump udpong

$ ls lib
ibacm libefa.so.1.1.34.0 libibmad.so.5 libibumad.so.3 libmlx4-rdmav34.so libmlx5.so.1 librdmacm.so.1 pkgconfig
libbnxt_re-rdmav34.so libhfi1verbs-rdmav34.so libibmad.so.5.3.34.0 libibumad.so.3.2.34.0 libmlx4.so libmlx5.so.1.18.34.0 librdmacm.so.1.3.34.0
libcxgb4-rdmav34.so libhns-rdmav34.so libibnetdisc.so libibverbs.so libmlx4.so.1 libmthca-rdmav34.so librspreload.so
libefa-rdmav34.so libi40iw-rdmav34.so libibnetdisc.so.5 libibverbs.so.1 libmlx4.so.1.0.34.0 libocrdma-rdmav34.so librxe-rdmav34.so
libefa.so libibacmp.so libibnetdisc.so.5.0.34.0 libibverbs.so.1.12.34.0 libmlx5-rdmav34.so libqedr-rdmav34.so libsiw-rdmav34.so
libefa.so.1 libibmad.so libibumad.so libipathverbs-rdmav34.so libmlx5.so librdmacm.so libvmw_pvrdma-rdmav34.so

$ ls python/pyverbs
addr.cpython-38-x86_64-linux-gnu.so cq.cpython-38-x86_64-linux-gnu.so __init__.py providers srq.cpython-38-x86_64-linux-gnu.so
base.cpython-38-x86_64-linux-gnu.so device.cpython-38-x86_64-linux-gnu.so mem_alloc.cpython-38-x86_64-linux-gnu.so __pycache__ utils.py
cm_enums.cpython-38-x86_64-linux-gnu.so dmabuf.cpython-38-x86_64-linux-gnu.so mr.cpython-38-x86_64-linux-gnu.so pyverbs_error.py wr.cpython-38-x86_64-linux-gnu.so
cmid.cpython-38-x86_64-linux-gnu.so enums.cpython-38-x86_64-linux-gnu.so pd.cpython-38-x86_64-linux-gnu.so qp.cpython-38-x86_64-linux-gnu.so xrcd.cpython-38-x86_64-linux-gnu.so

使用

使用本地构建的 rdma-core 时,需要修改系统的 PATH 等环境变量:

1
2
3
4
5
6
7
export ROOT=$(dirname $PWD)
export BUILD_DIR=$ROOT/build
export BIN=$BUILD_DIR/bin
export LIB=$BUILD_DIR/lib
export PYTHONPATH=$BUILD_DIR/python:$BUILD_DIR/python/pyverbs
export LD_LIBRARY_PATH=$LIB
export PATH=$BIN:$PATH

当前,是在 build/ 目录下导出这些环境变量,之所以需要切换到 build/ 目录,是为了简单起见一般会把这些命令放到一个独立的脚本里去执行,如果本地有多个 rdma-core 版本(如 git clone 了多份本地代码),这样一个脚本就能满足在不同代码版本之间切换,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cd ~/working/cpp/rdma-core/build
$ . ~/rdma-core-env.sh
$ which rping
/home/runsisi/working/cpp/rdma-core/build/bin/rping
$ ldd /home/runsisi/working/cpp/rdma-core/build/bin/rping
linux-vdso.so.1 (0x00007fff90f9a000)
librdmacm.so.1 => /home/runsisi/working/cpp/rdma-core/build/lib/librdmacm.so.1 (0x00007fd1949ff000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd194996000)
libibverbs.so.1 => /home/runsisi/working/cpp/rdma-core/build/lib/libibverbs.so.1 (0x00007fd194975000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd194783000)
libnl-3.so.200 => /lib/x86_64-linux-gnu/libnl-3.so.200 (0x00007fd194760000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd194a28000)
libnl-route-3.so.200 => /usr/lib/x86_64-linux-gnu/libnl-route-3.so.200 (0x00007fd1946e8000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd1946e0000)

显然,从上面的输出可以看到,不管是可执行程序本身,还是它所链接的动态库现在都使用的是本地构建的版本。