目录
一、使用gcc命令来编译.c源程序
1、gcc编译过程:预处理->编译->汇编->链接
gcc支持的后缀
gcc常用选项
一步编译、连接
gcc无需加选项
对应gcc代码:gcc hello.c –o hello
1.1、预处理 -E
作用:对头文件和宏定义等进行处理
对应gcc代码:gcc –E hello.c –o hello.i
1.2、编译 -S
作用:检查代码是否有语法错误,并将其翻译成汇编语言
对应gcc代码:gcc –S hello.i –o hello.s
1.3、汇编 -c
作用:将编译阶段生产的汇编.s文件,处理为.o目标文件
对应gcc代码:gcc –c hello.s -o hello.o
1.4、链接
作用:将多个.o目标文件组装成最后的可执行文件
对应gcc代码:gcc hello.o -o hello
1.5、运行 ./文件名
对应代码:./文件名
Ps:gcc编译多文件举例gcc -o main main.c sub_add.c unsgn_pow.c -I/include -L. -lmymath
-lmymath
二、gcc扩展
1、gcc——警告选项
使用举例
$ gcc –Wall warning.c –o warning warning.c:4 警告:“main”的返回类型不是“int” warning.c: 在函数“main”中: warning.c:7 警告:在无返回值的函数中,“return” 带返回值 warning.c:5 警告:未使用的变量“tmp”
2、gcc——优化选项
gcc通过编译选项“-On”来控制优化代码的生成(n是一个代表优化级别的整数,取值1-3),不同的优化级别对应不同的优化处理工作
- “-O1”主要进行线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化
- “-O2”除了完成所有“-O1”级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度
- -O3”则还包括循环展开和其他一些与处理器特性相关的优化工作
- 使用优化选项的场合:程序发行
- 不适合使用优化选项的场合:程序开发
三、linux静态库、动态库的创建和使用
1、静态库 libname.a
1.1、什么是静态库
- 静态库是一系列目标文件(.o文件)的归档,文件命名格式为libname.o
- 静态库内包含的大量可供调用的函数,但它们是以二进制的格式存在的
- 如果在编译过程中,有某个程序链接了静态库,则链接器会搜索整个静态库,从而提取它说需要的目标文件,并拷贝到可执行文件中
- 因此,静态库只在程序链接时起作用,最终的执行程序可脱离静态库运行。但由于其特性,静态库不免地显得特别臃肿。
1.2、如何创建静态库
- 第一步:使对应的.c源文件转为.o的目标文件
gcc -c *.c
- 第二步:使用ar命令,如
ar rcsv libmymath.a sub_add.o
ar命令的使用格式:
ar 参数 lib_libname.a file1.o file2.o ... filen.o
ar命令的参数详解:
r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
c:创建一个库。不管库是否存在,都将创建。s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。甚至对于没有任何变化的库也作该动作。对一个库做ar s等同于对该库做ranlib。v:该选项用来显示执行操作选项的附加信息。a:在库的一个已经存在的成员后面增加一个新的文件。如果使用任选项a,则应该为命令行中membername参数指定一个已经存在的成员名。
b:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项b,则应该为命令行中membername参数指定一个已经存在的成员名。 q:快速追加。增加新模块到库的结尾处。并不检查是否需要替换。'a','b',或'I'任选项对此操作没有影响,模块总是追加的库的结尾处。如果使用了任选项v则列出每个模块。 这时,库的符号表没有更新,可以用'ar s'或ranlib来更新库的符号表索引。 d:从库中删除模块。按模块原来的文件名指定要删除的模块。如果使用了任选项v则列出被删除的每个模块。 p:显示库中指定的成员到标准输出。如果指定任选项v,则在输出成员的内容前,将显示成员的名字。如果没有指定成员的名字,所有库中的文件将显示出来。ar命令使用示例
$ ar -rcsv libtest.a *.oa - sub_add.oa - test.oa - unsgn_pow.o
1.3、静态库的使用方法
- 第一步:链接静态库
gcc -o main main.c sub_add.c unsgn_pow.c -I/include -L. -lmymath
- 第二步:执行程序
./main
2、动态库 libname.so
2.1、什么是动态库
- 动态库也是一系列目标文件(.o文件)的归档,其文件命名格式为libname.so
- 动态库按其英文(shared library)也可理解为共享库,即多个程序共享使用
- 动态库在程序编译时并不会被链接到目标代码中,只有在在程序运行时才会被载入
- 运行动态库之前需要先注册动态库的路径名
2.2、如何创建动态库
1. 第一步:使用gcc命令,如gcc -share -fpic -o libmymath.so sub_add.c unsgn_pow.c
2. 第二步:注册动态库的路径名
1. 方法一:修改/etc/ld.so.conf文件
# 将库libmymath.so的路径追加到/etc/ld.so.conf文件中去$ echo $PWD >> /etc/ld.so.conf $ ldconfig # ldconfig是一个动态链接库管理命令,注册动态库路径后要执行提醒一下$ ./pow_test 2 10 2 ^ 10 = 1024
2. 方法二:修改LD_LIBRARY_PATH环境变量
# 使用export命令设置动态库路径环境变量,如下:$export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH$ ./pow_test 2 10 2^10 = 1024
3. 方法三:将库文件直接拷备到/lib或者/usr/lib目录下
$ cp libpow.so /lib$ ./pow_test 2 10 2^10 = 1024
3、静态库和动态库的比较
链接到静态库会使你的程序臃肿,并且难以升级,但是可能会比较容易部署。而动态库会使你的程序轻便,并且易于升级,但是会难以部署