上嵌网院讲师:杨行系列课程—Linux基础多模块编译和链接第七章上嵌网院课程目标具备搭建linux系统平台能力•系统安装具备Linux系统日常维护能力•文件,目录结构•linux的常用命令,Vi•Shell脚本编程、管道及其重定向•tftp,nfs服务器的配置熟悉Linux系统下的开发环境•Gcc,Gdb上嵌网院课程安排第一天上午:Linux系统简介和安装下午:Linux安装实际演练第二天上午:Linux基本操作命令下午:Linux基本操作命令实战第三天上午:Linux进程操作下午:Linux服务器配置第四天上午:Linux脚本编程上下午:Linux脚本编程下第五天上午:源代码编译和调试下午:多模块软件的编译和链接(预科内容,根据实际情况调整授课天数,4-10天)上嵌网院课前提问Make–f文件,是什么文件?目标类表:关联性列表含义是什么?如何定义简单变量?举一个make内置变量的例子上嵌网院本章目标Make实用程序的功能使用makefile管理多模块软件makefile的规则,变量makefile的虚目标规则Makefile常见错误和调试上嵌网院•实用的软件都是拥有多个源文件–这些源文件称之为模块–多模块软件•多模块软件优点缺点较小的程序文件易于维护知道所有文件的依赖性只需编译经过修改的源文件,而不是编译整个系统跟踪所有文件修改的时间戳支持信息隐藏必须键入很长的命令行知识点1-Make上嵌网院•一个差强人意的办法–使用shell脚本•上述的缺点,导致了make的产生。$catbuild.scgcc–cprog1.cprog2.cprog3.cgcc–oprogprog1.oprog2.oprog3.oMake上嵌网院工程管理器,顾名思义,是指管理较多的文件Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能构根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件文件的内容来执行大量的编译工作Make将只编译改动的代码文件,而不用完全编译。Make上嵌网院•管理多模块程序的编译和连接•读取一个说明文件---Makefile–描述系统中各模块的依赖关系•make使重编译的次数达到最小化–Makefile描述的依赖关系–各组件文件的时间戳•Makefile实质上是一种脚本语言Make上嵌网院[选项][目标][宏定义]目的Make程序更新文件是基于存放在一个文件中的依赖关系,称为Makefile。Make上嵌网院文件指定从哪个文件中读取依赖关系信息。默认文件是”Makefile”或“makefile”“-”表示从标准输入-h显示所有选项的简要说明-n不运行任何Makefile命令,只显示他们-s安静的方式运行,不显示任何信息Make上嵌网院—Makefile文件•Makefile是Make读入的唯一配置文件–由make工具创建的目标体(target),通常是目标文件或可执行文件–要创建的目标体所依赖的文件(dependency_file)–创建每个目标体时需要运行的命令(command)–注意:命令行前面必须是一个”TAB键”,否则编译错误为:***missingseparator.Stop.上嵌网院目标列表:关联性列表Tab命令列表目标列表:关联性列表;命令列表也称为先决条件Makefile文件Makefile格式1target:dependency_filesTABcommand例子hello.o:hello.chello.hgcc–chello.c–ohello.o•Makefile格式2target:dependency_files;command•例子hello.o:hello.chello.h;gcc–chello.c–ohello.o上嵌网院•注释–#•连接符–\•关联列表和命令列表中使用shell通配符–?–*–[…]与shell脚本的相同Makefile文件上嵌网院•实例源码power.c#includemath.h#includestdio.hVoidmain(){floatx,y;printf(theprogramtakexandfromstdinanddisplaysx^y.\n);printf(enternumberx:);scanf(%f,&x);printf(enternumbery:);scanf(%f,&y);printf(x^yis%6.3f\n,pow((double)x,(double)y));}$catMakefile#Samplemakefileforthepowerprogram#Remember:eachcommandlinestartswithaTABpower:power.cgccpower.c-opower–lm$制表符TabMakefile文件上嵌网院•把power.c分成两个文件#includestdio.hdoublecompute(doublex,doubley);main(){floatx,y;printf(theprogramtakexandfromstdinanddisplaysx^y.\n);printf(enternumberx:);scanf(%f,&x);printf(enternumbery:);scanf(%f,&y);printf(x^yis%6.3f\n,compute(x,y));}#includemath.hdoublecompute(doublex,doubley){return(pow((double)x,(double)y));}Makefile文件上嵌网院:power.ocompute.ogccpower.ocompute.o-opower-lmMakefile文件-依赖树上嵌网院:power.ocompute.ogccpower.ocompute.o-opower-lmpower.o:power.cgcc–cpower.ccompute.o:compute.cgcc–ccompute.cpower.ccompute.c$makegcc-cpower.cgcc-ccompute.cgccpower.ocompute.o-opower—lm树中节点的处理是自底向上的,由叶结点的父节点开始Makefile文件-依赖树上嵌网院•当目标文件比关联文件更新•更新关联文件,对比$makemake:’power’isuptodate$touchpower.C$makegccpower.c–opower–lm仅仅只更新文件的修改时间为当前时间目标文件存在,且比关联文件更新重新编译更新的关联文件Makefile文件上嵌网院•进一步分成六个文件,建立依赖树$catcompute.c#includemath.h#include”compute.h”doublecompute(doublex,doubley){return(pow((double)x,(double)y));}$catmain.h/*Declarationofpromptstousers*/constchar*PROMPTl=”Enterthevalueofx:”;constchar*PROMPT2=”Enterthevalueofy:”;$catinput.C#include”input.h”doubleinput(constchar*s){floatx;printf(”%s”,s);scanf(“%f”,&x);return(x);}$catinput.h/*Declarationofthe”input”function*/doubleinput(char*);catcompute.h/*Declarationofthe“compute”function*/doublecompute(double,double);Makefile文件-依赖树上嵌网院.c#includestdio.h#include”main.h”#include”compute.h”#include”input.h”main(){doublex,y;printf(”TheprogramtakesXandYfromstdinanddisplaysx^y.\n”);x=input(PROMPTl);y=input(PROMPT2);printf(”x^yis:%6.3f\n”,compute(x,y));}Makefile文件-依赖树上嵌网院:main.oinput.ocompute.ogccmain.oinput.ocompute.o-opower-1mmain.o:main.cmain.hinput.hcompute.hgcc-cmain.cinput.o:input.cinput.hgcc-cinput.ccompute.o:compute.ccompute.hgcc-ccompute.c$$makegcc-cmain.cgcc-cinput.cgcc-ccompute.cgccmain.oinput.ocompute.o-opower-1m1.第一个先决条件不存在,或者先决条件作为目标文件的先决条件更新。生成第一个2.当所有的先决条件更新后,生成最终目标文件Makefile文件-依赖树上嵌网院:$(CC)$(CFLAGS)-c$.s.o:$(AS)$(ASFLAGS)-o$@$-默认的模式规则(gnuMake)%.o:%.c:$(CC)$(CFLAGS)-c$%.o:%.s$(AS)$(ASFLAGS)-o$@$-利用默认的规则修改后的makefile$catmakefilepower:main.oinput.ocompute.ogccmain.oinput.ocompute.o-opower-lmmain.o:main.hinput.hcompute.hinput.o:input.hcompute.o:compute.h内置变量,以后会经常遇到知识点3-Makefile的规则和变量上嵌网院的规则和变量•一个复杂一些的例子sunq:kang.oyul.ogcckang.obar.o-omyprogkang.o:kang.ckang.hhead.hgcc–Wall–O-g–ckang.c-okang.oyul.o:bar.chead.hgcc-Wall–O-g–cyul.c-oyul.o注释:-Wall:表示允许发出gcc所有有用的报警信息.-c:只是编译不链接,生成目标文件”.