目录
gcc编译器函数库静态库创建静态库动态库(共享库)创建动态库make工程管理make的使用Makefile文件编写gdb调试工具gcc编译器
gcc 编译器是 Linux 系统下最常用的 C/C++ 编译器,大部分 Linux 发行版中都会默认安装。
gcc的编译过程:
预处理:主要是加载头文件、进行宏替换、条件编译等编译:在确定没有语法和词法错误后将其翻译成汇编代码汇编:将编译过程中生成的汇编文件转换成二进制代码链接:将目标文件、库文件等链接成可执行文件
gcc支持编译的后缀名
gcc有非常多的编译选项,这里列举几个常用的
-o 指定输出文件,默认:a.out-E 仅进行预处理,生成预处理代码(默认输出到屏幕,可通过-o输出到文件)-S 编译到汇编语言,生成汇编代码:*.s-c 将汇编语言翻译到目标代码(也可以直接编译c文件,gcc会根据文件后缀名进行判断),不进行链接,生成目标文件:*.o-g 编译时在可执行文件中插入调试信息,以便gdb进行调试-Wall 显示更多警告信息-O n 优化编译,提高可执行程序的运行速度,n可取值:1,2,3-lx 链接库,对应库文件为libx.so或libx.a,x为库名,与-l之间没有空格I dir 指定额外的头文件搜索位置dirL dir 指定额外的库文件搜索位置dir-static 不使用动态库,编译出的文件较大,但不需要再链接库-share 尽量使用动态库
gcc编译常用格式如下:
gcc C源文件 -o 目标文件
函数库
函数库是一组预先编译好的函数集合,以便重复使用。
静态库
在链接阶段,编译器将指定的静态库与程序代码结合生成可执行文件。
静态库的文件名一般是:*.a
创建静态库
首先将源码编译为目标文件(*.o),然后使用ar命令创建静态库。
ar是一个静态库管理命令。
c:创建归档r:把文件合并成一个静态库,如果静态库文件已经存在则更新。v:显示过程信息ar [crv] 库名 文件列表
使用静态库
直接调用,在gcc的源文件里一起列出设置LIBRARY_PATH环境变量来指定库的路径,然后在gcc命令中通过参数-lx来指定库名在gcc参数中指定库文件搜索路径,然后通过参数-lx来指定库名
动态库(共享库)
在编译时,并不将函数库的代码插入到可执行程序中,而是将库的引用插入,在执行期间动态的加载函数库。
创建动态库
在使用gcc生成目标文件时添加参数–fPIC(生成与位置无关的代码),因为动态库的变量地址是运行时确定的,而不是链接时确定的。
然后使用gcc -shared来创建动态库
gcc -shared -o lib*.so(库名) *.o(目标文件列表)
make工程管理
make是一个"自动编译管理器"
在模块化开发中,make来根据程序模块的修改情况重新编译链接目标代码,以保证目标代码总是由它的最新模块组成。
make命令将根据Makefile文件的内容来处理依赖关系,只编译需要更新的模块,方便大型项目的管理。
make的使用
由于现在的很多IDE集成了自动生成Makefile文件的功能,因此这里只作简单介绍。
语法
make [选项] [make工程文件]
选项
-f makefile 指定规则文件,建议使用默认的Makefile-d 显示调试信息-n 显示命令,但不执行-s 执行命令但不显示任何信息
Makefile文件编写
Makefile的文件格式为:
目标文件列表:依赖文件列表
<TAB>命令列表
目标文件列表:make需要创建的文件依赖文件列表:编译目标文件所需要的其他文件,make会先去处理依赖文件的编译命令列表:make执行的动作,通常是编译命令
示例
下面的程序的功能是输入一个名字name,打印"hello,name"
sayhello.c文件内容
#include <stdio.h>int main(){printf("what's your name?\n");char name[100];scanf("%s", name);myprint(name);return 0;}
myprint.c文件内容
#include <stdio.h>void myprint(char name[]){printf("hello,%s\n", name);}
Makefile文件内容
sayhello:sayhello.c myprint.ogcc sayhello.c myprint.o -o sayhellomyprint.o:myprint.cgcc myprint.c -c -o myprint.o
下面是执行make命令的输出
gcc myprint.c -c -o myprint.ogcc sayhello.c myprint.o -o sayhello
运行sayhello文件
>>>what's your name?<<<jack>>>hello,jack
修改myprint.c文件
#include <stdio.h>void myprint(char name[]){printf("nice to meet you,%s\n", name);}
再次执行make命令,下面是输出内容,因为sayhello要重新链接目标文件,所以两条编译命令都执行了
gcc myprint.c -c -o myprint.ogcc sayhello.c myprint.o -o sayhello
修改sayhello.c文件
#include <stdio.h>int main(){printf("tell me your name\n");char name[100];scanf("%s", name);myprint(name);return 0;}
再次执行make命令,下面是输出内容,这次只执行了一条编译命令,因为myprint.o文件无需更新
gcc sayhello.c myprint.o -o sayhello
gdb调试工具
跟踪程序的运行,给出它的内部运行状态以协助开发者定位程序中的错误。
语法
gdb [选项] [可执行程序]
选项
-q 安静模式,启动gdb时不输出版本和版权信息-n 不执行任何初始化文件中的命令,默认初始化文件为 .gdbinit-cd dir 将dir作为调试的工作目录,默认为当前目录
进入gdb后通过gdb提供的命令来进行调试
file 装入待调试的程序kill 终止当前调试的程序list 列出源程序,默认只显示10行,按回车继续显示下10行next 执行一行程序但不进入函数step 执行一行程序但且进入函数run 执行当前程序watch 动态监视指定变量的值,当变量变化时立 即暂停执行print 打印表达式值break n 在第n行上设置断点quit 退出调试