什么是Makefile?首先,make是一个工具程序(Utility software),是一种控制编译或者重复编译软件的工具;make可以自动管理软件编译的内容、方式和时机从而使程序员能够把精力集中在编写代码上。那make怎样工作呢?其实make是通过makefile文件实现的。makefile是一个文本形式的数据库文件。其中包含一些规则,这些规则告诉make需要编译哪些文件、怎样编译这些文件以及在什么样的条件下去编译。

关于Makefile的基本规则:

target: dependency [dependency [...]]

command

command

[...]

每个命令的第一个字符必须是制表符,使用空格代替是不正确的。

其中,target是需要创建的二进制文件或目标文件,虽然目标体通常是程序,但它们也可以是文本文件、手册页面等任何东西甚至可以被用作测试和设置环境变量。dependency是在创建target时需要输入的一个或者是多个文件的列表。命令序列是创建target文件所需的步骤,如编译命令。一般,没有特殊指定的情况下,make的工作目录就是当前的目录。当GNU make被调用时会顺序查找名为GNUmakefile、makefile或者是Makefile的文件,但不知出于于某种不可描述的原因,绝大部分的Linux程序员习惯性的使用 Makefile这种形式。

简单的makefile写法:

首先有这么几个简单的程序 howdy.c helper.h helper.c

howdy.c

#include

#include"helper.h"

int main()

{

printf("hello,linux programming world\n");

msg();

return 0;

}

头文件 helper.h

void msg(void);

helper.c

#include

void msg(void)

{

printf("This message sent form helper.c .\n");

}

好了,利用上述的这些程序写一个简单的Makefile文件

howdy:howdy.o helper.o helper.h

gcc howdy.o helper.o -o howdy

helper.o:helper.c helper.h

gcc -c helper.c

howdy.o:howdy.c

gcc -c howdy.c

clean:

rm howdy *.o

要编译howdy,只要在Makefile目录下键入make即可。第一个目标体howdy称为默认(default)目标体--这就是该Makefile文件要创建的文件。howdy有三个依赖体,分别为howdy.o helper.o helper.h;要生成howdy这个文件就必须要他所依赖的这三个文件。第二行就是调用编译器的命令来供make执行来创建howdy文件,其中helper.h也列入依赖体的原因是为了防止编译器调用未申明的函数产生错误。接下来的规则是告诉make怎样生成单个目标文件:helper.o和howdy.o。这两个规则用了gcc -c选项,其含义为只编译但不链接文件。

嗯,,,大概的编译链接过程就是上图这样,howdy.c和helper.c这两个源文件经过预处理后编译成目标文件,然后连接器把来自howdy.o和helper.o的目标代码以及标准库和c启动代码链接到一起生成可执行的二进制文件howdy。通常情况下,如果在依赖体helper.o和howdy.o不存在的情况下使用命令编译howdy,那么gcc会报错并退出。On the other hand,编译器在看到howdy需要这两个文件(以及helper.h)后,make先看它们是否存在,如果不存在则根据规则命令生成它们,然后再根据第一条规则生成howdy。显然地,如果helper.h不存在,也会报错退出,因为Makefile文件中并没有规则命令生成helper.h。

好了,大概明白make是怎么执行的了,那新的问题又来了,make怎么知道什么时候该重新编译一个新的文件呢?  其实很简单:如果指定的目标文件不存在,那么毫无疑问,make就会根据规则命令生成它;如果目标文件已经存在,那么make就会将目标文件和依赖文件的时间戳进行对比,如果有一个以上的依赖文件比目标文件新(就是依赖文件的修改时间比目标文件的时间新),那么make就会重新编译生成新的目标体。

伪目标:

什么是伪目标?伪目标就是上面Makefile文件的clean就是伪目标,伪目标就是不对应实际的文件。但是,由于伪目标没有依赖体,所以它的命令是不会自动被make执行的,如果要编译执行这个目标体,那么只需 make clean,编译器就会编译执行clean的命令。但是,如果刚好有个名字叫做clean的文件存在,那么make就会发现它,但是clean没有依赖体,所以make就会认为clean已经是最新的文件从而不会执行其命令。为了处理这种情况,就需要使用特殊的目标体.PHONY。.PHONY的依赖体文件的含义和通常的一样,但是make不检查是否存在有文件名和依赖体中的一个名字相匹配的文件,而是直接执行与之相关的命令。如果使用.PHONY,上述的Makefile文件就成了下面这样

howdy:howdy.o helper.o helper.h

gcc howdy.o helper.o -o howdy

helper.o:helper.c helper.h

gcc -c helper.c

howdy.o:howdy.c

gcc -c howdy.c

#hello:hello.c

# gcc hello.c -o hello

#all:howdy hello

.PHONY

clean:

rm howdy *.o

什么意思?一句话,意思就是:make在更新目标文件时,不管clean后面有没有依赖,都会直接执行clean下面的命令。

变量:

为了简化编辑和维护Makefile,make允许在Makefile中创建和使用变量。所谓的变量就是伪指定文本串在makefile中定义一个名字,这个文本串就是变量的值。

定义变量的一般方法:

VARNAME = some_text [...]

把变量名用括号扩起来,然后在前面加上“$”,就可以引用变量的值了:$(VARNAME)

将之前的Makefile文件中使用变量:

OBJS = howdy.o helper.o

HDRS = helper.h

howdy:$(OBJS)

gcc $(OBJS) -o howdy

helper.o:helper.c $(HDRS)

gcc -c helper.c

howdy.o:howdy.c

gcc -c howdy.c

clean:

rm -rf *.o

OBJS和HDRS会在被引用的每个地方展开成它的值,编译时也是如此。关于自动变量:

变量 说明

$@ 规则的目标文件对应的文件名

$^ 规则中依赖的文件名

$< 规则中第一个相关文件名

$? 规则中日期新于目标的所有相关文件列表,以空格为分隔符

$(@D) 目标文件的目录部分(目标在子目录中)

$(@F) 目标文件的文件名部分(目标在子目录中)

用于程序名和标志的预定义变量:

变量 说明

AR 归档维护程序,默认值=ar

AS 汇编程序,默认值=as

CC C编译程序,默认值=cc

CPP C预处理程序,默认值=cpp

RM 文件删除程序,默认值= rm -rf

ARFLAS 传给归档维护程序的标志,默认值 = rv

ASFLAGS 传给汇编程序的标志,没有默认值

CPPFLAGS 传给c预处理程序的标志,没有默认值

CFLAGS 传给c编译器的标志,没有默认值

LDFLAGS 传给链接程序(ld)的标志,没有默认值

模式规则:

通过用户定义自己的隐式规则,模式规则提供了扩展make的隐式规则的一种方法。模式规则雷士与普通规则,但是它的目标中必定含有符号 “%s”,这个符号可以与任何非空字符串匹配;为与目标中的“%s”匹配,这个规则的相关部分文件也必须使用“%s”。例如: %.o:%.c

告诉make所有形式为somename.o的目标(object)文件都应该从源文件somename.c编译而来。再将上面的Makefile文件修改:

CC = gcc

OBJ = howdy

FILES = howdy.o helper.o

HDRS = helper.h

O_FLAG = -o

C_FLAG= -c

RM = rm -rf

howdy:$(FILES) $(HDRS)

$(CC) $(FILES) $(O_FLAG) $(OBJ)

%.o:%.c

$(CC) $(C_FLAG) $^ $(O_FLAG) $@

clean:

$(RM) $(FILES) $(OBJ)

以上内容为自己在《GNU/Linux》一书中学习Makefile时的一点理解,有错还请留言指正。

标签:文件,helper,howdy,Makefile,目标,linux,编写,make

来源: https://www.cnblogs.com/sugarxt/p/10585865.html

linux 建立伪目标过程,linux之Makefile 编写、规则、伪目标、变量相关推荐

  1. 一篇文章看懂makefile编写规则

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...

  2. linux内核的配置过程,linux内核的配置机制及其编译过程

    linux内核的配置机制及其编译过程. 一.配置系统的基本结构 Linux内核的配置系统由三个部分组成,分别是: 1.Makefile:分布在 Linux 内核源代码根目录及各层目录中,定义 Linu ...

  3. 【整理】Makefile编写规则

    Makefile 文章目录 Makefile Makefile的规则 语法 通配符 文件搜寻 伪目标 多目标 静态变量 自动生成依赖性 书写命令 嵌套执行make 定义命令包 变量使用 变量基础 变量 ...

  4. linux建立动态库链接,Linux动态链接库.so文件的创建与使用

    资料出处:http://linux.chinaitlab.com/administer/803560.html 编 写维护文件的目的,在于方便程序员维护程序,尤其是维护比较大的工程项目.一个素质良好的 ...

  5. linux定时器回调处理过程,Linux内核系统定时器TIMER实现过程分析

    可见涉及到系统定时器的数据结构并不多,那么:对于一个linux系统中,定时器个数可能会很多,而且每个定时器的超时事件时间并不相同,所以如何管理和处理定时器超时事件,关系到内核性能的高低.它根据不同的定 ...

  6. linux 跟踪命令执行过程,Linux的strace命令跟踪线程死锁

    strace命令,是Linux提供的跟踪系统调用的命令,需要sudo或root权限,可以查看进程(线程)使用的系统调用. 基本用法:sudo strace -p 进程号 如果一个线程递归获取同一个锁, ...

  7. linux搭建一个的过程,Linux内核创建一个新进程的过程

    此文仅用于MOOCLinux内核分析作业 task_struct数据结构 根据wiki的定义,进程是计算机中已运行程序的实体.在面向线程设计的系统(Linux 2.6及更新的版本)中,进程本身不是基本 ...

  8. MBR的Linux分区机制启动过程,linux系统启动流程(MBR)

    总:POST---> Boot Squence ---> Bootloader ---> kernel ---> init ---> 完成启动 系统:CentOS6 1. ...

  9. linux的kerne启动过程,linux

    333.6K http://www.vuse.vanderbilt.edu/~srs/linux-papers-talks/iee-2002.pdf vuse.vanderbilt.edu 全网免费 ...

最新文章

  1. delphi char与string比较
  2. 如何取消 DiscuzX 帖子被系统自动隐?
  3. 组织机构代码输入测试用例_测试代码以用于过大的输入
  4. JAVA版本微信公众账号开源项目版本发布-jeewx1.0(捷微)
  5. 在html中控制自动换行
  6. 微型计算机2014年9月下,2014年9月计算机应用基础》网络教育统考真题.doc
  7. 107 岁的 IBM 以 340 亿美元吞下了 25 岁的“小”红帽!
  8. npm install失败的解决方法
  9. python:只想在opencv中显示红色通道?
  10. SuperMap BIM+GIS技术白皮书
  11. 苹果电脑Mac系统如何下载安装谷歌Chrome浏览器
  12. VS2012帮助下载地址
  13. 创建SSM项目框架搭建流程--史上最详细教程
  14. 《基本无害的计量经济学》第二章:选择性偏误与随机实验
  15. 阿里云DataV基础平面地图使用笔记(2)
  16. docker的一些使用技巧
  17. 【Day3.3】美攻铁道市场零距离接触行驶中的火车
  18. 兔子繁殖问题Java实现
  19. python+scrapy爬虫 + mongoodb + hadoop+hive综合项目:招聘网站数据
  20. 【UV打印机】RYPC打印软件教程(七)-PCS说明(上)

热门文章

  1. js 异步执行_JS Asynchronous — JS 异步编程极简史
  2. 智能计米器jk76怎么安装_春节智能锁消费指南:只看价格的后果有多严重?
  3. C++新特性探究(八):初始化列表(Initialization List)再探究
  4. 大一微积分笔记整理_大一高数笔记.doc
  5. python with关键字_python中用with关键字来实现上下文管理器.
  6. python环形队列_Python 实现数据结构-循环队列的操作方法
  7. php authorization,PHP CURL设置Authorization
  8. crm系统是什么很棒ec实力_易观发布2019中国CRM实力矩阵,EC成为领先者
  9. word文字铺满页面_这5个Word问题,你会解决几个?
  10. 在线HTML网页小窗口复制不了,教你一招:解决某些网页不能复制的文字的N种方法!...