第二部分(基础篇)讲稿(二)___makefile及交叉开发环境.ppt_第1页
第二部分(基础篇)讲稿(二)___makefile及交叉开发环境.ppt_第2页
第二部分(基础篇)讲稿(二)___makefile及交叉开发环境.ppt_第3页
第二部分(基础篇)讲稿(二)___makefile及交叉开发环境.ppt_第4页
第二部分(基础篇)讲稿(二)___makefile及交叉开发环境.ppt_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2.5 Makefile,或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作, 但我个人认为:要想成为一个好的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在linux下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型软件工程的能力。,什么是makefile?,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个文件中,makefile定义了

2、一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。 makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。,什么是make?,make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,VisualC+的nmake,Linux下GNU的make。,Linux下GNU的make的工作流程: 1. 查找当前目录下的makefile文件; 2. 初始化makefile文件中的变量; 3. 分

3、析makefile中的所有规则; 4. 为所有的目标文件创建依赖关系 5. 根据依赖关系,决定性哪些目标文 件要重新生成; 6. 执行生成命令;,总之,makefile就是一种在软件工程方面的编译方法。,Makefile其实很复杂, 详尽的描述 可参看相关书籍,.这里通过一个实例来讲述一些最常用的功能,Makefile文件一般包含下面四个部分: 1、宏定义 2、目标定义 3、执行定义 4、伪指令,实例: 有a.c , b.c两个程序. a.c extern void p(char *str); main() p(hello world); b.c #include “stdio.h”void

4、p(char *str) printf(%sn,str); ,# Makefile hello:a.c b.c gcc -o hello a.c b.c 这里是一个Tab(注意一定要有一个Tab) 执行make gcc a.c b.c -o hello 产生一个叫hello的可执行程序.,Makefile:是由规则来组成的,每一条规则都有三部分组成: 目标(object) 依赖(dependency) 命令(command) 在上面的例子中, Makefile只有一条规则,其目标为hello,期依赖为a.c b.c,其命令为gcc -o hello a.c b.c.,依赖:可以是另一条规则的目

5、标,也可以是文件。 每一条规则被这样处理: 1.目标是一个文件:当它的依赖也是文件时,如果依赖文 件的时间比目标文件要新, 则运行规则所包含的命令 来更新目标。 2.如果依赖是另一个目标则用同样的方法先来处理这个 依赖的目标。 3.如目标不是一个存在的文件时,则一定执行。,例如: # Makefile hello:a.c b.o gcc -o hello a.c b.o b.o:b.c gcc -c b.c,执行 make ,则是处理hello这个目标. hello依赖于文件a.c和另一个目标 b.o, 则先去处理b.o,调用gcc -c b.c 来更 新b.o,之后返回,调用gcc -o h

6、ello a.c b.o 来 更新hello.,定义变量: 在makefile中可以定义自己的变量, 例如上例: # makefileCC = gcc hello:a.c b.c $(CC) a.c b.c,/定义变量,/引用变量,特殊变量: 在makefile中还有一些特殊的内部变量, 它们根据每一个规则内容定义 $ 指代当前规则下的目标文件列表 $ 指代依赖文件列表中的第一个依赖的文件 $ 指代依赖文件列表中所有的依赖文件 $? 指代依赖文件列表中新于对应目标文件的 文件列表,例如 # makefileCC = gcc a.o:a.c CC -c $,伪目标: .PHONY:target

7、-伪目标的命令一定会被执行例如 clean: rm a.o b.o clean的目的很简单,就是要删除所有的.o的文件.但这样写,如果处在着一个名为clean的文件时就会产生问题.加上下面一行: .PHONY:clean,例子:8个C文件和3个头文件的Makefile main.c kdb.c command.c display.c insert.c search.c files.c utils. c defs.h command.h buffer.h #Makefile #为生成目标所使用的.o文件 objects=main.o kdb.o command.o display.o inser

8、t.o search.o files.o utils.o #生成可执行文件 edit:$(objects) cc -o edit $(objects),main.o:main.c defs.h cc -c main.c kdb.o:kdb.c defs.h command.h cc c kdb.c command.o:command.c defs.h command.h cc c command.c display.o: display.c defs.h buffer.h cc -c display.c insert.o: insert.c defs.h buffer.h cc c inser

9、t.c search.o: search.c defs.h buffer.h cc c search.c,files.o: files.c defs.h buffer.h command.h cc c files.c utils.o: utils.c defs.h cc c utils.c #生成clean伪目标 .PHONY: clean clean: #执行make clean时删除所有的目标文件 rm -f $(objects),课后思考题,使用Makefile中的特殊的内部变量改写上例的Makefile文件 特殊的内部变量: $ 指代当前规则下的目标文件列表 $ 指代依赖文件列表中的第

10、一个依赖的文件 $ 指代依赖文件列表中所有的依赖文件 $? 指代依赖文件列表中新于对应目标文件的 文件列表,2.6 熟悉Linux编程库,所谓编程库:就是指始终可以被多个linux软件 项目重复使用的代码集。,编程库有两个主要优点 一:可以简化编程,实现代码重复使用; 二:可以直接使用比较稳定的代码,linux下的库文件分为: 共享库(动态库) 静态库 共享库是动态加载(程序运行时); 静态库是编译时静态加载的; 共享库以.so(share object)结尾 静态库以.a(archive)结尾。 linux库一般放在/lib或者/usr/lib目录下。,在终端下,共享库通常为绿色,而静态库为

11、黑色,Linux编程库举例:,Linux线程库,1.进程和线程的概念及区别和联系 进程:资源管理的最小单位; 线程:程序执行的最小单位; 一个进程至少需要一个线程作为它的指令执行体; 进程管理着资源,如文件,内存,CPU等,一个进程 可以拥有多个线程,2.为什么要使用多线程?,理由之一: 和进程相比,多线程是一种非常“节俭”的多任务操作方式。 在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种“昂贵”的多任务工作方式。 而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远

12、远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。 据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,理由之二: 是线程间方便的通信机制。 对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。 线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。,1)提高应用程序响应。 这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的

13、操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。2) 使多CPU系统更加有效。 操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。3) 改善程序结构。 一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。,多线程程序的优点:,/* example.c*/#include ”pthread.h”#include ”stdio.h”#include ”unistd.h” void thread(void) int i; for(i=0;i3;i+) printf(“This is a pthre

14、adn”);/usleep(10); int main(void) pthread_t id; int i,ret; ret=pthread_create(,我们编译此程序:gcc -lpthread -o example1 example1.c 运行example1,我们得到如下结果:This is the main process.This is a pthread.This is the main process.This is the main process.This is a pthread.This is a pthread.再次运行,我们可能得到如下结果:This is a p

15、thread.This is the main process.This is a pthread.This is the main process.This is a pthread.This is the main process.,前后两次结果不一样,这是两个线程争夺CPU资源的结果。,两个函数和一个变量解释: 1.创建新的线程函数 extern int pthread_create _P (pthread_t *_thread, _const pthread_attr_t *_attr,void *(*_start_routine) (void *), void *_arg);,2.等

16、待线程结束函数 extern int pthread_join _P (pthread_t _th, void *_thread_return);,3.pthread_t型的变量 pthread_t在头文件/usr/include/bits/pthreadtypes.h中定义:typedef unsigned long int pthread_t; 它是一个线程的标识符。,三、 交叉开发环境,3.1 交叉开发环境介绍 3.2 交叉开发环境建立(实验课中讲述) 3.3 交叉开发工具链(内核知识中讲述),3.1 交叉开发环境介绍,嵌入式系统是专用的计算机系统, 通常是一个资源受限的系统,如Flas

17、h存储空间很小,没有足够的安装空间,一些嵌入式系统产品不需要显示器键盘鼠标。 因此直接在嵌入式系统的硬件平台上编写软件比较困难,有时候甚至是不可能的。 目前一般采用的解决办法是首先在通用计算机上编写程序,然后通过交叉编译器生成目标平台上可以运行的二进制代码格式,最后再下载到目标平台上的特定位置上运行。 -交叉开发环境(Cross DevelopmentEnvironment),3.1.1 什么是交叉开发环境?,需要交叉开发环境 的支持是嵌入式应用软件开发时的一个显著特点。 交叉开发环境是指: 编译、链接和调试嵌入式应用软件的环境,它与运行嵌入式应用软件的环境有所不同,通常采用宿主机目标机模式,

18、如下图所示:,交叉开发环境示意图,宿主机(Host) 是一台通用计算机(如PC机或者工作站),它通过串口或者以太网接口与目标机通信。 宿主机的软硬件资源比较丰富,不但包括功能强大的操作系统(如Windows和Linux),而且还有各种各样优秀的开发工具(如Microsoft的Embedded Visual C+等),能够大大提高嵌入式应用软件的开发速度和效率。,目标机(Target) 一般在嵌入式应用软件开发期间使用,用来区别与嵌入式系统通信的宿主机,它可以是嵌入式应用软件的实际运行环境,也可以是能够替代实际运行环境的仿真系统,但软硬件资源通常都比较有限。,小结交叉开发环境: 在采用宿主机目标

19、机模式开发嵌入式应用软件时,首先利用宿主机上丰富的资源和良好的开发环境开发和仿真调试目标机上的软件,然后通过串口或者以网络将交叉编译生成的目标代码传输并装载到目标机上,并在监控程序或者操作系统的支持下利用交叉调试器进行分析和调试,最后目标机在特定环境下脱离宿主机单独运行。,嵌入式系统的交叉开发环境 一般包括交叉编译器、交叉调试器和系统仿真器,其中交叉编译器用于在宿主机上生成能在目标机上运行的代码,而交叉调试器和系统仿真器则用于在宿主机与目标机间完成嵌入式软件的调试。,3.1.2 交叉编译器和链接器,在完成嵌入式软件的编码之后,需要进行编译和链接以生成可执行代码,由于开发过程大多是在使用Inte

20、l公司x86系列CPU的通用计算机上进行的,而目标环境的处理器芯片却大多为ARM、MIPS、PowerPC、DragonBall等系列的微处理器,这就要求在建立好的交叉开发环境中进行交叉编译和链接。,交叉编译器和交叉链接器是能够在宿主机上运行,并且能够生成在目标机上直接运行的二进制代码的编译器和链接器。例如在基于ARM体系结构的gcc交叉开发环境中,arm-linux-gcc是交叉编译器,arm-linux-ld是交叉链接器。,3.1.3 交叉调试器,嵌入式软件经过编译和链接后即进入调试阶段,嵌入式软件开发过程中的交叉调试与通用软件开发过程中的调试方式有所差别。 在通用软件开发中,调试器与被调试的程序往往运行在同一台计算机上,调试器是一个单独运行着的进程,它通过操作系统提供的调试接口来控制被调试的进程。,在嵌入式软件开发中,调试时采用的是在宿主机和

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论