如何解决查找目录中的所有符号
我想知道在编译包含它作为头文件的程序时要包含哪个 C 库,在本例中为 #include <pcre2.h>
。我能够弄清楚我需要的文件在哪里的唯一方法是检查我知道需要导出的特定符号。例如:
$ ls
CMakeCache.txt Makefile install_manifest.txt libpcre2-posix.pc pcre2_grep_test.sh
CMakeFiles a.out libpcre2-8.a pcre2-config pcre2_test.sh
CTestCustom.ctest cmake_install.cmake libpcre2-8.pc pcre2.h pcre2grep
CTestTestfile.cmake config.h libpcre2-posix.a pcre2_chartables.c pcre2test
$ objdump -t libpcre2-8.a|grep pcre2_compile
pcre2_compile.c.o: file format elf64-x86-64
0000000000000000 l df *ABS* 0000000000000000 pcre2_compile.c
00000000000100bc g F .text 00000000000019dd pcre2_compile_8
0000000000000172 g F .text 00000000000000e3 pcre2_compile_context_create_8
0000000000000426 g F .text 0000000000000055 pcre2_compile_context_copy_8
0000000000000557 g F .text 0000000000000032 pcre2_compile_context_free_8
并且因为符号 pcre2_compile_8
存在于该文件中(在尝试了所有其他文件之后......)我知道我需要包含的库是 pcre2-8
,也就是说,我编译我的代码:
$ gcc myfile.c -lpcre2-8 -o myfile; ./myfile
与此相关的两个问题:
- 有没有更简单的方法可以在一批文件(其中一些不是 elf 文件)中找到一个符号?例如,像
objdump -t *
?或者最接近这样做的事情是什么? - 是否有更好的方法来找出
-l<library>
的库值?或者,当有人下载一个新的 C 程序时,他们知道将什么添加到他们的命令行以便程序运行时,常用的方法是什么? (对我来说,我刚刚花了最后一个小时才弄清楚它是-lpcre2-8
而不是-lpcre
或-lpcre2
。
解决方法
通常,您从库中调用的函数将是该库定义的符号。但是在 PCRE2 中,由于不同的代码单元大小,您调用的函数(例如 pcre2_compile
)实际上通过预处理器宏(例如 pcre2_compile_8
)变成了不同的符号。您可以通过编译您的程序并检查未定义的符号来从库中找到您需要的符号:
$ cat test.c
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
int main() {
pcre2_compile("",NULL,NULL);
}
$ gcc -c test.c
$ nm -u test.o
U _GLOBAL_OFFSET_TABLE_
U pcre2_compile_8
有没有更简单的方法可以在一批文件中找到一个符号?
您可以在目录(下面的/usr/lib/
)中搜索库文件(下面的.a
或 .so
扩展名),为每个文件运行 nm
并搜索未定义的符号(改编自this question):
$ for lib in $(find /usr/lib/ -name \*.a -o -name \*.so)
> do
> nm -A --defined-only $lib 2>/dev/null| grep pcre2_compile_8
> done
/usr/lib/x86_64-linux-gnu/libpcre2-8.a:libpcre2_8_la-pcre2_compile.o:0000000000007f40 T pcre2_compile_8
有没有更好的方法来找出 -l 的库值是什么?
通常通过库文档传达。对于 PCRE2,the second page of the documentation 讨论了提供适当标志的 pcre-config
工具:
pcre2-config
返回已安装 PCRE2 库的配置以及编译程序以使用它们所需的选项。部分选项分别仅适用于 8 位、16 位或 32 位库,不适用于尚未构建的库。
[...]
--libs8
将链接 8 位 PCRE2 库(在许多系统上为 -lpcre2-8
)所需的命令行选项写入标准输出。
[...]
--cflags
将编译使用 PCRE2 的文件所需的命令行选项写入标准输出(这可能包括一些 -I
选项,但在许多系统上为空白)。
所以对于这个特定的库,推荐的构建和链接方式是:
gcc -c $(pcre2-config --cflags) test.c -o test.o
gcc test.o -o test $(pcre2-config --libs8)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。