cc -l选项
来源:互联网 发布:淘宝 app 编辑:程序博客网 时间:2024/05/16 10:29
之前用g++ -l加载的库文件是.so,而今天发现cc -l加载的是.a,--help 也没有对这个选项作说明。
进一步发现.c代码中使用了一些未定义的函数却还能编译通过,感觉很奇怪,难道c中可以直接使用函数,而不用include进来对应的头文件,只需加载进来
相应的.a文件即可?
做个小实验,如下:
//1.cint main(){abc();return 0;}
执行
cc -c 1.c
生成1.o
此时执行
cc -g -o 1 1.o
提示abc有问题。这时候再写一个这个函数的.a,如下
//2.c#include <stdio.h>int abc(){printf("hello world\n");return 0}
执行命令
cc -c 2.c生成2.o
这时把2.o封装成.a
执行命令
ar -r lib2.a 2.o生成lib2.a
这时候再编译1
cc -g -o 1 -L./ -l2
此时可以成功生成1可执行文件,执行./1显式hello world
而如果是.so文件的话,我想还是需要包含对应的头文件的。
那么如果现在只有.a文件,怎么知道它包含了哪些文件,函数,变量呢?
1. 查看文件:ar -t *.a
2. 查看函数、变量:nm *.a
功能
列出.o .a .so中的符号信息,包括诸如符号的值,符号类型及符号名称等。所谓符号,通常指定义出的函数,全局变量等等。
使用
nm [option(s)] [file(s)]
有用的options:
-A 在每个符号信息的前面打印所在对象文件名称;
-C 输出demangle过了的符号名称;
-D 打印动态符号;
-l 使用对象文件中的调试信息打印出所在源文件及行号;
-n 按照地址/符号值来排序;
-u 打印出那些未定义的符号;
常见的符号类型:
A 该符号的值在今后的链接中将不再改变;
B 该符号放在BSS段中,通常是那些未初始化的全局变量;
D 该符号放在普通的数据段中,通常是那些已经初始化的全局变量;
T 该符号放在代码段中,通常是那些全局非静态函数;
U 该符号未定义过,需要自其他对象文件中链接进来;
W 未明确指定的弱链接符号;同链接的其他对象文件中有它的定义就用上,否则就用一个系统特别指定的默认值。
注意几点:
-C 总是适用于c++编译出来的对象文件。还记得c++中有重载么?为了区分重载函数,c++编译器会将函数返回值/参数等信息附加到函数名称中去形成一个mangle过的符号,那用这个选项列出符号的时候,做一个逆操作,输出那些原始的、我们可理解的符号名称。
使用 -l 时,必须保证你的对象文件中带有符号调式信息,这一般要求你在编译的时候指定一个 -g 选项,见 Linux:Gcc。
使用nm前,最好先用Linux:File查看对象文件所属处理器架构,然后再用相应交叉版本的nm工具。
举例
更详细的内容见man page。这里举例说明:
nm -u hello.o
显示hello.o 中的未定义符号,需要和其他对象文件进行链接.
nm -A /usr/lib/* 2>/dev/null | grep "T memset"
在 /usr/lib/ 目录下找出哪个库文件定义了memset函数.
- cc -l选项
- cc编译命令选项
- 编译选项-l,-L,-I
- gcc中的选项-L和-l
- gcc 选项 -c -I -o -L -l
- Unix:关于gcc -l和-L选项
- GCC编译器中的-I -L -l 选项。
- GCC选项 –I,-l,-L
- GCC选项 –I,-l,-L
- 链接选项-I,-l,-L,-Wl:rpath
- GCC编译器中的-I -L -l 选项。
- GCC编译器中的-I -L -l 选项
- cc的编译选项(学习笔记)
- Solaris10的CC编译器部分编译选项
- Makefile之 cc编译命令选项
- CC编译的一些命令选项
- Makefile之 cc编译命令选项
- gcc 中-I、 -L 与-l选项的作用
- sqlserver的最大连接数测试
- easyui datagrid 的 tip实现
- android之ViewPager的使用详解
- 强制类型转换
- iOS关于导航设置的问题
- cc -l选项
- Gradle DSL method not found: 'compile() 解决办法
- xml Schema
- pb web 环境配置及常见错误处理
- C4.5算法
- 【VBA研究】如何防止用户关闭窗体
- (assign,retain,copy):
- 系统调用基本概念
- boost filesystem测试