SPDK应用静态链接

如何完全静态链接一个SPDK应用

在编译SPDK应用程序时,有时需要使用静态链接SPDK库的版本。

有时甚至需要完全静态链接(包括静态链接系统库,libc等)的版本。

用于特定TEE环境,无动态库甚至无完整操作系统支持

去网上查询,没有直接SPDK静态链接的解决办法。探索了一番后,把我的做法总结上来。

注意:本文的解决方案在于完全静态链接SPDK程序(包括libc), 如果你寻找的是仅静态链接SPDK库的方法,请参考Linking SPDK applications with pkg-config

TL;DR

以SPDK自带的spdk_nvme_perf应用为例。

首先按照正常流程编译DPDK和SPDK。

对于交叉编译(以RISC-V为例),先交叉编译DPDK并安装到路径/path/to/dpdk/bin,随后如下编译SPDK:

进入SPDK根目录:

1
2
3
4
export CC=riscv64-linux-gnu-gcc
export CXX=riscv64-linux-gnu-g++
./configure --target-arch=rv64gc --cross-prefix=riscv64-linux-gnu --with-dpdk=/path/to/dpdk/bin
make -j($nproc)

进入SPDK_ROOT/app/spdk_nvme_perf

编辑Makefile 在尾部添加

1
2
3
4
5
6
7
8
9
PKG_CONFIG_PATH = $(SPDK_ROOT_DIR)/build/lib/pkgconfig
SPDK_LIB := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --libs spdk_nvme spdk_env_dpdk spdk_vmd)
SYS_LIB := $(shell PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" pkg-config --libs --static spdk_syslibs)

static:
	$(CC) -o $(SPDK_ROOT_DIR)/build/bin/perf-static perf.o \
	-static -static-libgcc \
	-Wl,--whole-archive $(SPDK_LIB) \
	-Wl,--no-whole-archive $(SYS_LIB)

执行

1
make static

即可获得位于$(SPDK_ROOT_DIR)/build/bin/perf-static的静态链接可执行文件。

解析

pkg-config

pkg-config是一个编译辅助工具,用于确定第三方库的位置以获取正确的链接位置和编译命令。需要配合环境变量PKG_CONFIG_PATH使用以指向第三方库提供的*.pc文件。

PKG_CONFIG_PATH = $(SPDK_ROOT_DIR)/build/lib/pkgconfig即SPDK库的pakage config所在位置。

pkg-config --libs spdk_nvme spdk_env_dpdk spdk_vmd命令给出了spdk_nvme,spdk_env_dpdkspdk_vmd三个库的链接命令,这些库的源文件位于$(SPDK_ROOT_DIR)/lib

命令PKG_CONFIG_PATH = $(SPDK_ROOT_DIR)/build/lib/pkgconfig pkg-config --libs spdk_nvme示例输出:

1
-L/path/to/build/lib -lspdk_nvme -lspdk_sock -lspdk_sock_posix -lspdk_trace -lspdk_rpc -lspdk_jsonrpc -lspdk_json -lspdk_util -lspdk_vfio_user -lspdk_log

pkg-config --libs --static spdk_syslibs命令给出了SPDK库所需链接的系统库。

编译选项

-static 静态链接全局选项,所有库会进行静态链接。如果只想对部分库进行静态链接,可以使用-Wl,-Bstatic-Wl,-Bdynamic 包裹要进行静态链接的库链接命令。

-static-libgcc 静态链接libgcc

-Wl, --whole-archive 给链接器传递的指令,强制将后面指定的静态库的所有对象文件都包含到最终的可执行文件中(包括未被引用的符号)

-Wl,--no-whole-archive 禁用 --whole-archive 的行为

我尝试了许多不同命令组合,最终上文那种是最小的有效命令。

碎碎念

本文是今年7月份帮师兄做实验的时候就打算写的一篇小trick, 拖到现在才写,坏处就是回顾了半天才想起来当时的做法。下次还是要更勤快些,现解决,现分享 :p

参考

  1. Linking SPDK applications with pkg-config
  2. SPDK Libraries: #SPDK Static Objects
  3. compile statically linked dpdk apps
Licensed under CC BY-NC-SA 4.0
最后更新于 Dec 09, 2024 19:07 CST