Makefile文件简介

  • 蓝蓝的天
  • LV5工程师
  • |      2016-06-15 17:37:41
  • 浏览量 790
  • 回复:7
本帖最后由 HelloWii 于 2016-6-15 20:51 编辑 使用GCC的命令行进行程序编译在单个文件下是比较方便的,当工程中的文件逐渐 增多,甚至变的十分庞大的时候,使用GCC命令编译就会变的力不从心。Linux中的 make工具提供了一种管理工程的功能,可以方便的进行程序的编译,对更新的文件进行 重新编译。 一个多文件的工程例子: 有一个工程共有5个源文件,在add目录中有add_int.c和add-float.c,两个文件分别 计算整形和浮点型的相加;在sub目录下有文件sub_int.c和sub_float.c,分别计算 整形和浮点型的相减;顶层目录有main.c文件负责整个程序。 工程中的代码分别存放在add/add_int.c,add/add_float.c,add/add.h,sub/sub_int.c, sub/sub_float.c,sub/sub.h,和main.c中。 文件main.c 文件main.c的代码如下。在main()函数中调用整数、浮点的加减运算函数进行数值计算。 加操作: 文件add.h的代码如下,包含整数和浮点数的求和函数声明。 文件add_float.c的代码如下,函数add_float()进行浮点型数值的相加计算。 文件add_init.c的代码如下,函数add_int()进行整数型数值的相加计算。 减操作: 文件sub.h的代码如下,包含整数和浮点数的相减函数声明: 文件sub_int.c的代码如下,函数sub_int()进行整形的相减计算。 文件sub_float.c的代码如下,函数sub_float()进行浮点型的相减计算。
  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:2
zhangsf_chongza 2016-06-15
给你个赞,呵呵 
0   回复
举报
发布
蓝蓝的天 回复 2016-06-16
谢谢
0   回复
举报
蓝蓝的天 回复 2016-06-16
本帖最后由 蓝蓝的天 于 2016-6-16 08:49 编辑 Makefile中使用变量: 在前面讲的Makefile中,生成cacu的规则如下: 生成cacu的时候,多次使用同一组.o目标文件:在cacu规则的依赖项中出现一次, 在生成cacu执行文件的时候又出现一次。直接使用文件名进行书写的方法不仅 书写起来麻烦,而且进行增加或者删除文件时容易遗忘。 Makefile中的用户自定义变量: 使用Makefile进行规则定义的时候,用户可以定义自己的变量,称为用户自定义变量。 例如,可以用变量来表示上述的文件名,定义OBJS变量表示目标文件,用CC变量 表示gcc,用CFLAGS表示编译的选项,RM表示rm -f,TARGET表示最终的生成目标 cacu。 之前冗长的Makefile可以简化成如下方式: 执行命令的情况如下; make 查找到第一个执行的规则为生成cacu,但是main.o等5个文件不存在, make按照默认的规则生成main.o等5个目标文件。 运行可执行文件:
0   回复
举报
蓝蓝的天 回复 2016-06-16
Makefile中的预定义变量: 在Makefile中有一些已经定义的变量,用户可以直接使用这些变量,不用进行定义。 在进行编译的时候,某些条件下Makefile会使用这些预定义变量的值进行编译。 在Makefile中经常用变量CC来表示编译器,其默认值为cc,即使用cc命令来进行 C语言程序的编译;在进行程序删除的时候经常使用命令RM,它的默认值为rm -f. 经过简化后,之前的Makefile可以采用如下形式: 执行命令的情况如下: 运行可执行文件:
0   回复
举报
蓝蓝的天 回复 2016-06-16
本帖最后由 蓝蓝的天 于 2016-6-16 10:01 编辑 Makefile中的自动变量: Makefile中的变量除了用户自定义变量和预定义变量外,还有一类自动变量。Makefile 中的编译语句中经常会出现目标文件和依赖文件,自动变量代表这些目标文件和依赖文件。 比如,$<表示依赖项中第一个依赖文件的名称。 按照自动变量重新改写的Makefile文件如下: 重新编写后的Makefile中,生成TARGET规则的编译选项使用$@表示依赖项中的文件名称,使用$<表示目标文件的名称。 运行make命令: 运行可执行文件:
0   回复
举报
蓝蓝的天 回复 2016-06-16
搜索路径: 在大的系统中,通常存在很多目录,手动添加目录的方法不仅十分笨拙而且容易造成 错误。Make的目录搜索功能提供了一个解决此问题的方法,指定需要搜索的目录,make 会自动找到指定文件的目录并添加到文件上,VPATH变量可以实现此目的。 重新书写上面的Makefile为如下的代码: 这样,目标文件都放到了objs目录下,只有最终的执行文件cacu放在当前目录,执行 make的结果如下: 编译目标文件时会自动加上路径名,并且当objs不存在时会创建此目录。 运行可执行文件:
0   回复
举报
蓝蓝的天 回复 2016-06-16
自动推导规则: 使用命令make编译扩展名为.c的C语言文件的时候,源文件的编译规则不用明确 给出。这是因为make进行编译的时候会使用一个默认的编译规则,按照默认规则 完成对.c文件的编译,生成对应的.o文件。 这样,在书写Makefile时,就可以省略描述.c文件和.o依赖关系的规则,而只需要 给出那些特定的规则描述。因此上面的例子可以使用更加简单的方式书写,Makefile 文件的内容如下: 在此Makefile中,不用指定OBJS的规则,make自动会按照隐含规则形成一个规则来 生成目标文件。 运行make命令: 运行可执行文件:
0   回复
举报
蓝蓝的天 回复 2016-06-16
本帖最后由 蓝蓝的天 于 2016-6-16 13:47 编辑 递归make: 当有多人在多个目录下进行程序开发,并且每个人负责一个模块,而文件在相对独立的 目录中,这时由同一个Makefile维护代码的编译会十分蹩脚,因为他们对自己目录下的文件 增减都要修改次Makefile,这通常会造成项目的维护问题。 递归调用的方式: Make命令有递归调用的作用,它可以递归调用每个子目录中的Makefile。 总控Makefile: 调用“$(MAKE) -C"的Makefile叫做总控Makefile。如果总控Makefile中的一些变量 需要传递给下层的Makefile,可以使用export命令。 例如上面的文件布局,需要在add和sub目录下分别编译,总控Makefile代码如下: CC编译器变量由总控Makefile统一指定,下层的Makefile直接调用即可。生成的 目标文件都放到./objs目录中,export了一个变量OBJSDIR.其中的${shelll pwd} 是执行一个shell命令pwd获得总控Makefile的当前目录。子目录Makefile的编写: add目录下的Makefile如下: 这个Makefile很简单,编译add目录中的两个C文件,并将生成的目标文件按照总控 Makefile传入的目标文件存放路径放置。 sub目录下的Makefile与add目录下的一致,也是将生成的目标文件放到总控Makefile 指定的路径中。 运行make命令: 运行可执行文件:
0   回复
举报
蓝蓝的天 回复 2016-06-16
Makefile中的函数: 在比较大的工程中,经常需要一些匹配操作或者自动生成规则的功能。 1.获取匹配模式的文件名wildcard: 这个函数的功能是查找当前目录下所有符合模式PATTERN的文件名,其 返回值是以空格分割的、当前目录下的所有符合模式PATTERN的文件名 列表。 2.模式替换函数patsubst: 这个函数的功能是查找字符串text中按照空格分开的单词,将符合模式 pattern的字符串替换成replacement。 3.循环函数foreach: 函数的功能为foreach将LIST字符串中的一个空格分隔的单词,先传给临时 变量VAR,然后执行TEXT表达式,TEXT表达式处理结束后输出。 利用上面几个函数对原有的Makefile文件进行重新编写,使新的Makefile可以 自动更新各个目录下的C语言源文件: 编译程序,输出结果如下: 运行可执行文件:
0   回复
举报
蓝蓝的天 2016-06-15
本帖最后由 HelloWii 于 2016-6-15 20:51 编辑 多文件工程的编译: 将1楼的多文件工程编译成可执行文件有两种方法,一是命令行操作,手动 输入将源文件编译为可执行文件;另一种是编写Makefile文件,通过make命令 将多个文件编译为可执行文件。 命令行方式就不介绍了,直接进行多文件的Makefile 使用make进行项目管理,需要一个Makefile文件,make在进行编译的时候,从 Makefile文件中读取设置情况,进行解析后运行相关的规则。make程序查找当前 目录下的文件Makefile或者makefile,按照其规则运行。例如,建立一个如下规则的 Makefile文件。 多文件的编译: 编译多文件的项目,在上面Makefile文件编写完毕后,运行make命令: 运行结果也出来了
0   回复
举报
发布
x
收藏成功!点击 我的收藏 查看收藏的全部帖子