linux下可用man ldd 或ldd --help来查看命令怎么使用
- $ ls
- main.c test.c test.h
- $ gcc -c test.c
- $ ar rcs libtest.a test.o
- $ gcc main.c -L. -ltest
- $ ls
- a.out libtest.a main.c test.c test.h test.o
- $ ldd a.out
- $ gcc -c test.c
- $ gcc -shared -fPIC -o libtest.so test.o
- $ gcc main.c -L. -ltest
- $ ls
- a.out libtest.so main.c test.c test.h test.o
- $ ldd libtest.so
ldd 是list, dynamic, dependencies的缩写, 意思是, 列出动态库依赖关系。查看对象需要是dynamic executable,可执行程序和动态链接库.so文件。静态链接库.a文件不可查看
ar是archive的缩写 ,归档文件 .ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
下面是ar命令的格式:
ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...
nm是names的缩写 ,nm命令主要是用来列出某些文件中的符号(说白了就是一些函数和全局变量等)。 可以看到, 对于目标文件和可执行文件,以及动态链接库和静态链接库而言, 均可以获得其中的函数.
strings - print the strings of printable characters in files.
意思是, 打印文件中可打印的字符。 我来补充一下吧, 这个文件可以是文本文件(test.c), 可执行文件(test), 动态链接库(test.o), 静态链接库(test.a)
Case 1:
快速查看模块版本。
我们项目组的每个程序模块,都有一个模块子版本号来唯一标识。
例如上面代码中的:
char MODULE_VER[] = "REDISDRIVER_VER_0.17_20180709";1
假如我在一个装有我们项目组研发的软件平台环境中看到一个模块,如何快速地确定这个模块的版本呢?
使用 strings 命令 + grep 命令 可以快速地将版本号过滤查找出来:
[test1280@localhost ~]$ strings main | grep "REDISDRIVER"
REDISDRIVER_VER_0.17_2018070912
Case 2:
快速定位某源文件编译生成哪个 Binary 文件。
例如在 main.c 文件中有:
printf("global unique identifier\n");1
我想要知晓,main.c 源文件最后会编译到哪个 Binary 文件中,如何查找呢?
[test1280@localhost ~]$ strings -f * | grep "global unique identifier"
main: global unique identifier
main.c: printf("global unique identifier\n");123
从上面的输出可以看到,main.c 源文件最后编译到 main Binary 文件中啦!
注:由于 * 包含了 main.c 源文件,自然输出了源文件 main.c 一项。优化时可以判断是否有 x 权限,等等。
Case 3:
快速确认 重新编译 是否成功。
当项目很庞大时,如果更新单个文件,然后重新 make 可能由于五花八门的各类原因导致编译、链接错误,使得更新过的代码并未正确反映到对应的可执行文件中。
例如:
更新前为
printf("update something\n");
$ strings main | grep "update something"
update something12
更新后为
printf("update something @ \n");
$ strings main | grep "update something"
update something @
这样我们可以在不运行程序之前,确认代码是否更新成功。