问题背景
最近在给dpdk22.11 lib/ethdev/rte_ethdev.c 文件新增功能接口做测试,新增的接口(rte_eth_dev_get_timestamp)被其他模块调用,编译时出现如下报错:
undefined reference to `rte_eth_dev_get_timestamp’
问题分析
- 从函数声明和定义看都没有问题
- 然后查看生成的so文件,发现符号类型是 t
#nm ./build/lib/librte_ethdev.so.23.0 | grep rte_eth_dev_get_timestamp
符号值 符号类型 符号名称
0000000000011ae0 t rte_eth_dev_get_timestamp
nm 是 Linux/Unix系统下查看二进制文件(如可执行文件,目标文件和共享库文件)符号信息的工具。 在 nm 命令的输出中,小写的 t
和大写的 T 都表示相应的符号是在文本(代码)段定义的,但它们表示符号的作用域不同: ● t (小写) 表示该符号是 局部(local)
的,仅在定义它的编译单元(比如一个C文件)中可见,其他编译单元不能链接到该符号。它们通常是由 static 关键字定义的函数或变量。 ● T
(大写) 表示该符号是 全局(global) 的,其他编译单元可以链接到该符号。例如在一个C文件中没有加 static
关键字的全局变量或者函数。
为什么会出现新增函数是个 local 函数呢?对比了一下global的函数,发现global函数都在lib/ethdev/version.map文件中做了定义,然后尝试将新增函数加入version.map中,重新编译,再查看符合表,如下,问题解决。
#nm ./depends/dpdk/build/lib/librte_ethdev.so.23.0 | grep rte_eth_dev_get_timestamp
0000000000011b10 T rte_eth_dev_get_timestamp