gcc的简单使用

来源:互联网 发布:学软件测试工程师 编辑:程序博客网 时间:2024/05/21 00:19

gcc是一系列的软件的组合
首先,gcc通过cpp预处理器将源程序进行扩展,包括头文件的展开和宏的展开,形成.i文件,然后,gcc通过cc1编译器进行编译,生成汇编程序,通过汇编器as产生可重定位的目标程序,可重定位表示代码段、数据段的开始地址为0,没有根据机器生成实际的地址。最后,通过链接器ld生成可执行目标程序,链接器不仅要完成物理地址的翻译,还要和其他调用的库链接,最终生成可执行文件。

gcc常用选项
-o    生成的文件名称(.s,.i,.o等)
-E    只运行c预处理器
-S    生成汇编代码后停止编译
-c    取消链接的步骤,生成可重定位的目标代码
-Wall  显示所有的警告(建议全部加上)
例如:
gcc -E hello.c -o hello.i(预处理后的文件)
gcc -S hello.i -o hello.s(生成汇编代码)
gcc -c hello.s -o hello.o(可重定位的目标程序)
gcc hello.c -o hello(直接生成可执行程序)

gcc编译多个文件:
一次性编译: gcc hello.c main.c -o main
分开各个编译: gcc -c hello.c -o hello.o
                          gcc -c main.c -o main.o
                          gcc hello.o main.o -o main
为什么分开编译需要加-c选项?因为还无法知道其他库的信息,无法进行链接

头文件:一般包含外部函数的声明
库文件:预先编译好的函数

外部库的使用:gcc -Wall calc.c -o calc -lm         -l表示链接外部库,m表示链接的库是libm.a或者libm.so
虽然链接了外部的库函数,但是函数声明的头文件必须要包含,否则可能产生隐式的转换

静态库与共享库:
静态库:.a文件,一般在程序的链接过程中就被包含进去,运行时不需要包含
动态库:.so文件,只有在程序运行时才被包含,多个程序可以共享,所以,程序使用共享库的时候,仅仅包含了函数入口地址的一个表,而不是整段代码
在程序运行之前,由操作系统将共享库代码由磁盘的共享库中拷贝到内存,称为动态链接

生成静态库:
ar rcs libhello.a hello.o      ar是gnu归档工具,r表示replace(如果存在则替换),c表示create(如果不存在则创建),s表示save(将.o文件中一些索引信息到.a文件中)

使用静态库
gcc -Wall main.c libhello.a -o main
gcc -Wall -L. main.c -o main -lhello     使用-L选项表示搜索的库文件的路径,表示将当前路径加入

库的搜索路径:
C_INCLUDE_PATH,LIBRARY_PATH
从左至右搜索-I -L指定的路径
环境变量指定的目录    ~/.bashprofile
系统指定的目录

生成共享库:
gcc -shared -fPIC hello.o -o libhello.so   shared表示生成共享库格式,PIC表示位置无关码,可以在内存的任何位置启动执行

使用共享库:
gcc -Wall main.o -o main -L. -lhello
一般可以将库文件拷贝至/usr/lib中使用

命令ldd 查看一个目标文件的链接情况

原创粉丝点击