一、GCC概述GCC目前支持的体系结构有四十余种如X86、ARM、PowerPC等系列处理器能运行在不同的操作系统上如Linux、Windows、Android、CE等操作系统可完成C、C等源文件向运行在特定CPU硬件上的目标代码的转换。换言之GCC可以根据不同CPU的指令集来生成对应的二进制机器指令。GCC是Linux平台下做常用的编译器之一它也是Linux平台编译器事实的标准。GCC编译器与GNU Binutils工具包是紧密集成的Binutils是一系列开发工具。虽然Linux操作系统中文件名的扩展名不能代表文件的类型但是为了提高工作效率通常会给每种文件定义一个扩展名。以下是GCC支持的一些文件类型扩展名说明.cC源程序.a由目标文件文件构成的档案文件库文件.C、.ccC源程序.h头文件.i经过预处理的C程序.ii经过预处理的C程序.mObjective C源程序.o编译后的目标程序.s汇编语言源程序.S经过预编译的汇编程序二、GCC编译过程使用GCC由C语言源代码程序生成的可执行文件要经历四个过程分别是预处理、编译、汇编、连接。1预编译预编译的主要功能就是读取源程序并且对头文件include、预编译语句和一些特殊符号进行分析和预处理。源代码中的预编译指示以“#”为前缀。预编译主要完成三个具体任务包括把include中的头文件复制到要编译的源文件中、用实际值代替define文本、在调用宏的地方进行宏替换。通常在gcc后加上-E选项完成对代码的预编译预编译命令如下# gcc -E hello.c2编译编译主要功能包括两部分第一部分是检查代码的语法有错误给出错误提示并结束编译没有错误才进入第二步第二步是将与编译后的文件转换成汇编语言并自动生成扩展名为.s的文件。编译命令如下# gcc -S hello.c3汇编汇编主要功能是将汇编语言代码转化为目标代码机器码。汇编只是将汇编语言代码转化成目标代码这个时候的目标代码话不能再CPU上运行。汇编使用-c会自动生成一个扩展名为.o的目标程序。汇编命令如下# gcc -c hello.c4链接链接的主要功能是连接目标代码并形成可执行文件。执行命令后会生成一个名为test的可执行文件通过执行./test命令就可以运行指定程序。连接的命令如下# gcc test.c -o test //或者 # gcc test.o -o test三、GCC选项GCC编译器提供了较多的选型选项必须以“-”开始常用的选项如下选项说明-c只编译生成目标文件扩展名为.o-E只进行预编译不做其他处理-g在执行程序中包括标准调试信息-I DirName将DirName加入头文件的搜索目录列表中-L DirName将DirName加入库文件的搜索目录列表中在默认情况下gcc只链接共享库-I FOO链接名为libFOO的函数库-O整个源代码会在编译、连接过程中进行优化处理可执行文件的执行效率可以提高但是编译、连接的过程就相对较慢了-O2比-O更好的优化但是编译、连接的速度更慢了-o FileName指定输出文件名如果没有指定默认文件名是a.out-pipe在编译过程中不同阶段间使用的管道-S只编译不会汇编生成汇编代码-static连接静态库-Wall指定产生全部的警告信息1输出文件选项如果不进行任何选项的编译生成的可执行文件都是a.out。如果要指定文件名可以使用选项-o例如将源文件hello.c编译成可执行文件hello命令格式如下# gcc hello.c -c hello2链接库文件选项LInux操作系统的库文件包含两种格式一是动态链接库扩展名为.so是在程序运行过程中进行动态加载的换言之就是“用时去借”二是静态链接库扩展名为.a是在编译过程中完成静态加载换言之就是“提前复制”。编译过程属于代码构建阶段会执行预处理、编译、汇编、链接这时候使用静态链接库链接器将库中的代码复制一份到可执行文件里程序运行过程也就是运行可执行文件时使用动态链接库程序就会取在北村中找到对应的动态库加载进去供程序调用。使用GCC编译时编译器会自动调用C标准库文件但当要使用标准库以外的库文件时一定要使用选项-l来指定具体库的文件名否则会报错比如报undefined reference to“XXX”错误。Linux操作系统下的库都以lib开头因此在使用选项-l指定链接的库文件时可以省去lib。如果只是生成目标文件而不链接生成可执行文件则不需要指定库文件名如输入以下命令-o指定输出文件名所以其后必须是它的参数-c的位置可以随意# gcc test.c -c -o test.o如果要链接可执行文件就必须指定标准库外的库的文件名命令如下假定pthread不是标准库由于-c只编译不链接所以不用-c# gcc test.c -lpthread -o testGCC默认使用动态链接库所以如果要强制使用静态链接库的话必须要加上-static的选项命令如下# gcc test.c -static -lpthread -o test3指定库文件目录选项编译时编译器会自动到默认目录一般为/usr/lib寻找库文件但当编译时所用到的库文件不在目录时就需要使用选项-L来指定库文件所在的目录。假设程序test.c中调用的函数change在库libnew.so中而这个库不在默认目录下在/home/test/lib目录下这时将test.c编译成可执行程序test的命令如下# gcc test.c -L /home/test/lib -lnew -o test4指定头文件目录选项编译时编译器会自动到默认目录一般为/usr/include寻找头文件但当编译时所用到的头文件不在目录时就需要使用选项-I来指定头文件所在的目录。假设程序test.c中使用的一个头文件保存在/home/test/include目录下这时将test.c编译成可执行程序test的命令如下# gcc test.c -I /home/test/include -o test5警告选项GCC包含完整的警告提示功能以便确定代码是否正确尽可能地实现可移植性其警告选项如下类型说明-Wall启用所有警告信息-Werror在发生警告时取消编译操作即将警告看作是错误-w禁用所有警告信息6调试选项代码通过编译并不代表可以正常工作了还应该通过调试器来检查代码以便更好的找到程序中的问题。在采用调试器之前执行程序中要包括标准调试信息具体命令如下# gcc -g hello.c -o hello7优化选项优化选项的作用在于缩减代码规模和提高代码执行效率常用选项为-O、-O1、-O2、-O3。四、GDB调试器Linux操作系统下GNU的调试器成为GDB可以使开发者在运行程序的过程中观察程序的内部结构和内存的使用情况。GDB主要可以完成如下4个方面的内容1启动程序按照程序员自定义的要求运行程序2单步执行、设置断点可以让被调试的程序在所指定的断点处停住3监视程序中变量的值4动态的改变程序的执行环境。五、GDB基本使用方法使用GDB调试器必须在编译时加入调试选项-g命令如下# gcc test.c -g -o test生成可执行文件后启动GDB调试环境可以在调试环境中对代码进行断点等设置命令如下//启动GDB调试环境 # gcc test //查看源代码相当于list gdbl //在源代码第8行设置断点 gdbbreak 8 //在源代码sum函数处设置断点 gdbbreak sum //显示断点信息 gdbinfo break //运行程序 gdbr //在第一个断点处停止单步执行 gdbn //输出变量s的值 gdbprint s //继续执行 gdbc //退出调试环境 gdbq六、GDB基本命令GDB中有很多命令可以通过help命令来帮助查看help命令只列出了种类名如果想要了解一类下的具体命令要在help后加类名命令如下gdbhelp //查看run类下的具体命令 gdbhelp run常用的GDB命令如下命令描述backtrace显示程序中的当前位置和表示如何到达当前位置的栈跟踪break设置断点cd改变当前工作目录clear消除停止处的断点continue从断点处开始继续执行delete删除一个断点或监视点display程序停止时显示变量或表达式file装入要调试的可执行文件info查看要调试的可执行文件kill终止正在调试的程序make使用户不退出GDB就可以重新产生可执行文件next执行下一行代码从而执行一个整体的函数print显示变量或表达式的值pwd显示当前工作目录quit退出GDBrun执行当前被调试的程序set给变量赋值shell不离开GDB就执行UNIX shell命令step执行下一行代码并进入函数内部watch设置监视点使用户能监视一个变量或表达式的值而不管它何时被变化list列出源文件内容
Linux系统编程基础——GCC编译器与GDB调试器
一、GCC概述GCC目前支持的体系结构有四十余种如X86、ARM、PowerPC等系列处理器能运行在不同的操作系统上如Linux、Windows、Android、CE等操作系统可完成C、C等源文件向运行在特定CPU硬件上的目标代码的转换。换言之GCC可以根据不同CPU的指令集来生成对应的二进制机器指令。GCC是Linux平台下做常用的编译器之一它也是Linux平台编译器事实的标准。GCC编译器与GNU Binutils工具包是紧密集成的Binutils是一系列开发工具。虽然Linux操作系统中文件名的扩展名不能代表文件的类型但是为了提高工作效率通常会给每种文件定义一个扩展名。以下是GCC支持的一些文件类型扩展名说明.cC源程序.a由目标文件文件构成的档案文件库文件.C、.ccC源程序.h头文件.i经过预处理的C程序.ii经过预处理的C程序.mObjective C源程序.o编译后的目标程序.s汇编语言源程序.S经过预编译的汇编程序二、GCC编译过程使用GCC由C语言源代码程序生成的可执行文件要经历四个过程分别是预处理、编译、汇编、连接。1预编译预编译的主要功能就是读取源程序并且对头文件include、预编译语句和一些特殊符号进行分析和预处理。源代码中的预编译指示以“#”为前缀。预编译主要完成三个具体任务包括把include中的头文件复制到要编译的源文件中、用实际值代替define文本、在调用宏的地方进行宏替换。通常在gcc后加上-E选项完成对代码的预编译预编译命令如下# gcc -E hello.c2编译编译主要功能包括两部分第一部分是检查代码的语法有错误给出错误提示并结束编译没有错误才进入第二步第二步是将与编译后的文件转换成汇编语言并自动生成扩展名为.s的文件。编译命令如下# gcc -S hello.c3汇编汇编主要功能是将汇编语言代码转化为目标代码机器码。汇编只是将汇编语言代码转化成目标代码这个时候的目标代码话不能再CPU上运行。汇编使用-c会自动生成一个扩展名为.o的目标程序。汇编命令如下# gcc -c hello.c4链接链接的主要功能是连接目标代码并形成可执行文件。执行命令后会生成一个名为test的可执行文件通过执行./test命令就可以运行指定程序。连接的命令如下# gcc test.c -o test //或者 # gcc test.o -o test三、GCC选项GCC编译器提供了较多的选型选项必须以“-”开始常用的选项如下选项说明-c只编译生成目标文件扩展名为.o-E只进行预编译不做其他处理-g在执行程序中包括标准调试信息-I DirName将DirName加入头文件的搜索目录列表中-L DirName将DirName加入库文件的搜索目录列表中在默认情况下gcc只链接共享库-I FOO链接名为libFOO的函数库-O整个源代码会在编译、连接过程中进行优化处理可执行文件的执行效率可以提高但是编译、连接的过程就相对较慢了-O2比-O更好的优化但是编译、连接的速度更慢了-o FileName指定输出文件名如果没有指定默认文件名是a.out-pipe在编译过程中不同阶段间使用的管道-S只编译不会汇编生成汇编代码-static连接静态库-Wall指定产生全部的警告信息1输出文件选项如果不进行任何选项的编译生成的可执行文件都是a.out。如果要指定文件名可以使用选项-o例如将源文件hello.c编译成可执行文件hello命令格式如下# gcc hello.c -c hello2链接库文件选项LInux操作系统的库文件包含两种格式一是动态链接库扩展名为.so是在程序运行过程中进行动态加载的换言之就是“用时去借”二是静态链接库扩展名为.a是在编译过程中完成静态加载换言之就是“提前复制”。编译过程属于代码构建阶段会执行预处理、编译、汇编、链接这时候使用静态链接库链接器将库中的代码复制一份到可执行文件里程序运行过程也就是运行可执行文件时使用动态链接库程序就会取在北村中找到对应的动态库加载进去供程序调用。使用GCC编译时编译器会自动调用C标准库文件但当要使用标准库以外的库文件时一定要使用选项-l来指定具体库的文件名否则会报错比如报undefined reference to“XXX”错误。Linux操作系统下的库都以lib开头因此在使用选项-l指定链接的库文件时可以省去lib。如果只是生成目标文件而不链接生成可执行文件则不需要指定库文件名如输入以下命令-o指定输出文件名所以其后必须是它的参数-c的位置可以随意# gcc test.c -c -o test.o如果要链接可执行文件就必须指定标准库外的库的文件名命令如下假定pthread不是标准库由于-c只编译不链接所以不用-c# gcc test.c -lpthread -o testGCC默认使用动态链接库所以如果要强制使用静态链接库的话必须要加上-static的选项命令如下# gcc test.c -static -lpthread -o test3指定库文件目录选项编译时编译器会自动到默认目录一般为/usr/lib寻找库文件但当编译时所用到的库文件不在目录时就需要使用选项-L来指定库文件所在的目录。假设程序test.c中调用的函数change在库libnew.so中而这个库不在默认目录下在/home/test/lib目录下这时将test.c编译成可执行程序test的命令如下# gcc test.c -L /home/test/lib -lnew -o test4指定头文件目录选项编译时编译器会自动到默认目录一般为/usr/include寻找头文件但当编译时所用到的头文件不在目录时就需要使用选项-I来指定头文件所在的目录。假设程序test.c中使用的一个头文件保存在/home/test/include目录下这时将test.c编译成可执行程序test的命令如下# gcc test.c -I /home/test/include -o test5警告选项GCC包含完整的警告提示功能以便确定代码是否正确尽可能地实现可移植性其警告选项如下类型说明-Wall启用所有警告信息-Werror在发生警告时取消编译操作即将警告看作是错误-w禁用所有警告信息6调试选项代码通过编译并不代表可以正常工作了还应该通过调试器来检查代码以便更好的找到程序中的问题。在采用调试器之前执行程序中要包括标准调试信息具体命令如下# gcc -g hello.c -o hello7优化选项优化选项的作用在于缩减代码规模和提高代码执行效率常用选项为-O、-O1、-O2、-O3。四、GDB调试器Linux操作系统下GNU的调试器成为GDB可以使开发者在运行程序的过程中观察程序的内部结构和内存的使用情况。GDB主要可以完成如下4个方面的内容1启动程序按照程序员自定义的要求运行程序2单步执行、设置断点可以让被调试的程序在所指定的断点处停住3监视程序中变量的值4动态的改变程序的执行环境。五、GDB基本使用方法使用GDB调试器必须在编译时加入调试选项-g命令如下# gcc test.c -g -o test生成可执行文件后启动GDB调试环境可以在调试环境中对代码进行断点等设置命令如下//启动GDB调试环境 # gcc test //查看源代码相当于list gdbl //在源代码第8行设置断点 gdbbreak 8 //在源代码sum函数处设置断点 gdbbreak sum //显示断点信息 gdbinfo break //运行程序 gdbr //在第一个断点处停止单步执行 gdbn //输出变量s的值 gdbprint s //继续执行 gdbc //退出调试环境 gdbq六、GDB基本命令GDB中有很多命令可以通过help命令来帮助查看help命令只列出了种类名如果想要了解一类下的具体命令要在help后加类名命令如下gdbhelp //查看run类下的具体命令 gdbhelp run常用的GDB命令如下命令描述backtrace显示程序中的当前位置和表示如何到达当前位置的栈跟踪break设置断点cd改变当前工作目录clear消除停止处的断点continue从断点处开始继续执行delete删除一个断点或监视点display程序停止时显示变量或表达式file装入要调试的可执行文件info查看要调试的可执行文件kill终止正在调试的程序make使用户不退出GDB就可以重新产生可执行文件next执行下一行代码从而执行一个整体的函数print显示变量或表达式的值pwd显示当前工作目录quit退出GDBrun执行当前被调试的程序set给变量赋值shell不离开GDB就执行UNIX shell命令step执行下一行代码并进入函数内部watch设置监视点使用户能监视一个变量或表达式的值而不管它何时被变化list列出源文件内容