20135203齐岳 信息安全系统设计基础第二周学习总结
学习计时:共15小时
读书:5
代码:4
作业:4
博客:2
一、学习目标
1.熟悉Linux系统下的开发环境
2.熟悉vi的基本操作
3.熟悉gcc编译器的基本原理
4.熟练使用gcc编译器的常用选项
5.熟练使用gdb调试技术
6.熟悉makefile基本原理及语法规范
7.掌握静态库和动态库的生成
二、学习任务
1.教材第一章,第七章学习:阅读并消化教材内容
2.《嵌入式Linux应用程序开发标准教程》第三章3.1-3.5的学习
3.完成实验:
练习vimtutuor
练习gcc编译运行代码
练习gdb调试代码
把上述代码中除了main函数外的代码制作成一个静态库math.a和一个共享库math.so
编写makefile,让代码编译,上述静态库和共享库的使用自动化。
三、学习过程
1.linux下的C语言编程环境
(1)编辑器
完成对所录入文字的编辑功能,最常用的是vi(vim)和emacs
vi的三种模式及用法
·命令行模式:最初进入的默认模式,可上下移动光标进行删除字符或整行删除,也可进行复制粘贴,但无法编辑
·插入模式:可以编辑,按[Esc]键回到命令行模式
·底行模式:可以进行保存或退出,或设置编辑环境。
(2)编译链接器
指源代码转化成生成可执行代码的过程,最常用的编译器是gcc。
gcc的编译流程
·预处理阶段:头文件和宏定义,—E可以让gcc在预处理结束之后停止编译过程,因此可以看到预处理的过程
一般格式为:gcc [选项] 要编译的文件 [选项] 目标文件
gcc -E hello.c -o hello.i
·编译阶段:gcc将代码翻译成汇编语言,使用选项-S只进行编译而不进行汇编,结果生成汇编代码。
gcc -S hello.i -o hello.s
汇编阶段:将.s文件转成目标文件,使用选项-c可以看到汇编代码转换为二进制目标代码。
gcc -c hello.s -o hello.o
链接阶段:默认搜索链接到libc.so.6函数库当中,调用库文件中已经实现的函数。
gcc编译选项分析
常用选项
-I dir :在头文件的搜索路径列表中添加dir目录,当用户希望添加放置在非默认位置的头文件时可以通过该选项来指定。
库选项
静态库:一系列的目标文件的归档文件,在编译时会搜索静态库提取出其所需要的目标文件并将其复制到该程序可执行的二进制文件中。
动态库:在程序编译时并不会被链接到目标代码中,而是在程序运行时才会被载入。
警告和出错选项
优化选项
"-On":n是一个代表优化级别的整数,n的取值范围对应的优化效果并不完全相同,比较典型的范围是从0变化到2或者3。
“-O”主要进行线程跳转和延迟退栈。 一般在程序即将发行的时候才考虑对其优化。
体系结构相关选项
(3)调试器
gdb调试器,可方便的设置断点、单步跟踪。
gdb的使用流程
·查看文件:键入l(list)查看所载入的文件
·设置断点
i)按行设置断点:b+对应行号即可,可设置多个断点,运行到设置断点的一行程序会自动停止
ii)函数断点:按函数设置断点只需把函数名列在命令“b”之后
iii)条件断点:b 行数或函数名 if 表达式
·查看断点情况:info b,在断点键入bt可查到调用函数(堆栈)的情况。
·运行代码:r+行号可从指定行开始运行代码,默认从头执行
·查看变量值:p+变量值即可
·单步运行
·恢复程序运行
gdb基本命令:
可通过help选项查看
help all:
(4)项目管理器
一个工程中的源文件不计其数,按其类型、功能、模块分别放在若干个目录中。makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至进行更复杂的功能操作(因为makefile就像一个shell脚本一样,可以执行操作系统的命令)。
makefile带来的好处就是——“自动化编译”,一但写好,只需要一个make命令,整个工程完全编译,极大的提高了软件的开发效率。make是一个命令工具,是一个及时makefile中命令的工具程序。
make工具最主要也是最基本的功能就是根据makefile文件中描述的源程序至今的相互关系来完成自动编译、维护多个源文件工程。而makefile文件需要按某种语法进行编写,文件中需要说明如何编译各个源文件并链接生成可执行文件,要求定义源文件之间的依赖关系。
makefile基本结构
需要由make工具创建的目标体(target),通常是目标文件或可执行文件
要创建的目标体所依赖的文件(dependency_file)
创建每个目标体时需要运行的命令(command),这一行必须以制表符开头,格式为
target:dependency_files
command
makefile变量
makefile规则
make管理器的使用
2.链接
与静态库链接
动态库:将所有相关的目标模块打包成一个单独的文件,称为静态库。在unix系统中,静态库以一种称为存档的特殊文件格式存放在磁盘中。
为了创建该库,使用AR工具:
ar rcs libvector.a addvec.o multvec.o
为了创建可执行文件,需要编译链接输入文件*.o 和libvector.a:
gcc -O2 -c *.c
gcc -static -o p2 *.o ./libvector.a
加载可执行目标文件
./p
与动态库链接
共享库是一个目标模块,在运行时可以加载到任意的存储器地址,并和一个在存储器中的程序链接起来。这个过程称为动态链接,是由一个叫做动态链接器的程序来执行的。
创建动态库:
gcc -shared -fPIC -o libvector.so addvec.c multvec.c
将动态库链接到程序中:
gcc -o p2 *.c ./libvector.so
四、遇到的问题
1.起初在使用gcc编译时,认为-E、-S等选项是可写可不写的,于是第一次编译过程中没有加选项,出现了如下情况
2.设置断点后查看断点相关情况出现如下错误:
原因是程序并未开始运行,所以断点无数据,也无堆栈使用情况。使用r命令使程序运行后数据正常。
3.制作静态库动态库的时候,在前面的代码都编译无误,进行到这一步时报错:
原因是vector.h未定义,找不到该文件。 书上解释说vector.h为头文件,当中定义了libvector.a中的函数原型,又尝试去掉#include “vector.h”进行编译,当编译到最后一步时报错函数addvec未定义。
同样,在动态库的制作过程中vector.h也没有相关文件,导致链接失败。
4.课本第七章动态库与静态库的创建和链接应用较好理解,但7.6符号解析,7.7重定位以及7.12PIC和重定位相关知识较为抽象不好理解,希望老师在课堂上作系统讲解。
总结:
本周学习内容以练习为主,vim编辑器,gcc编译以及gdb调试和makefile项目管理都是C语言中的知识只不过换到linux系统中用不同的工具以命令行的形式呈现,较为容易理解,其中对makefile理解最深刻因为在VC写程序时VC环境会帮助做好项目管理,无需自己编写,但在linux中面对较为复杂的程序时makefile则会大大减轻工作量,需多加练习。