Linux_ 4、Linux下的C编程


一、使用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
其中,-I ./include 告诉gcc在“./include”目录下搜寻头文件
**-L. **表示要链接的库,库名为libmymath.a,链接时写为-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),不同的优化级别对应不同的优化处理工作

  1. “-O1”主要进行线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化
  2. “-O2”除了完成所有“-O1”级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度
  3. -O3”则还包括循环展开和其他一些与处理器特性相关的优化工作
  • 使用优化选项的场合:程序发行
  • 不适合使用优化选项的场合:程序开发

三、linux静态库、动态库的创建和使用

1、静态库 libname.a

1.1、什么是静态库

  1. 静态库是一系列目标文件(.o文件)的归档,文件命名格式为libname.o
  2. 静态库内包含的大量可供调用的函数,但它们是以二进制的格式存在的
  3. 如果在编译过程中,有某个程序链接了静态库,则链接器会搜索整个静态库,从而提取它说需要的目标文件,并拷贝到可执行文件中
  4. 因此,静态库只在程序链接时起作用,最终的执行程序可脱离静态库运行。但由于其特性,静态库不免地显得特别臃肿。

1.2、如何创建静态库

  1. 第一步:使对应的.c源文件转为.o的目标文件gcc -c *.c
  2. 第二步:使用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 *.o
a - sub_add.o
a - test.o
a - unsgn_pow.o

1.3、静态库的使用方法

  1. 第一步:链接静态库gcc -o main main.c sub_add.c unsgn_pow.c -I/include -L. -lmymath
  2. 第二步:执行程序./main

2、动态库 libname.so

2.1、什么是动态库

  1. 动态库也是一系列目标文件(.o文件)的归档,其文件命名格式为libname.so
  2. 动态库按其英文(shared library)也可理解为共享库,即多个程序共享使用
  3. 动态库在程序编译时并不会被链接到目标代码中,只有在在程序运行时才会被载入
  4. 运行动态库之前需要先注册动态库的路径名

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、静态库和动态库的比较

链接到静态库会使你的程序臃肿,并且难以升级,但是可能会比较容易部署。而动态库会使你的程序轻便,并且易于升级,但是会难以部署

四、使用gdb调试程序

posted @ 2019-03-30 23:29  盼归汀  阅读(391)  评论(0编辑  收藏  举报