一、通用命令选项;(区分大小写)
-Wall:将所有的警告信息输出到stdout
-save-temps:将中间文件.i\.s\.o都保存到当前目录下
-o 文件名:指定输出的文件名
-g 可执行程序包含调试信息
size 文件名:可以查看程序中各存储段的情况,dec表示十进制
-std=c99可处理C99代码-ansi 是使用c++98标准去编译代码
-pedantic 允许发出ANSI C标准所列的全部警告信息
二、gcc各处理阶段
part 1:预处理
预处理阶段完成三部分的内容:宏替换,去注释,头文件的包含;输入:.c文件,输出.i文件(纯ASCII码)
-I 头文件目录(可用相对路径):/usr/include目录一般是不用指定的,但如果头文件不在/usr/include里就要用-I参数指定,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数
-E:将预处理后的.i代码输出到stdout,预处理阶段完成后即停止
part 2:编译
编译阶段将纯ASCII码转换为汇编码;输入:.i文件,输出:.s文件(汇编)
-S:编译阶段完成后即停止
-v选项会显示所有编译步骤的调试信息
-Werror:将编译警告转换为错误
part 3:汇编
将汇编码转换为机器语言;输入:.s文件,输出:.o文件(ELF格式,是二进制文件,里面包含一些链接和符号信息)
-C:汇编阶段完成后即停止,实际发现-C后得到的是a.out
part 4:链接
将多个.o文件静态或动态链接,给程序添加一些开始和结束的标识代码;输入.o文件,输出可执行文件(也是ELF格式)
-l 库名:指定链接共享库;以数学库为例,他的库名是m,库文件名是libm.so,把库文件名的头lib和尾.so去掉就是库名(可链接默认文件夹下的库)
-L 库文件路径(可用相对路径):指定链接库的目录;把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest
三、动态库的编译和链接:
在编译时,使用-fPIC选项(创建动态链接库时,可生成位置无关的代码)-shared选项;gcc -fpic -shared (文件名.c) -o (lib动态库名.so)
在链接时, 使用-L -l选项指定要链接的动态库的目录和库名(只在链接时指定了目录,实际运行时还会找不到动态库而报错)
-Wl,-rpath,就是将链接时的动态库路径写入ELF文件,使得运行时也能生效;gcc object.o -l库名 -L. -Wl,-rpath=.
四、静态库的编译和链接:
编译,其实就是把.o文件打包;ar -r (静态库名.a) *.o
链接, 使用-L 选项指定要链接的静态库的目录;gcc object.o a.a -L.
五、总结通用格式:
编译汇编目标文件:gcc -g -Werror -c *.c -I.
编译汇编动态库文件:gcc -fPIC -shared *.c -o liba.so
静态库文件:ar -r b.a *.o
链接动态库:gcc *.o -la -L. -Wl,-rpath=.
链接静态库:gcc *.o *.a -L.