VxWorks操作系统MakeFile
vxWorks开发环境构建步骤及开发资源
vxWorks开发环境构建步骤及开发资源技创科技(Technique Innovator Inc.) 一、Tornado集成开发环境构成Tornado是集成开发环境的名称,主要由帮助及参考文档、操作系统vxWorks、开发工具(编译器、调试器、编辑器、target server等,据统计,挂接在Tornado下的可选工具和第三方有数百个)等三部分构成,分别对应三个目录:i.docs/ 所有文档都集中在该目录中, books.html是根索引,入门级开发请务必查看以下文档:●如果要熟悉使用界面及Tornado使用、创建工程,请参考:Tornado用户手册及Tornado集成开发环境的HELP->content调出来的联机帮助文档;●vxWorks的编译是使用标准GNU Makefile来编译连接的,要了解Makefile语法请参考”GNU Make”;具体的Make rules存放在target/h/make/目录下。
●如何调试?请参考“Debugging with GDB”●vxWorks构成、特点及kernel,编程等:请参考:VxWorks Programmer's Guide,系统调用、库函数接口标准等,请参考:VxWorks Reference Manual●有关BSP(board support package)的构成、初始化、底层驱动等,请参考“BSPReference”●网络应用编程指南(socket编程): “VxWorks Network Programmer's Guide”ii.host/ 该部分存放主机端(开发机)的工具,如Tornado.exe,make.exe,编译器、调试器及TCL命令解释器等等,开发中要用到的工具都存放在目录host\x86-win32\bin 下,部分命令是.exe文件,部分是.bat的,其中有torvars.bat文件,是设置Tornado集成开发环境的环境变量用的,在使用其他工具前,要运行它设置正确的环境变量及可执行文件搜索路径。
VxWork介绍及编程
VxWork介绍及编程一.嵌入式操作系统VxWorks简介VxWorks操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),是嵌入式开发环境的关键组成部分。
良好的持续发展能力、高性能的内核以及友好的用户开发环境,在嵌入式实时操作系统领域占据一席之地。
它以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。
在美国的 F-16、FA-18 战斗机、B-2 隐形轰炸机和爱国者导弹上,甚至连1997年4月在火星表面登陆的火星探测器上也使用到了VxWorks。
WindRiver公司网址实时操作系统和分时操作系统的区别从操作系统能否满足实时性要求来区分,可把操作系统分成分时操作系统和实时操作系统。
分时操作系统按照相等的时间片调度进程轮流运行,分时操作系统由调度程序自动计算进程的优先级,而不是由用户控制进程的优先级。
这样的系统无法实时响应外部异步事件。
实时操作系统能够在限定的时间内执行完所规定的功能,并能在限定的时间内对外部的异步事件作出响应。
分时系统主要应用于科学计算和一般实时性要求不高的场合。
实时性系统主要应用于过程控制、数据采集、通信、多媒体信息处理等对时间敏感的场合。
VxWorks的特点∙可靠性操作系统的用户希望在一个工作稳定,可以信赖的环境中工作,所以操作系统的可靠性是用户首先要考虑的问题。
而稳定、可靠一直是VxWorks的一个突出优点。
自从对中国的销售解禁以来,VxWorks以其良好的可靠性在中国赢得了越来越多的用户。
∙实时性实时性是指能够在限定时间内执行完规定的功能并对外部的异步事件作出响应的能力。
实时性的强弱是以完成规定功能和作出响应时间的长短来衡量的。
VxWorks 的实时性做得非常好,其系统本身的开销很小,进程调度、进程间通信、中断处理等系统公用程序精练而有效,它们造成的延迟很短。
VxWorks操作系统简介
VxWorks操作系统简介VxWorks操作系统简介VxWorks操作系统是一种广泛应用于嵌入式系统开发的实时操作系统。
本文将详细介绍VxWorks操作系统的架构、特性、应用领域以及相关的法律名词注释。
一、VxWorks操作系统架构VxWorks操作系统采用分层架构,包括内核层、中间层以及外围应用层。
具体架构如下:⒈内核层:提供底层的操作系统服务,包括任务管理、内存管理、中断处理、设备驱动等。
内核层使用高度模块化的设计,可以根据需求选择性地加载不同的内核服务。
⒉中间层:提供更高层次的功能,如文件系统、网络协议栈、图形用户界面等。
中间层通过对内核接口的封装,提供更便捷的应用开发接口。
⒊外围应用层:包括用户应用程序和系统管理工具。
用户应用程序可以基于VxWorks操作系统的开发环境进行开发,并且通过内核和中间层提供的接口与系统进行交互。
二、VxWorks操作系统特性VxWorks操作系统有以下特点:⒈实时性:VxWorks操作系统被广泛应用于实时系统开发,具有快速响应、低延迟和可预测性等特性。
它使用了优化的调度算法和中断处理机制,确保系统对实时任务的及时响应。
⒉可靠性:VxWorks操作系统采用了可靠性设计和故障恢复机制,例如内存保护、任务隔离和异常处理等。
这些机制可最大限度地减少系统崩溃和错误的影响。
⒊可扩展性:VxWorks操作系统具有高度可扩展性,可以根据应用的需要进行灵活配置。
开发人员可以根据系统需求选择性地加载所需的内核服务和中间层模块,以达到最佳性能和资源利用。
⒋安全性:VxWorks操作系统提供了多层次的安全机制,包括权限控制、数据加密和访问控制等。
这些机制可以在网络和物理环境中保护系统不受未经授权的访问和攻击。
三、VxWorks操作系统的应用领域VxWorks操作系统在各行各业都有广泛的应用,特别适用于对实时性和可靠性要求较高的领域。
以下是一些典型的应用领域:⒈工业自动化:VxWorks操作系统被广泛用于控制系统和工业领域,如汽车制造、航空航天和机械制造等。
Vxworks虚拟机环境搭建
Vxworks虚拟机环境搭建一、tornado的安装大部分地方默认,部分要注意的地方如下:需要的安装包:[风河VxWorks].WINDRIVER.TORNADO.V2.2.FOR.PENTIUM.CD1.ISO[风河VxWorks].WINDRIVER.TORNADO.V2.2.FOR.PENTIUM.CD2.ISO 虚拟光驱工具:任意DTLite4356-0091.zip (必须通过虚拟光驱来安装)注册序列号:sn_all.txt 见第四条四、WINDRIVER.TORNADO.V2.2.FOR.PENTIUM软件大小:328M安装方法:1)首先安装虚拟光驱软件DAEMON3.22)分别MOUNT 文件夹CD1和CD2下后缀名为BIN的文件3)自动安装后,输入序列号如下:CD1: cAQ8i-qP2I&-g$vT6-3&gjw-bEk9gCD2: A7KbB-Rd37p-hNFBE-kzgaT-b9gpC4)拷贝CRACK目录下的license.dat 到c:\flexlm 目录,如果没有这个目录,自己建一个。
设置如下环境变量:LM_LICENSE_FILE = c:\flexlm\license.dat按装完tornado后,首先要解压vxworks_end.exe文件三次出现target文件夹,将target\h\drv\end\ln97xEnd.h和target\src\drv\end\ln97xEnd.c、Makefile 覆盖对应的问件。
不要全部覆盖。
(其他的config\pc486.972、man文件夹都不要,太旧了。
注意做好整个tornado2.2\target的备份)二安装vxworks:总的过程分为以下几步:1、编译网卡驱动单击windows系统的开始菜单,在“运行”里输入“cmd”打开控制台程序。
进入:D:\tornado2.2\host\x86-win32\bin\运行:torVars.bat;进入:cd D:\tornado2.2\target\src\drv\end目录运行:make CPU=PENTIUM tool=gnu ln97xend.o (这一步会出现重复提示,不要管它,它自己会结束。
嵌入式系统原理与应用习题答案
版权说明本文件中出现的任何文字叙述、文件格式、插图、照片、方法、过程等内容,除另有特别注明,版权均属本人所有。
----WangYiwei由于我正在学习“嵌入式系统原理与应用——基于ARM微处理器和Linux操作系统”这门课程,网络上找不到课后习题答案。
因此本人通过认真地做习题,不懂百度,查阅相关书籍等途径,整理了一份答案,可供各位参考。
注意:答案并不一定完全正确,有异议的答案欢迎提出来大家一起探讨。
练习题P141.选择题(1)A说明:嵌入式系统的发展趋势表现在以下几方面:1.产品种类不断丰富,应用范围不断普及2.产品性能不断提高3.产品功耗不断降低,体积不断缩小4.网络化、智能化程度不断提高5.软件成为影响价格的主要因素(2)D说明:常见的嵌入式操作系统: VxWorks,Windows CE、uC/OS-II和嵌入式Linux。
(3)A说明:VxWorks是美国WindRiver公司于1983年开发的一种32位嵌入式实时操作系统。
2.填空题(1)嵌入式计算机(2)微处理器外围电路外部设备(3)板级支持包实时操作系统应用编程接口应用程序(4)嵌入式处理器微控制器数字信号处理器3.简答题(1)简述嵌入式系统的定义和特点答:定义:以应用为中心,以计算机技术为基础,软硬件可裁剪,应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。
特点:专用性强、实时性好、可裁剪性好、可靠性高和功耗低等。
(2)简述计算机系统的发展历程第一阶段大致在20世纪70年代前后,可以看成是嵌入式系统的萌芽阶段;第二阶段是以嵌入式微处理器为基础,以简单操作系统为核心的嵌入式系统;第三阶段是以嵌入式操作系统为标志的嵌入式系统,也是嵌入式应用开始普及的阶段;第四阶段是以基于Internet为标志的嵌入式系统,这是一个正在迅速发展的阶段。
(3)简述MCU和DSP的区别MCU是微控制器,DSP是数字信号处理器。
MCU相当于小型的电脑,内部集成的CPU、ROM、RAM、I/O总线,所以集成度高是它的特点。
vmware下vxworks6.6安装文档
vmware下vxworks6.6安装⽂档VmWare下跑VxWorks 6.6 教程1、先期准备a)开发环境VxWorks 6.6 for pentium 安装包VmWare WorkStation 7.1.2b)⼯具虚拟软驱RamDiskNT 1.52、虚拟机设置2.1安装虚拟软驱(供虚拟硬盘做DOS,和初期拷贝⽂件使⽤)保证红圈配置正确后,点击START运⾏,随后重启电脑,虚拟软驱A应该就出现了2.2 新建虚拟机File->New->Virtual Machine->Custom->New-Workstation 5->other(other)->指定虚拟机名和保存位置->选单处理器->内存128MB对应VxWorks⾜以->使⽤桥接⽹络(注意:⼀定要使⽤⽹桥连接)->IO适配器选BusLogic->创建虚拟硬盘->类型选择IDE(Recommended) ->磁盘空间设置0.25GB(256MB)⾜以,并勾上⽴刻分配磁盘空间->最终完成虚拟机配置3、FTP引导的bootrom制作修改BSP⾸先,我们复制⼀份纯净未做修改的D:\WindRiver-GPPVE-3.6-IA-Eval\vxworks-6.6\target\config\下的pcPentium3⽂件夹,改名为Pentium3(名称随便你起),再将该改名后⽂件夹放到config⽬录下,最好不要带空格或什么特殊符号。
我们要修改编译bootrom、VxWorks的配置头⽂件Config.h中定义的⼀些参数,使编译出来的系统引导程序bootrom和VxWorks 的映象符合我们的要求;3.1修改config.h1)定位到⽬录D:\WindRiver-GPPVE-3.6-IA-Eval\vxworks-6.6\target\config\Pentium3并打开该⽬录下Config.h⽂件;2)定位到”INCLUDE_CPU_PROBE”,更改成如下:3)查找到定义DEFAULT_BOOT_LINE宏的地⽅,修改预处理条件CPU = = PENTIUM3分⽀下的定义如下:"lnPci(0,0)host: vxWorks h=172.18.101.121 e=172.18.101.124:ffffff00 u=target pw=target tn=target"这⾥的host地址得修改成你的主机地址,target地址只需要在同⼀个⽹段内就可以了4)定位到INCLUDE_ATA,在前⾯⼀句添加#undef INCLUDE_FD,如下所⽰:5)定位到/* Network driver options: VxBus drivers */作如下修改:6)定位到INCLUDE_LN_97X_END,将其定义上,修改如下:7)定位到INCLUDE_PC_CONSOLE,将其设成定义的,如下所⽰8)定位到#if (SYS_WARM_TYPE == SYS_WARM_BIOS),修改如下:3.2修改 configNet.h1)定位到/* max number of END ipAttachments we can have */ 在上⾯添加如下内容:/* Am79C97x (lnPci) driver defines */#ifdef INCLUDE_LN_97X_END#define LN_97X_LOAD_FUNC sysLn97xEndLoad#define LN_97X_BUFF_LOAN TRUE#define LN_97X_LOAD_STR ""IMPORT END_OBJ * LN_97X_LOAD_FUNC (char *, void *);#endif /* INCLUDE_LN_97X_END */截图如下:2)定位到/* Atheros AR521X WLAN Support */在上⾯添加如下内容:#ifdef INCLUDE_LN_97X_END{0, LN_97X_LOAD_FUNC, LN_97X_LOAD_STR, LN_97X_BUFF_LOAN,NULL, FALSE},#endif /* INCLUDE_LN_97X_END */截图如下:3.3 将D:\WindRiver-GPPVE-3.6-IA-Eval\vxworks-6.6\target\src\drv\end⽬录下的ln97xEnd.c拷贝进你的Pentium3⽬录下,并作如下修改:定位到 do {; /* poll for suspend mode entry */}while ((csrLockedRead (pDrvCtrl, CSR(5)) & CSR5_SPND) == 0);添加宏如下所⽰:3.4将5.5的Sysln97xEnd.c移植到你的Pentium3⽬录下,并作如下修改:1)定位到/* map a 4Kb 32-bit non-prefetchable memory address decoder */ 添加如下宏2)定位到ln97xPciResources[ln97XUnits].bar[0] = ioBase;添加如下宏:3.5修改makefile⽂件,作如下修改:1)定位到TOOL = diab将diab修改为gnu2) 定位到EXTRA_DEFINE,作如下修改:3.6修改sysnet.c1)定位到# include "sysUltraEnd.c"添加内容如下:2)定位到LOCAL VEND_ID_DESC vendorIdEnet [] = 修改内容如下:3.7 将安装⽬录下的wrenv.exe拷贝进Pentium3⽬录下,删除如下⽂件:bootrom;bin;bootrom.pxe;vxWorks;vxWorks.st;vxWorks.sym并添加两个⽂件如下:1)torVars.bat内容如下:wrenv -p vxworks-6.62)vxcopy.bat内容如下:objcopypentium -O binary --gap-fill=0 %1 %23.8 编译BootRom往PATH环境变量添加路径,如下所⽰D:\WindRiver-GPPVE-3.6-IA-Eval\vxworks-6.6\host\x86-win32\bin;D:\WindRiver-GPPVE-3.6-IA-Eval\workbench-3.0\x86-win32\bin打开Wind River Workbench 3.0,File->New ->VxWorks BootLloader / BSP Project,填写⼯程名,并选择我们的Pentium3⽂件夹,及⼯具gnu,然后编译:打开CMD,进去⽬录Pentium3⽂件夹,运⾏如下命令mkboot a: bootrom 注意:之间的空格,不然会出错3.9基于BSP创建VxWorks镜像打开Wind River Workbench 3.0,File->New->VxWorks Image Project,还是选择Pentium跟⼯具gnu,然后配置组件FTP Server组件,编译⼯程⽂件3.5开始配置FTP Server1)打开FTP Server->Security -> users/rights -> New User -> ⽤户名跟密码都是vxworks –>在Home Directory 填写你编译好的vxworks image所放置路径,然后选择Done 3.6关闭防⽕墙,设置Vmware从软盘启动,最后运⾏VmWare,然后就能够加载成功了。
嵌入式实时操作系统VxWorks下BSP分析及VxWorks裁减
第15卷 第2期2005年6月天 津 工 程 师 范 学 院 学 报JO URNAL O F T I ANJ I N UN I VERS I TY O F TECHNOLO GY AND ED UCAT I O N Vol .15 No .2Jun .2005嵌入式实时操作系统Vx W orks 下BSP 分析及Vx W orks 裁减3褚 哲,孟小锁(西安微电子技术研究所,陕西西安710075)摘 要:以Vx Works 操作系统为例,阐述了BSP 的概念、原理和系统启动流程,并在此基础上以某目标机为原型,着重叙述了Vx Works 的裁减方法。
关键词:Vx Works;板级支持包;映像中图分类号:TP316.2 文献标识码:A 文章编号:167321018(2005)022*******BSP ana lysis under em bedded rea l 2ti m e opera ti n gsystem Vx W orks and Vx W orks ′t a ilorCHU Zhe,ME NG Xiao 2suo(Xi ′an M icr oelectr onics Technol ogy I nstitute,Xi ′an 710054,China )Abstract :This article takes the Vx Works operating system as an examp le to illustrate the concep t,the p rincirle and the start 2up p r ocedure of BSP .Under this foundation it uses certain target machine as original for m to ex 2p lain the tail or method of Vx Works .Key words :Vx Works;board suppot package;i mage Vx Works 操作系统是美国W indR iver 公司推出的一种嵌入式强实时操作系统,自20世纪80年代问世以来,以其不断推出的升级版本、高性能内核以及友好的用户开发环境,在嵌入式实时操作系统领域逐渐占据一席之地,尤其以成功应用于火星探测车和爱国者导弹等高科技产品而声名鹊起,拥有较多的用户。
Makefile经典教程(最掌握这部分足够---因为汇集全部精华)!!!!!!!!!!
Makefile经典教程0 Makefile概述什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。
这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。
特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。
可见,makefile都成为了一种在工程方面的编译方法。
现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。
当然,不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。
必竟,这个make是应用最为广泛的,也是用得最多的。
而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。
在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。
vxworks命令教程2024新版
文件创建、打开和关闭
创建文件
使用`creat()`函数创建新文件,需要指定文件名和访 问模式。
打开文件
使用`open()`函数打开已存在的文件,同样需要指定 文件名和访问模式。
关闭文件
使用`close()`函数关闭已打开的文件,释放相关资源 。
文件读写操作
01
读取文件
写入文件
02
03
telnet
远程终端服务命令,用于建立TCP连接 并远程登录到目标主机。
ftp
文件传输协议(FTP)命令,用于在网 络上传输文件。
tftpபைடு நூலகம்
简单文件传输协议(TFTP)命令,用 于在网络上进行简单的文件传输。
网络诊断和调试
netstat
网络统计命令,用于显示网络 连接、路由表、接口状态等网
络相关信息。
在嵌入式系统开发中,命令行接口(CLI )是一个不可或缺的工具。通过CLI,开 发者可以与系统进行交互,执行命令,查 看系统状态,调试问题等。
本教程旨在帮助开发者熟悉并掌握 VxWorks的命令行接口,以便更有效地 进行嵌入式系统开发和调试。
教程范围
基本命令介绍
涵盖VxWorks中常用的基本命令, 如任务管理、内存管理、时间管理
ndp
邻居发现协议(NDP)命令,用于 IPv6网络中的邻居发现和管理。
route
用于设置和查看路由表,实现网络数 据包的正确转发。
dhcpc
动态主机配置协议客户端(DHCP Client)命令,用于从DHCP服务器 获取网络配置信息。
数据传输和接收
ping
用于测试网络连接可达性,发送ICMP 回显请求并接收回显应答。
Makefile使用总结
Makefile使⽤总结1. Makefile 简介Makefile 是和 make 命令⼀起配合使⽤的.很多⼤型项⽬的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项⽬中各种库和代码之间的依赖关系不知会多复杂. Makefile的组织流程的能⼒如此之强, 不仅可以⽤来编译项⽬, 还可以⽤来组织我们平时的⼀些⽇常操作. 这个需要⼤家发挥⾃⼰的想象⼒.本篇博客是基于⽽整理的, 有些删减, 追加了⼀些⽰例.⾮常感谢 gunguymadman_cu 提供如此详尽的Makefile介绍, 这正是我⼀直寻找的Makefile中⽂⽂档.1.1 Makefile 主要的 5个部分 (显⽰规则, 隐晦规则, 变量定义, ⽂件指⽰, 注释)Makefile基本格式如下:target ... : prerequisites ...command......其中,target - ⽬标⽂件, 可以是 Object File, 也可以是可执⾏⽂件prerequisites - ⽣成 target 所需要的⽂件或者⽬标command - make需要执⾏的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头1. 显⽰规则 :: 说明如何⽣成⼀个或多个⽬标⽂件(包括⽣成的⽂件, ⽂件的依赖⽂件, ⽣成的命令)2. 隐晦规则 :: make的⾃动推导功能所执⾏的规则3. 变量定义 :: Makefile中定义的变量4. ⽂件指⽰ :: Makefile中引⽤其他Makefile; 指定Makefile中有效部分; 定义⼀个多⾏命令5. 注释 :: Makefile只有⾏注释 "#", 如果要使⽤或者输出"#"字符, 需要进⾏转义, "\#"1.2 GNU make 的⼯作⽅式1. 读⼊主Makefile (主Makefile中可以引⽤其他Makefile)2. 读⼊被include的其他Makefile3. 初始化⽂件中的变量4. 推导隐晦规则, 并分析所有规则5. 为所有的⽬标⽂件创建依赖关系链6. 根据依赖关系, 决定哪些⽬标要重新⽣成7. 执⾏⽣成命令2. Makefile 初级语法2.1 Makefile 规则2.1.1 规则语法规则主要有2部分: 依赖关系和⽣成⽬标的⽅法.语法有以下2种:target ... : prerequisites ...command...或者target ... : prerequisites ; commandcommand...*注* command太长, 可以⽤ "\" 作为换⾏符2.1.2 规则中的通配符* :: 表⽰任意⼀个或多个字符:: 表⽰任意⼀个字符[...] :: ex. [abcd] 表⽰a,b,c,d中任意⼀个字符, [^abcd]表⽰除a,b,c,d以外的字符, [0-9]表⽰ 0~9中任意⼀个数字~ :: 表⽰⽤户的home⽬录2.1.3 路径搜索当⼀个Makefile中涉及到⼤量源⽂件时(这些源⽂件和Makefile极有可能不在同⼀个⽬录中),这时, 最好将源⽂件的路径明确在Makefile中, 便于编译时查找. Makefile中有个特殊的变量VPATH就是完成这个功能的.指定了VPATH之后, 如果当前⽬录中没有找到相应⽂件或依赖的⽂件, Makefile 回到VPATH指定的路径中再去查找.. VPATH使⽤⽅法:vpath <directories> :: 当前⽬录中找不到⽂件时, 就从<directories>中搜索vpath <pattern> <directories> :: 符合<pattern>格式的⽂件, 就从<directories>中搜索vpath <pattern> :: 清除符合<pattern>格式的⽂件搜索路径vpath :: 清除所有已经设置好的⽂件路径# ⽰例1 - 当前⽬录中找不到⽂件时, 按顺序从 src⽬录 ../parent-dir⽬录中查找⽂件VPATH src:../parent-dir# ⽰例2 - .h结尾的⽂件都从 ./header ⽬录中查找VPATH %.h ./header# ⽰例3 - 清除⽰例2中设置的规则VPATH %.h# ⽰例4 - 清除所有VPATH的设置VPATH2.2 Makefile 中的变量2.2.1 变量定义 ( = or := )OBJS = programA.o programB.oOBJS-ADD = $(OBJS) programC.o# 或者OBJS := programA.o programB.oOBJS-ADD := $(OBJS) programC.o其中 = 和 := 的区别在于, := 只能使⽤前⾯定义好的变量, = 可以使⽤后⾯定义的变量测试 =# Makefile内容OBJS2 = $(OBJS1) programC.oOBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使⽤$ makeprogramA.o programB.o programC.o测试 :=# Makefile内容OBJS2 := $(OBJS1) programC.oOBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出 OBJS2 中的 $(OBJS1) 为空$ makeprogramC.o2.2.2 变量替换# Makefile内容SRCS := programA.c programB.c programC.cOBJS := $(SRCS:%.c=%.o)all:@echo "SRCS: " $(SRCS)@echo "OBJS: " $(OBJS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.cOBJS: programA.o programB.o programC.o2.2.3 变量追加值 +=# Makefile内容SRCS := programA.c programB.c programC.cSRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.c programD.c2.2.4 变量覆盖 override作⽤是使 Makefile中定义的变量能够覆盖 make 命令参数中指定的变量语法:override <variable> = <value>override <variable> := <value>override <variable> += <value>下⾯通过⼀个例⼦体会 override 的作⽤:# Makefile内容 (没有⽤override)SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: nothing################################################## Makefile内容 (⽤override)override SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: programA.c programB.c programC.c2.2.5 ⽬标变量作⽤是使变量的作⽤域仅限于这个⽬标(target), ⽽不像之前例⼦中定义的变量, 对整个Makefile都有效.语法:<target ...> :: <variable-assignment><target ...> :: override <variable-assignment> (override作⽤参见变量覆盖的介绍)⽰例:# Makefile 内容SRCS := programA.c programB.c programC.ctarget1: TARGET1-SRCS := programD.ctarget1:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)target2:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)# bash中执⾏make$ make target1SRCS: programA.c programB.c programC.cSRCS: programD.c$ make target2 <-- target2中显⽰不了 $(TARGET1-SRCS)SRCS: programA.c programB.c programC.cSRCS:2.3 Makefile 命令前缀Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不⽤前缀.3种格式的shell命令区别如下:不⽤前缀 :: 输出执⾏的命令以及命令执⾏的结果, 出错的话停⽌执⾏前缀 @ :: 只输出命令执⾏的结果, 出错的话停⽌执⾏前缀 - :: 命令执⾏有错的话, 忽略错误, 继续执⾏⽰例:# Makefile 内容 (不⽤前缀)all:echo"没有前缀"cat this_file_not_existecho"错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 @)all:@echo "没有前缀"@cat this_file_not_exist@echo "错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ make没有前缀 <-- 只有命令执⾏的结果, 不显⽰命令本⾝cat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 -)all:-echo"没有前缀"-cat this_file_not_exist-echo"错误之后的命令" <-- 这条命令会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: [all] Error 1 (ignored)echo"错误之后的命令" <-- 出错之后的命令也会显⽰错误之后的命令 <-- 出错之后的命令也会执⾏2.4 伪⽬标伪⽬标并不是⼀个"⽬标(target)", 不像真正的⽬标那样会⽣成⼀个⽬标⽂件.典型的伪⽬标是 Makefile 中⽤来清理编译过程中中间⽂件的 clean 伪⽬标, ⼀般格式如下: .PHONY: clean <-- 这句没有也⾏, 但是最好加上clean:-rm -f *.o2.5 引⽤其他的 Makefile语法: include <filename> (filename 可以包含通配符和路径)⽰例:# Makefile 内容all:@echo "主 Makefile begin"@make other-all@echo "主 Makefile end"include ./other/Makefile# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 20K-rw-r--r-- 1 wangyubin wangyubin 125 Sep 2316:13 Makefile-rw-r--r-- 1 wangyubin wangyubin 11K Sep 2316:15 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2316:11 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile'主 Makefile end2.6 查看C⽂件的依赖关系写 Makefile 的时候, 需要确定每个⽬标的依赖关系.GNU提供⼀个机制可以查看C代码⽂件依赖那些⽂件, 这样我们在写 Makefile ⽬标的时候就不⽤打开C源码来看其依赖那些⽂件了.⽐如, 下⾯命令显⽰内核源码中 virt/kvm/kvm_main.c 中的依赖关系$ cd virt/kvm/$ gcc -MM kvm_main.ckvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系2.7 make 退出码Makefile的退出码有以下3种:0 :: 表⽰成功执⾏1 :: 表⽰make命令出现了错误2 :: 使⽤了 "-q" 选项, 并且make使得⼀些⽬标不需要更新2.8 指定 Makefile,指定特定⽬标默认执⾏ make 命令时, GNU make在当前⽬录下依次搜索下⾯3个⽂件 "GNUmakefile", "makefile", "Makefile",找到对应⽂件之后, 就开始执⾏此⽂件中的第⼀个⽬标(target). 如果找不到这3个⽂件就报错.⾮默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的⽬标.⽰例:# Makefile⽂件名改为 MyMake, 内容target1:@echo "target [1] begin"@echo "target [1] end"target2:@echo "target [2] begin"@echo "target [2] end"# bash 中执⾏make$ lsMakefile$ mv Makefile MyMake$ lsMyMake$ make <-- 找不到默认的 Makefilemake: *** No targets specified and no makefile found. Stop.$ make -f MyMake <-- 指定特定的Makefiletarget [1] begintarget [1] end$ make -f MyMake target2 <-- 指定特定的⽬标(target)target [2] begintarget [2] end2.9 make 参数介绍make 的参数有很多, 可以通过 make -h 去查看, 下⾯只介绍⼏个我认为⽐较有⽤的.参数含义--debug[=<options>]输出make的调试信息, options 可以是 a, b, v-j --jobs同时运⾏的命令的个数, 也就是多线程执⾏ Makefile-r --no-builtin-rules禁⽌使⽤任何隐含规则-R --no-builtin-variabes禁⽌使⽤任何作⽤于变量上的隐含规则-B --always-make假设所有⽬标都有更新, 即强制重编译2.10 Makefile 隐含规则这⾥只列⼀个和编译C相关的.编译C时,<n>.o 的⽬标会⾃动推导为 <n>.c# Makefile 中main : main.ogcc -o main main.o#会⾃动变为:main : main.ogcc -o main main.omain.o: main.c <-- main.o 这个⽬标是隐含⽣成的gcc -c main.c2.11 隐含规则中的命令变量和命令参数变量2.11.1 命令变量, 书写Makefile可以直接写 shell时⽤这些变量.下⾯只列出⼀些C相关的变量名含义RM rm -fAR arCC ccCXX g++⽰例:# Makefile 内容all:@echo $(RM)@echo $(AR)@echo $(CC)@echo $(CXX)# bash 中执⾏make, 显⽰各个变量的值$ makerm -farccg++2.11.2 命令参数变量变量名含义ARFLAGS AR命令的参数CFLAGS C语⾔编译器的参数CXXFLAGS C++语⾔编译器的参数⽰例: 下⾯以 CFLAGS 为例演⽰# test.c 内容#include <stdio.h>int main(int argc, char *argv[]){printf ("Hello Makefile\n");return 0;}# Makefile 内容test: test.o$(CC) -o test test.o# bash 中⽤make来测试$ lltotal 24K-rw-r--r-- 1 wangyubin wangyubin 69 Sep 2317:31 Makefile-rw-r--r-- 1 wangyubin wangyubin 14K Sep 2319:51 <-- 请忽略这个⽂件-rw-r--r-- 1 wangyubin wangyubin 392 Sep 2317:31 test.c$ makecc -c -o test.o test.ccc -o test test.o <-- 这个是⾃动推导的$ rm -f test test.o$ make CFLAGS=-Wall <-- 命令中加的编译器参数⾃动追加⼊下⾯的编译中了cc -Wall -c -o test.o test.ccc -o test test.o2.12 ⾃动变量Makefile 中很多时候通过⾃动变量来简化书写, 各个⾃动变量的含义如下:⾃动变量含义$@⽬标集合$%当⽬标是函数库⽂件时, 表⽰其中的⽬标⽂件名$<第⼀个依赖⽬标. 如果依赖⽬标是多个, 逐个表⽰依赖⽬标$?⽐⽬标新的依赖⽬标的集合$^所有依赖⽬标的集合, 会去除重复的依赖⽬标$+所有依赖⽬标的集合, 不会去除重复的依赖⽬标$*这个是GNU make特有的, 其它的make不⼀定⽀持3. Makefile ⾼级语法3.1 嵌套Makefile在 Makefile 初级语法中已经提到过引⽤其它 Makefile的⽅法. 这⾥有另⼀种写法, 并且可以向引⽤的其它 Makefile 传递参数.⽰例: (不传递参数, 只是调⽤⼦⽂件夹 other 中的Makefile)# Makefile 内容all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 28K-rw-r--r-- 1 wangyubin wangyubin 104 Sep 2320:43 Makefile-rw-r--r-- 1 wangyubin wangyubin 17K Sep 2320:44 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2320:42 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end⽰例: (⽤export传递参数)# Makefile 内容export VALUE1 := export.c <-- ⽤了 export, 此变量能够传递到 ./other/Makefile 中VALUE2 := no-export.c <-- 此变量不能传递到 ./other/Makefile 中all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "VALUE1: " $(VALUE1)@echo "VALUE2: " $(VALUE2)@echo "other makefile end"# bash中执⾏make$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginVALUE1: export.c <-- VALUE1 传递成功VALUE2: <-- VALUE2 传递失败other makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end*补充* export 语法格式如下:export variable = valueexport variable := valueexport variable += value3.2 定义命令包命令包有点像是个函数, 将连续的相同的命令合成⼀条, 减少 Makefile 中的代码量, 便于以后维护.语法:define <command-name>command...endef⽰例:# Makefile 内容define run-hello-makefile@echo -n "Hello"@echo " Makefile!"@echo "这⾥可以执⾏多条 Shell 命令!"endefall:$(run-hello-makefile)# bash 中运⾏make$ makeHello Makefile!这⾥可以执⾏多条 Shell 命令!3.3 条件判断条件判断的关键字主要有 ifeq ifneq ifdef ifndef语法:<conditional-directive><text-if-true>endif# 或者<conditional-directive><text-if-true>else<text-if-false>endif⽰例: ifeq的例⼦, ifneq和ifeq的使⽤⽅法类似, 就是取反# Makefile 内容all:ifeq ("aa", "bb")@echo "equal"else@echo "not equal"endif# bash 中执⾏make$ makenot equal⽰例: ifdef的例⼦, ifndef和ifdef的使⽤⽅法类似, 就是取反# Makefile 内容SRCS := program.call:ifdef SRCS@echo $(SRCS)else@echo "no SRCS"# bash 中执⾏make$ makeprogram.c3.4 Makefile 中的函数Makefile 中⾃带了⼀些函数, 利⽤这些函数可以简化 Makefile 的编写.函数调⽤语法如下:$(<function> <arguments>)# 或者${<function> <arguments>}<function> 是函数名<arguments> 是函数参数3.4.1 字符串函数字符串替换函数: $(subst <from>,<to>,<text>)功能: 把字符串<text> 中的 <from> 替换为 <to>返回: 替换过的字符串# Makefile 内容all:@echo $(subst t,e,maktfilt) <-- 将t替换为e# bash 中执⾏make$ makemakefile模式字符串替换函数: $(patsubst <pattern>,<replacement>,<text>)功能: 查找<text>中的单词(单词以"空格", "tab", "换⾏"来分割) 是否符合 <pattern>, 符合的话, ⽤ <replacement> 替代.返回: 替换过的字符串# Makefile 内容all:@echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执⾏make$ makeprogramA.o programB.o去空格函数: $(strip <string>)功能: 去掉 <string> 字符串中开头和结尾的空字符返回: 被去掉空格的字符串值# Makefile 内容VAL := " aa bb cc "all:@echo "去除空格前: " $(VAL)@echo "去除空格后: " $(strip $(VAL))# bash 中执⾏make去除空格前: aa bb cc去除空格后: aa bb cc查找字符串函数: $(findstring <find>,<in>)功能: 在字符串 <in> 中查找 <find> 字符串返回: 如果找到, 返回 <find> 字符串, 否则返回空字符串# Makefile 内容VAL := " aa bb cc "all:@echo $(findstring aa,$(VAL))@echo $(findstring ab,$(VAL))# bash 中执⾏make$ makeaa过滤函数: $(filter <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *保留* 符合模式 <pattern> 的单词, 可以有多个模式返回: 符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.o program.a反过滤函数: $(filter-out <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *去除* 符合模式 <pattern> 的单词, 可以有多个模式返回: 不符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.c排序函数: $(sort <list>)功能: 给字符串 <list> 中的单词排序 (升序)返回: 排序后的字符串# Makefile 内容all:@echo $(sort bac abc acb cab)# bash 中执⾏make$ makeabc acb bac cab取单词函数: $(word <n>,<text>)功能: 取字符串 <text> 中的第<n>个单词 (n从1开始)返回: <text> 中的第<n>个单词, 如果<n> ⽐ <text> 中单词个数要⼤, 则返回空字符串# Makefile 内容all:@echo $(word 1,aa bb cc dd)@echo $(word 5,aa bb cc dd)@echo $(word 4,aa bb cc dd)# bash 中执⾏make$ makeaadd取单词串函数: $(wordlist <s>,<e>,<text>)功能: 从字符串<text>中取从<s>开始到<e>的单词串. <s>和<e>是⼀个数字.返回: 从<s>到<e>的字符串# Makefile 内容all:@echo $(wordlist 1,3,aa bb cc dd)@echo $(word 5,6,aa bb cc dd)@echo $(word 2,5,aa bb cc dd)# bash 中执⾏make$ makeaa bb ccbb单词个数统计函数: $(words <text>)功能: 统计字符串 <text> 中单词的个数返回: 单词个数# Makefile 内容all:@echo $(words aa bb cc dd)@echo $(words aabbccdd)@echo $(words )# bash 中执⾏make$ make41⾸单词函数: $(firstword <text>)功能: 取字符串 <text> 中的第⼀个单词返回: 字符串 <text> 中的第⼀个单词# Makefile 内容all:@echo $(firstword aa bb cc dd)@echo $(firstword aabbccdd)@echo $(firstword )# bash 中执⾏make$ makeaaaabbccdd3.4.2 ⽂件名函数取⽬录函数: $(dir <names...>)功能: 从⽂件名序列 <names> 中取出⽬录部分返回: ⽂件名序列 <names> 中的⽬录部分# Makefile 内容all:@echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ make/home/ ./ ../ ./取⽂件函数: $(notdir <names...>)功能: 从⽂件名序列 <names> 中取出⾮⽬录部分返回: ⽂件名序列 <names> 中的⾮⽬录部分# Makefile 内容all:@echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ makea.c bb.cc.cd.c取后缀函数: $(suffix <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的后缀返回: ⽂件名序列 <names> 中各个⽂件名的后缀, 没有后缀则返回空字符串# Makefile 内容all:@echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执⾏make$ make.c .o .a取前缀函数: $(basename <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的前缀返回: ⽂件名序列 <names> 中各个⽂件名的前缀, 没有前缀则返回空字符串# Makefile 内容all:@echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执⾏make$ make/home/a ./b ../c /home/加后缀函数: $(addsuffix <suffix>,<names...>)功能: 把后缀 <suffix> 加到 <names> 中的每个单词后⾯返回: 加过后缀的⽂件名序列# Makefile 内容all:@echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执⾏make$ make/home/a.c b.c ./c.o.c ../d.c.c加前缀函数: $(addprefix <prefix>,<names...>)功能: 把前缀 <prefix> 加到 <names> 中的每个单词前⾯返回: 加过前缀的⽂件名序列# Makefile 内容all:@echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执⾏make$ maketest_/home/a.c test_b.c test_./d.c连接函数: $(join <list1>,<list2>)功能: <list2> 中对应的单词加到 <list1> 后⾯返回: 连接后的字符串# Makefile 内容all:@echo $(join a b c d,1234)@echo $(join a b c d,12345)@echo $(join a b c d e,1234)# bash 中执⾏make$ makea1 b2 c3 d4a1 b2 c3 d4 5a1 b2 c3 d4 e3.4.3 foreach语法:$(foreach <var>,<list>,<text>)⽰例:# Makefile 内容targets := a b c dobjects := $(foreach i,$(targets),$(i).o)all:@echo $(targets)@echo $(objects)# bash 中执⾏make$ makea b c da.ob.oc.od.o3.4.4 if这⾥的if是个函数, 和前⾯的条件判断不⼀样, 前⾯的条件判断属于Makefile的关键字语法:$(if <condition>,<then-part>)$(if <condition>,<then-part>,<else-part>)⽰例:# Makefile 内容val := aobjects := $(if $(val),$(val).o,nothing)no-objects := $(if $(no-val),$(val).o,nothing)all:@echo $(objects)@echo $(no-objects)# bash 中执⾏make$ makea.onothing3.4.5 call - 创建新的参数化函数语法:$(call <expression>,<parm1>,<parm2>,<parm3>...)⽰例:# Makefile 内容log = "====debug====" $(1) "====end===="all:@echo $(call log,"正在 Make")# bash 中执⾏make$ make====debug==== 正在 Make ====end====3.4.6 origin - 判断变量的来源语法:$(origin <variable>)返回值有如下类型:类型含义undefined<variable> 没有定义过default<variable> 是个默认的定义, ⽐如 CC 变量environment<variable> 是个环境变量, 并且 make时没有使⽤ -e 参数file<variable> 定义在Makefile中command line<variable> 定义在命令⾏中override<variable> 被 override 重新定义过automatic<variable> 是⾃动化变量⽰例:# Makefile 内容val-in-file := test-fileoverride val-override := test-overrideall:@echo $(origin not-define) # not-define 没有定义@echo $(origin CC) # CC 是Makefile默认定义的变量@echo $(origin PATH) # PATH 是 bash 环境变量@echo $(origin val-in-file) # 此Makefile中定义的变量@echo $(origin val-in-cmd) # 这个变量会加在make的参数中@echo $(origin val-override) # 此Makefile中定义的override变量@echo $(origin @) # ⾃动变量, 具体前⾯的介绍# bash 中执⾏make$ make val-in-cmd=val-cmdundefineddefaultenvironmentfilecommand lineoverrideautomatic3.4.7 shell语法:$(shell <shell command>)它的作⽤就是执⾏⼀个shell命令, 并将shell命令的结果作为函数的返回.作⽤和 `<shell command>` ⼀样, ` 是反引号3.4.8 make 控制函数产⽣⼀个致命错误: $(error <text ...>)功能: 输出错误信息, 停⽌Makefile的运⾏# Makefile 内容all:$(error there is an error!)@echo "这⾥不会执⾏!"# bash 中执⾏make$ makeMakefile:2: *** there is an error!. Stop.输出警告: $(warning <text ...>)功能: 输出警告信息, Makefile继续运⾏# Makefile 内容all:$(warning there is an warning!)@echo "这⾥会执⾏!"# bash 中执⾏make$ makeMakefile:2: there is an warning!这⾥会执⾏!3.5 Makefile中⼀些GNU约定俗成的伪⽬标如果有过在Linux上, 从源码安装软件的经历的话, 就会对 make clean, make install ⽐较熟悉.像 clean, install 这些伪⽬标, ⼴为⼈知, 不⽤解释就⼤家知道是什么意思了.下⾯列举⼀些常⽤的伪⽬标, 如果在⾃⼰项⽬的Makefile合理使⽤这些伪⽬标的话, 可以让我们⾃⼰的Makefile看起来更专业, 呵呵 :)伪⽬标含义all所有⽬标的⽬标,其功能⼀般是编译所有的⽬标clean删除所有被make创建的⽂件install安装已编译好的程序,其实就是把⽬标可执⾏⽂件拷贝到指定的⽬录中去print列出改变过的源⽂件tar把源程序打包备份. 也就是⼀个tar⽂件dist创建⼀个压缩⽂件, ⼀般是把tar⽂件压成Z⽂件. 或是gz⽂件TAGS更新所有的⽬标, 以备完整地重编译使⽤check 或 test⼀般⽤来测试makefile的流程。
TG-231FQ Vxworks操作系统安装及使用说明
TG-231FQ(带TG-M7扩展板)Vxworks 操作系统安装及使用说明Edit By Linkhope-Lightning2014/6/18第一章开发环境安装和部署第一节Tornado开发环境安装Tornado简介:系统内容TornadoTornado代表嵌入实时应用中最新一代的开发和执行环境。
Tornado 包含三个完整的部分:(1)Tornado系列工具,一套位于主机或目标机上强大的交互式开发工具和使用程序;(2)VxWorks系统,目标板上高性能可扩展的实时操作系统;(3)可选用的连接主机和目标机的通讯软件包如以太网、串行线、在线仿真器或ROM仿真器。
Tornado安装过程:1)先安装daemon虚拟光盘软件;2)使用daemon tool映射(mount)虚拟文件(*.cue,*.bin)(如果没有这两个文件就直接添加iso的压塑包然后点对应的磁盘,进入后点setup.exe文件);3)一路选择默认安装,开始时的key根据DISK_ID的数值输入对应的序列号,name和company可以任意;(key附在文末,查找对应的版本对应的key,分清CD1和CD2)4)一直点击下一步,按默认情况安装,当出现Project Information 向导界面时,Project Name和Number of Tornado Seat 随便填写;5)到最后一步安装license时,选择第三项phone or fax,安装完毕;下面列出主要步骤:图一进入启动后的界面图二点右上角Accept,在点击下一步图三name和company随便输入,Install输入序列号安装的光盘号与序列号如下所示:WINDRIVER.TORNADO.V2.2.FOR.PENTIUMCD1= Tornado 2.2/VxWorks 5.5 for PENTIUM(DISK_ID: TDK-14611-ZC-01)CD2= BSPs/Drivers for VxWorks 5.5: PENTIUM(DISK_ID: TDK-14621-ZC-01)序列号:CD1: cAQ8i-qP2I&-g$vT6-3&gjw-bEk9g序列号:CD2: A7KbB-Rd37p-hNFBE-kzgaT-b9gpC图四Project Name随便输入,Number of Tornado Seat随便输入个数字图五选择安装目录图七选择第三项phone or fax其他图片中没提的步骤选择默认即可。
makefile中make指令
文章标题:深度解析makefile中make指令的功能与作用1. 引言在软件开发过程中,makefile是一个非常重要的工具,它可以帮助程序员自动化构建和管理项目。
而make指令则是makefile中最常用的命令之一,它负责按照一定规则执行makefile中定义的任务,从而大大提高了开发效率。
本文将重点探讨makefile中make指令的功能与作用。
2. make指令的基本概念在makefile中,make指令用于执行makefile中定义的任务,比如编译、信息、生成目标文件等。
它可以根据目标文件的依赖关系和规则,自动识别需要更新的文件,并进行相应的操作。
3. make指令的使用方法在makefile中,make指令的使用方法非常简单,只需要在命令行中输入“make”即可。
当make指令被执行时,它会首先读取makefile中的规则和任务,然后根据规则执行相应的操作,如编译源文件、信息目标文件等。
4. make指令的作用和功能make指令的主要作用是帮助程序员自动构建和管理项目。
通过make 指令,程序员可以方便地对项目进行编译、信息、生成可执行文件等操作,从而减少了手动操作的繁琐和错误率。
5. make指令的深入分析make指令的深度和广度兼具,它不仅可以执行简单的编译操作,还可以根据makefile中定义的规则进行自动化构建、增量编译等高级操作。
这使得程序员能够更加高效地管理和维护项目。
6. 结语总结来说,makefile中的make指令是一个非常强大的工具,它为程序员提供了自动化构建和管理项目的便利。
通过深入探索make指令的功能与作用,我们可以更好地理解makefile的工作原理,进而提高软件开发的效率和质量。
个人观点和理解:作为我的文章写手,我深信make指令在软件开发中的重要性和价值。
它不仅帮助程序员高效地管理和维护项目,还提供了自动化构建的便利。
通过学习和使用make指令,可以更好地理解makefile的机制,从而提高软件开发的效率和质量。
VxWorks操作系统简介
VxWorks操作系统简介VxWorks操作系统简介1.VxWorks操作系统概述VxWorks是一种实时操作系统(RTOS),由美国风险通信公司(Wind River Systems)开发和销售。
它广泛应用于嵌入式系统、网络设备和航空航天等领域,以其高度可靠性、实时性和可定制性而闻名。
2.VxWorks操作系统的特点与优势2.1 实时性能:VxWorks具有优秀的实时性能,能够以微秒级的精确度响应任务,并能够满足各种实时应用的需求。
2.2 可定制性:VxWorks提供了丰富的可定制选项,开发人员可以根据具体需求选择合适的开发环境、编程语言和硬件平台。
2.3 可靠性:VxWorks采用可靠性架构,能够有效地处理系统错误和异常,提供稳定性能与高可靠性。
2.4 安全性:VxWorks支持多层次的安全机制,包括访问控制、数据加密和安全认证等,保护系统免受恶意攻击。
3.VxWorks操作系统的体系结构3.1 内核:VxWorks内核提供了操作系统的核心功能,包括任务调度、内存管理、中断处理等。
它是操作系统与硬件之间的核心接口。
3.2 文件系统:VxWorks支持多种文件系统,包括RAM文件系统、ROM文件系统和网络文件系统等。
这些文件系统可用于数据存储、配置文件管理和软件更新等方面。
3.3 设备驱动程序:VxWorks提供了丰富的设备驱动程序,用于管理和控制外设设备,如串口通信、网络接口和硬盘等。
3.4 网络协议栈:VxWorks内置了多种网络协议栈,包括TCP/IP协议栈和UDP协议栈等,以实现设备间的网络通信。
4.VxWorks操作系统的开发工具4.1 Tornado集成开发环境:Tornado是VxWorks的主要开发工具,提供了图形化界面和一系列的编译、调试和部署工具,简化了开发过程。
4.2 GNU工具链:VxWorks还支持GNU工具链,包括GCC编译器、GDB调试器和Make构建工具等,为开发人员提供更灵活的开发环境。
Makefile
定义
概述
Linux环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序 员,至少不能称得上是 Unix程序员。在 Linux(unix )环境下使用GNU的make工具能够比较容易的构建一个属 于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投 入一些时间去完成一个或者多个称之为Makefile文件的编写。
在 UNIX系统中,习惯使用 Makefile作为 makefile文件。如果要使用其他文件作为 makefile,则可利用 类似下面的 make命令选项指定 makefile文件:
make命令
$ make -f Makefile.debug
Makefile文件工程样例例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件 LS编译生成,这三个文件还分别包含自己的头文件a.h、b.h和c.h。通常情况下,C编译器将会输出三个目标文件 filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件,但filec.c不用。即 在filea.c和fileb.
所要完成的Makefile文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以 及如何编译、需要创建哪些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。尽管看起来 可能是很复杂的事情,但是为工程编写Makefile的好处是能够使用一行命令来完成“自动化编译”,一旦提供一 个(通常对于一个工程来说会是多个)正确的 Makefile。编译整个工程你所要做的事就是在shell提示符下输入 make命令。整个工程完全自动编译,极大提高了效率。
vxWorks文件系统详细介绍
VxWorks为块设备(磁盘)的实时使用提供了两种本地文件系统:一种与MS-DOS文件系统相兼容,另一种与RT-11文件系统相兼容。
这些文件系统的支持库分别为dosFsLib和rt11FsLib。
VxWorks还提供了一种简单的raw文件系统,这个文件系统把整个磁盘作为一个单独的大文件。
这个文件系统的支持库是rawFsLib.VxWorks还为不使用标准文件或目录结构的磁带设备提供了一个文件系统。
磁带卷被看作一个raw设备,整个卷就是一个大文件.这个文件系统的支持库是tapeFsLib。
另外,VxWorks提供了一个文件系统支持库cdromFsLib,它允许应用程序从依照ISO9660标准文件系统格式化的CD-ROMs中读取数据。
在VxWorks中,文件系统不受块设备种类型或它的驱动程序的约束.VxWorks块设备都使用一个标准接口,以便文件系统可以与设备驱动程序自由的混合。
做为选择,你可以写自己的能被驱动程序以相同方式使用的文件系统,只要在文件系统、驱动程序和I/O系统间遵循同样的标准接口。
VxWorks的I/O体系结构使得在一个VxWorks系统中可以有多样的文件系统,甚至其类型也可以不同。
块设备界面在3。
9.4块设备中讨论.1 与MS—DOS兼容的文件系统:dosFs使用dosFs文件系统格式化的磁盘与MS-DOS(直至6.2版本)磁盘是相兼容的。
由两个文件系统初始化的硬盘之间在格式上有细微区别。
然而,数据自身是兼容的,而且dosFs可被配置成使用MS—DOS格式化的磁盘。
DosFs文件系统向不同要求的实时应用程序提供了良好的适应性。
主要特点包括:l 文件和目录分等级排序,允许有效地组织,在一卷上可以创建任意数量的文件。
l 每个文件可以是连续存储或非连续存储的。
非连续存储的文件可使硬盘空间利用率更高,连续存储的文件可以增强系统性能。
l 具有与广泛可用的存储器和可恢复介质的兼容性.应用VxWorks(不使用dosFs文件扩展名)、MS—DOS PCs和其它系统创建的磁盘可以自由的交换.如果分区表被说明,那么硬盘也是兼容的。
在vmware下安装vxworks系统
1。VMware的安装就不说了
2。在VMware里面装2000也不说了
3。在VMware里的2000里装Tonardo2.2/VxWorks5.5 for PC(包括BSP,要有pentium的)更不说了
我的装在了C:\Tornado
4。去AMD下载网卡驱动/us-en/assets/content_type/utilities/u=pentium -march=pentium -ansi -O2 -fvolatile -nostdlib -fno-builtin -fno-d
efer-pop -Wall -I\h -I. -ID:\Tornado2.2\target\config\all -ID:\Tornado2.2\target\h -ID:\
5.2 cd C:\Tornado\target\src\drv\end
5.3 make CPU=PENTIUM tool=gnu ln97xend.o (discard warnings, wabc said it's ok)
5.4 copy ln97xend.o C:\target\lib\pentium\PENTIUM\common
怒发冲冠。
不过对于我这个半吊子工程,想要舒舒服服的把VxWorks在VMware一次or几次(<10)上跑起来
是比较yy的,事实证明我不能yy。幸好在这个家(自从迷上Embeded,我就把这里当作Embeded的家
了)里面,高手如云(wabc,adaye2003,kala...),而且古道热肠,终于让我云破天开。
11 再启动刚建的虚拟机,是不是可以load image,然后看到VxWorks的Logo了 :)
贪心不足,又想接着搞硬盘启动,硬盘加载,参考了很多贴子,还是load不了,只能到这一步,望大虾支招啊
海思makefile结构解析
海思makefile结构解析全文共四篇示例,供读者参考第一篇示例:海思芯片是一家领先的半导体公司,在国际市场上拥有广泛的市场份额。
海思芯片的产品广泛应用在手机、网络通信、物联网、智能家居等领域,其芯片性能卓越,在同行业内享有很高的声誉。
在海思芯片的开发中,makefile是一个非常重要的工具,它负责管理整个项目的编译、链接和部署过程,帮助开发人员更高效地完成工作。
makefile是一个用于自动化编译的脚本文件,通过编写makefile 文件,可以告诉计算机如何编译源代码,生成可执行文件。
海思makefile结构解析主要包括以下几个部分:1. 定义变量:在makefile中定义变量是非常重要的,可以方便地管理项目的路径、编译参数等信息。
海思makefile中通常会定义一些常用的变量,比如CC表示编译器的路径,CXX表示C++编译器的路径,CFLAGS表示编译参数等。
通过定义这些变量,可以在整个makefile中直接引用,减少了代码的冗余,提高了代码的可维护性。
2. 设置编译规则:在makefile中,通常会定义一些编译规则,告诉make工具如何编译源文件和生成可执行文件。
海思makefile中的编译规则通常使用模式匹配的方式,比如"%.c:%.o"表示将所有的.c文件编译为.o文件,而"%.o:%.c"则表示将所有的.o文件根据对应的.c文件进行重新编译。
通过这些编译规则,make工具可以根据需要自动化地完成整个项目的编译过程。
3. 定义目标:在makefile中通常会定义一些目标,这些目标可以是编译生成可执行文件的命令,也可以是清理生成的临时文件的命令。
海思makefile中的目标通常包括all、clean、install等,通过定义这些目标,可以方便地管理整个项目的编译和部署过程。
4. 调用外部工具:在海思makefile中,通常会调用一些外部工具来完成一些特定的任务,比如编译器、链接器、打包工具等。
Vxworks的文档
Vxworks的文档Create by zaken 06-11-6Tornado的安装:1.1 进入WINDRIVER.TORNADO.V2.2.FOR.POWERPC.CD1目录,运行setup.exe1.2 KEY=TcS5i-Zq%J+-4XVu#-3&bjv-M63&g1.3 安装完毕后拷贝license.dat到c:\flexlm目录,该license.dat内容如下FEATURE tornado2 wrsd 2.2 permanent uncounted HOSTID=ANY \ISSUER=RORiSO SIGN=CBB253963374FEATURE windview2 wrsd 2.2 permanent uncounted HOSTID=ANY \ISSUER=RORiSO SIGN=B2D1B8162764FEATURE DIAB_PPC wrsd 5.0 permanent uncounted HOSTID=ANY \ISSUER=RORiSO SIGN=A8F5FB26AC001.4 设置环境变量LM_LICENSE_FILE = c:\flexlm\license.dat1.5 安装mpc827x BSP补丁2. 如何配置SIMNT调试环境2.1 设置环境变量CPU=SIMNT2.2 如果vxsim无法启动,在注册表内查找KB917422,找到后在运行框内输入卸载这个补丁2.3 建新工程,选择编译器为simnt gnu,编译成*.out即可下载(如果有杀毒软件必须关掉)Tornado的使用:参看《VxWorks开发指南和Tornado实用手册》电力出版社BSP的基础:1.导入:在tornado下新建一个VxWorks工程,在Step2选择从BSP导入。
2.Tornado/Target/Config/All目录下的文件Config_all.h 文件:所有VxWorks映像的默认配置。
VxWorks简介
VxWork BSP 和启动过程开发BSP 主要的两点:系统image 的生成,image 的种类,image 的download 下载过程,系统的启动顺序和过程,调试环境的配置及远端调试的方式和方法,相应BSP 设置文件的修改(网络,串口..),BSP 各文件的组成和作用.要对系统底层驱动清楚,也就是对CPU 及相关的硬件有所了解.主要是32微处理器(上电启动过程, download image 的方式方法,读写ROM,地址空间分配,MMU,寄存器,中断定义,..).参照硬件资料,多读一些源码会有所帮助.Tornado 2 开发调试环境协议框图 主机开发(Host Development System) 目标机(Target System)Tornado 工具WTX 协议通信<==========> Editor Project S h e l lDebug g e r B r o w s erWindviTargetServer|Target Agent VxWor ks Target Simulat or WDB 协议通信 <==========> Application VxWorks OS VxWorks Target (WDB )Agentew两个主要两个协议WTX协议(Wind River Tool eXchange): 用于开发机内部Tornado工具与Target Server之间通信.WDB协议(Wind DeBug): 用于主机Target Server与目标机之间的通信.一.基本概念BSP定义:Provides VxWorks with primary interface to hardware environment.作用:在通电后,初始化硬件.支持VxWorks和硬件驱动通信.使hardware-dependent 和hardware-independent在VxWorks系统中很好的结合.主要BSP主要文件目录的组成及主要文件的作用:目录target/config/All:这个目录下的文件是所有BSP文件共享的,不是特别需要不要更改里面的任何文件. configAll.h:缺省定义了所有VxWorks的设置.如果不用缺省的设置,可在BSP目录下的config.h文件中用#define或#undef方式来更改设置.bootInit.c:在romInit.s后,完成Boot ROM的第二步初始化.程序从romInit.s中的romInit()跳到这个文件中的romStart().来执行必要的解压和ROM image的放置.bootConfig.c:完成Boot ROM image的初始化和控制.usrConfig.c: VxWorks image的初始化代码.目录target/config/comps/src:涉及系统核心的components,主要由target/config/All中usrConfig.c中函数调用目录target/config/bspname:包含系统或硬件相关的BSP文件.Makefile一些命令行控制images的生成,参见BSP设置部分及生成下载READMEBSP发布纪录,版本,总的文档config.h包括所有涉及CPU主板的设置及定义(includes,definations),参见BSP设置文件及生成下载configNet.h网络驱动的主要设置文件,主要对END驱动设置.romInit.s汇编语言文件,是VxWorks Boot ROM和ROM based image的入口,参见系统启动部分sysALib.s汇编语言文件,程序员可以把自己的汇编函数放在这个文件里,在上层调用.VxWorks image的入口点_sysInit在这个文件里,是在RAM中执行的第一个函数.sysLib.c包含一些系统相关的函数例程,提供了一个board-level的接口,VxWorks和应用程序可以以system-indepent的方式生成.这个文件还能包含目录target/config/comps/src的驱动. sysScsi.c可选文件用于Scsi设备设置和初始化.sysSerial.c可选文件用于所有的串口设置和初始化.bootrom.hexASIC文件包含VxWorks Boot ROM代码VxWorks运行在目标机上,完整的,连结后的VxWorks二进制文件.VxWorks.sym完全的,连结后带有符号表的VxWorks二进制文件VxWorks.st完全的,连结后,standalone,带有符号表的VxWorks二进制文件BSP用"make"来编译连接生成(Created),而不是用Tornado的工具.BSP和应用程序都可以在"make"或"tornade"上开发(developed)BSP被设置包括以下驱动:中断控制interrupt controller,计时器timer(sys/aux),串口UART(serial),显示屏LCD,键盘Keyboard(opt),触摸屏touch-screen(opt).前面三个是BSP的主要部分.BSP默认的download VxWorks RAM image方式是从ethernet.串口电缆需要用来和开发板(COM1)通信,通过协议WDB.VxWorks Image的种类:Loadable images.ROM-based images---compressed/uncompressed.ROM-Resident images.ROM-resident image 对一些系统内存RAM资源较少的情况下,为了节省资源,只拷贝image 中的数据部分(data segment)到内存RAM,留下程序部分(text segment)在ROM中执行。
vxWorks的BSP开发
VxWorks的BSP开发➢BSP概述一个成熟的商用操作系统,其被广泛应用的必要条件之一就是能够支持众多的硬件平台,并实现应用程序的硬件无关性。
一般来说,这种无关性都是由操作系统实现的。
但对于嵌入式系统来说,它没有像PC机那样具有广泛使用的各种工业标准,各种嵌入式系统其不同的应用需求就决定了它一般都选用了各自定制的硬件环境,这种诸多变化硬件的环境就决定了无法完全由操作系统来实现上层软件与底层硬件之间的无关性。
因此各种商用实时操作系统,都采用了分层设计的方法,它将系统中与硬件直接相关的一层软件独立出来,称之为Board Support Package即简称BSP。
顾名思义,BSP是针对某个单板而设计的,并且它对于用户(指开发者)也是开放的,用户可以根据不同的硬件需求对其作改动或二次开发,而操作系统本身仅仅提供了CPU内核的无关性。
BSP在系统中的角色,很相似于BIOS在PC系统中的地位。
定义BSP就是为软件操作系统正常运行提供最基本、最原始的硬件操作的软件模块,它和操作系统息息相关,但又不属于操作系统的一部分。
BSP可以分为三大部分:1:系统上电时的硬件初始化。
2:为操作系统访问硬件驱动程序提供支持。
3:集成的硬件相关和硬件无关的操作系统所需的软件模块.BSP的表现形式BSP主要以两种形式来表现:1:源代码(C代码、汇编代码)、系统编译连接依靠文件。
2:二进制的目标代码和目标代码库。
BSP在软件系统中的位置BSP在软件系统中的位置可以用下图来表示,BSP为操作系统和硬件设备的互操作建了一个桥梁,操作系统通过BSP来完成对指定硬件的配置和管理.2 vxWorks系统中的BSP 目录结构BSP软件与其他软件的最大区别在于BSP软件有一整套模板和格式,开发人员必须严格遵守,不允许任意发挥.在BSP软件中,绝大部分文件的文件名和所要完成的功能都是固定的。
所以,BSP软件的开发一般来说都是在一个基本成型的BSP软件上进行修改,以适应不同单板的需求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VxWorks操作系统MakeFile(一)时间:2008-8-24 夜版权申明:本文为水煮鱼为水煮鱼@博客园撰写,不得用于商业用途,如需摘用,请与水煮鱼联系。
1、介绍本文将介绍为什么要将你的C源代码分离成几个合理的独立文档,什么时候需要拆分,那又怎么拆分呢?然后再介绍如何使用GUN Make使你的编译和链接步骤自动化。
可能你使用的是其他的make工具,但是其实道理都差不多。
当然如果你对自己的编程工具有怀疑的话,可以不妨实际的试试。
2、多文件项目介绍a. why?为什么使用多文件项目?他们有什么好处呢?从表面上看,多文件项目是够复杂的了,又要头文件,又需要extern申明,并且如果你要查找一个文件的话,还需要在更多的文件里搜索。
但是如果把其考虑成一个项目,那一个项目根据功能划分为小的模块,那就不难理解了。
想想如果是一个一万行代码,如果你把其放到一个文件里,则在编译的时候,则需要对一万行代码进行重新编译。
不过如果你如果把其放到不同的文件里,那修改一行,则只需要编译一个文件就可以了。
可能你会说,一万行代码,就算全部编译,那点时间也基本可以忽略不计,但是实际情况是,在一个大的系统里,可能代码达到几十万甚至上百万,千万行代码的规模。
以我们的项目为例,目前代码规模已经达到了上千万行的级别,如果全部重新编译,则将耗费几个小时甚至半天的时间。
如果将其划分多多个文件,则修改一行所引入的编译代码,将不会随着你代码规模的增大而增大。
所以多个文件的优点不言自明了。
不过对于不便于搜索的问题,其实只要文件划分得当,也并不会造成多大的困难。
其实,从多个目标文件生成一个程序包比从一个单一文件生成程序包要好的多。
当然,实际上这是不是一个优势还与你所使用的系统有关。
但是当使用gcc/ld(一个GUN C编译器/连接器)把一个程序包连接到一个程序时,在连接的过程中,它会尝试不去连接没有使用到的部分,但它每次只能从程序包中把一个完整的目标文件排除在外。
因此,如果你修改了一个程序包中某一个目标文档中任何一个符号的话,那么这个目标文件整个都会被连接进来。
要是一个程序包被非常充分的分解的话,那么经过链接后,得到的可执行文件会比从一个大目标文件组成的程序包连接得到的文件小的多。
并且常常我们的程序是模块化的,高内聚,低耦合,使得文件之间共享部分被减少到了最少,因此采用多文件的方式,可以比较容易的找到代码中的bug。
b.when?那什么时候分解你的项目?如果你开发的是一个大项目,在开始前,应该好好考虑一下你将如何实现,并且将生成几个文件来存放你的代码。
当然,在项目的开发过程中,你可以建立新的我文件,但是这将打乱你的整体布局,可能造成你整体结构的调整。
因此特别建议在做之前,需要想想细细的考虑清楚,开发过程中允许有小范围的调节,但是涉及到整体结构的修改,将为你的项目引入过多的风险。
如果你开发的是一个中型的项目,你可以向上面介绍的那样,想清楚了再开始动手,但是你也可以想当然的写到哪就到哪,当你发现你的代码已经多到难以管理的时候在进行分解,但是希望你尽量先有一个好的谋局后,再动手,你将花费的代码最小。
c.how?如何分解呢?一下仅仅是个人的建议,如果你有自己的风格的话,如果你认为更好,那请保持你原来的做法:i. 不用使用一个header指向多个源代码。
使用一个头文件对应一个源代码文件,不仅更容易查询,方便代码的阅读,而且,无需修改一个头文件,而引起更多的文件的重新编译。
ii.如果可以的话,推荐采用多个头文件指向一个源代码文件的方式。
有时将不可公开调用的函数原型,类型定义等,从它们的C源嗲吗文件中分离出来是非常有用的。
可以使用一个库文件装共用的变量,而使用另外一个库文件装私用的变量,这样不会导致你修改源代码文件的内部结构时,你只需要重新编译这个源代码文件,而无需重新编译调用了公开的库文件的其他源代码。
iii.不要再多个库文件中重复定义。
这个不说,大家应该都知道为什么了。
iv. 在每一个源代码文件中,#include那些申明了源代码符号的所有头文件。
这样一来,你在源文件和头文件对某些函数做出的矛盾声明就可以比较容易的被编译器发现。
编译中常见的一些错误:1、定义符在源码文件中的矛盾。
在C语言里,变量和函数的缺省状态是公用的。
因此任何C源码的文件都可以引用存在于其他源码文件中的全局函数和全局变量,即使在这个源码文件中,并没有该全局函数或者全局变量的声明或者原型。
因此你必须保证在你的全局函数或者全局变量没有重复的定义,否则在连接的时候会出现错误,可能在编译的时候也会提示告警。
解决方法:一种有效的解决方法,就是在你申明的全局函数或者全局变量名前,加入一个可以区分文件的前缀名:比如如果在gfx.c里的函数完全就可以加上前缀名gfx_。
如果要防止一个符号在它被定义的源文件以外看到,可以在它的定义前加上关键字“static", 则该关键字定义了该符号的局部属性,仅能在定义的文件内使用。
(请注意,改关键字”static“的使用与局部变量定义时的区别)。
2、多次定义的符号。
当你用#include包含一个库文件的时候,实际上在编译的时候仅仅是在该处使用你包含的库文件逐字替换。
如果头文件被#include到多个文档中时,该头文件中的所有定义都会在你引用的源代码中重新定义一次。
重复定义,会导致链接出现错误。
解决方法:不要在头文件中定义变量。
定义变量一般放到使用他们的源码问文件中,而在其他文件中声明一下就可以了。
对于初学者来说,定义和声明,总是容易混淆。
定义的时候,编译器会给该变量分配实际的内存空间,而声明,仅仅是通知编译器该变量存在,并且告知该变量的类型。
声明一个变量的时候,需要在它的前面加上extern的关键字。
由于函数的原型中已经有了隐式的extern,所以不要考虑该问题。
3、重复定义、重复声明或者类型矛盾考虑如果你的源码文件中#include了头文件a.h和b.h,但是你的头文件中a.h又包含了b.h,则编译的时候会出现什么结果呢?很明显,b.h中定义的宏或者声明都会被执行两次。
从理论上讲,这样的重复都是完全一样的拷贝,不会出现问题,但是在实际的编译中,这是不符合C的基本语法,可鞥编译的时候会出现错误,至少也是一个告警。
解决办法:确定每一个头文件中在任何一个源码文件中仅仅包含了一次。
但是随着代码规模的扩大,通过认为控制的手段实在有点低效。
聪明的方法是使用预处理器。
常用的用法是:#ifndef MACRO_XXXX#define MACRO_XXXX XXXX#endif但是如果每一个宏都这么放一条,是不是显得也太低效了呢?(还不说,我还真的看到了这么做的,呵呵!!)在实际的应用中,我们只需在头文件的开头处定义:#ifndef FILENAME_H#define FILENAME_H在库文件的最后处定义:#endif使用库文件的文档名代替上面的FILENAME就可以了Makefile的结构:一般编译的步骤为:1、将每一个单独的源代码文件首先编译成为目标文件。
2、通过链接器,将目标文件连接成为可执行文件。
由于本文只讨论vxworks中的makefile,因此本文主要以常用的gcc为例。
通过-c开关,可以使用gcc将源文件编译成为期望的目标文件。
生成文件以.o为后缀名。
然后通过命令gcc -o exec_filename *.o,将生成的目标文件连接成为可执行文件。
在gcc中,生成的可执行文件以.out为后缀名。
对于一个多文件的项目,这些非常繁琐。
但是GNU Make工具让一切都可以变得很简单。
GUN Make的输入是一个文本文件:makefile。
在这个文件中,主要描述了目的文件是从那些依靠文件中产生的关联关系。
根据文本中描述的关系,make通过检查磁盘上的文件,如果目的文件的时间戳比至少它一个依靠文件的时间戳旧的话,make工具将执行相应的命令,以更新目的文件。
一个makefile主要含有以下的规则::....(tab)<command>(tab)<command>...例:====make file 开始====myprog:foo.o bar.ogcc foo.o bar.o -o myprogfoo.o: foo.c foo.h bar.hgcc -c foo.c -o foo.obar.o: bar.c bar.hgcc -c bar.c -o bar.o====make file 结束====这是一个非常典型的makefile。
make从最上面开始,把上面第一个目的, "myprog",作为它的主要目标。
给出跪着说明只要文件"myprog"比文件"foo.o"或者"bar.o"中的任何一个旧,则下一行命令将会被执行。
但是在检查文件foo.o和bar.o的文件戳之前,它会往下查找那些把foo.o或者bar.o 作为目标文件的规则,以此递归,直到找到最新的目标文件,并执行该目标文件下的命令。
从此可以看出,make工具通过这种递归查找最新时间戳的方式,保证当你修改任何代码的时候(可能是只有修改了一个源码文件,或者一个头文件),保证与之关联的文件都可以被编译。
当然,你必须保证你在makefile中写的编译规则,都是正确的,只列出了那些在源码文件中被包括的头文件。
编写Make的规则:通过上节的介绍,知道了怎么去生成一个makefile文件。
当文件较少的时候,采用上述的方法是可行的。
但是随着文件数目的增加,已经各个文件相互依赖关系变复杂以后,以上生成makefile的方式已经不再具有可行性了。
幸好很多编译器都具有自动生成makefile的功能。
以gcc为例:打开-m开关,则gcc 可以将你输入的C文件,根据其中包含的头文件自动生成依赖文件。
注意,如果采用-mm的方式,采用“<”,“>”方式包含的头文件将不生成依赖文件。
通过gcc生成的makefile,不会包含命令部分,该部分你可以自己补充,或者直接使用它的隐藏规则。
为了便于编写makefile文件,下面将具体介绍生成的makefile文件中的一些基本概念:1、makefile变量makefile变量类似于环境变量,起对大小写敏感,一般使用大写字母表示,它可以在任何地方引用,主要具有如下的功能:a. 用于存储文件列表名。
生成可执行文件的makefile,需要指定一些目标文件作为依赖文件;或者在命令行部分,需要会执行那些文件作为gcc命令的输入文件,通过变量的方式来存储这些文件名,更便于makefile的维护;b.用于存储可执行文件名。
如果你使用的是一个非gcc的编译器,则可能你需要修改所有命令行的使用的gcc的编译名部分,你可以定义一个变量保存编译器名称,则当编译器不同时,简单的修改该变量名称从而实现对不同编译器的命令的整体替代修改。