我们在Linux系统中学习C语言或者C++语言时,大多数时候只是用gcc命令或者g++命令在命令行进行简单的编译、链接即可得到最终的可执行文件,进一步即可验证所写C/C++语言的正确性。但是,在大型工程项目中,源文件成千上万,甚至几十万都有可能,如果还是用命令行直接进行编译,这将是一项比南水北调还复杂的工程。由于文件之间复杂的依赖关系,直接使用命令行编译大型工程项目是不现实的,此时,makefile应运而生,makefile就是管理源文件之间依赖关系的一种脚本程序、也是一种脚本语言。

  makefile脚本文件的内容大体由以下三点组成:

  1、它定义了一系列规则来指定源文件编译的先后顺序。

    规则是makefile中的重要概念,它一般由目标、依赖、命令组成。

  2、拥有特定的语法规则,支持变量、函数、函数调用等。

  3、能够直接集成操作系统中的各种命令。

  你可能会问,makefile是不是只在Linux系统中存在?其实,在任何一个编译环境中都需要makefile的存在,在VS、Qt这种集成的开发环境中,开发工具已经帮我们管理好了源文件,而底层正是通过makefile实现的,只是,开发工具帮我们屏蔽了这些细节。

  一些接触过makefile的同学可能会有疑问,makefile是不是只能应用在C/C++程序的编译中呢?答案是否定的。只要电脑系统中拥有了正确的编译环境(拥有对应语言的编译命令、正确配置了环境变量),makefile可以应用于任何编译型语言的依赖管理。

  既然,makefile是一种脚本语言,那么makefile的解释器是什么呢?没错,就是make,make是一个解释器,是一个应用程序。make应用程序具体有以下三个作用:

  1、根据makefile文件中的程序解析出文件之间的依赖关系。

    根据makefile语法,我们将源文件的依赖关系写在了makefile文件中,而make应用程序解析该文件的内容并得到源文件之间的依赖关系,进一步确定并控制文件的编译顺序。

  2、根据文件之间的依赖关系,自动维护编译工作。

    假设一个工程中有10000个源文件,在作用1中,make已经将它们之间的依赖关系确定出来,但是,在编译的过程中,由于makefile程序中所写命令的错误或者源程序中的语法错误,导致make应用程序在编译到第5000个程序时出现错误并终止执行,根据错误提示我们更改makefile程序中的指令或者源文件中的相关语句,并再次执行make。由前面分析可知,在第5000个程序编译出错时,前4999个程序已经进行了成功编译,而修改第5000个源文件或者makefile指令时,前4999个源文件没有进行更新或更改,因此,再次执行make时无需重新编译这4999个文件,直接使用已经编译好的结果即可。make自动维护编译工作就是这个意思,它能非常聪明的知道哪些文件需要重新编译,哪些不需要重新编译。在大型工程中,大大节省了编译时间。

  3、执行宿主操作系统中的各种命令

    例如,在Linux系统中,makefile程序中可以调用任何Linux下的命令,make在解析makefile时,可以解析出这些命令,并执行这些命令来完成任务。在Windows等其他系统中一样如此。

  实际中,makefile在Linux系统的开发中使用最为广泛,且需要开发人员手工编写,包括嵌入式Linux开发、Linux应用开发等。接下来,我们主要介绍Linux下与C语言开发相关的makefile。

  规则是makefile中的重要概念,一条规则如下所示:

  

  其中,第1、2行共同组成一个规则,第一行的hello是该规则的目标,冒号(:)后的为该规则的依赖,本规则中依赖为空,第2行的echo “Hello Makefile”为该规则的命令,规则的命令所在的行必须以tab键开头(不能以多个空格键代替),否则make解释器在解释该makefile时会报错。

  makefile文件的文件名可以随意命名(符合操作系统的习惯),Linux命令行在调用make应用程序时,通过-f选项指定makefile文件名即可,并可以同时指定make的执行目标。如下图所示:

  

  将makefile文件改名为1.txt。第一条编译命令make -f 1.txt hello中,-f指定了makefile文件的文件名为1.txt,并去该文件中寻找hello目标,执行该目标下的命令。第二条命令没有指定目标,则默认寻找1.txt文件中第一个目标。

  Linux的设计哲学是越简单越好,因此,make也可以不指定文件名称及目标。如下所示:

    

  

  将makefile文件改名为makefile,第一条命令make会使得make解释器在当前目录下寻找名字为makefile或者Makefile的文件,并默认寻找该文件中的第一个目标,执行该目标下的指令。第二条命令make test,会使得make解释器在当前目录下寻找名为makefile或者Makefile的文件,并寻找该文件下的test目标,执行该目标下的指令。

  至此,makefile的基本概念讲解完了,后续会有更加深入的makefile系列文章。

欢迎评论、指导以及进一步交流,QQ527635593

本文参考:

    狄泰软件教学课件

    gun make手册

    专业嵌入式软件开发

第一篇 make与makefile介绍的更多相关文章

  1. Golang学习-第一篇 Golang的简单介绍及Windows环境下安装、部署

    序言 这是本人博客园第一篇文章,写的不到位之处,希望各位看客们谅解. 本人一直从事.NET的开发工作,最近在学习Golang,所以想着之前学习的过程中都没怎么好好的将学习过程记录下来.深感惋惜! 现在 ...

  2. Python全栈开发之路 【第一篇】:Python 介绍

    本节内容 一.Python介绍 python的创始人为荷兰人——吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本 ...

  3. 第一篇 SQL Server代理概述

    本篇文章是SQL Server代理系列的第一篇,详细内容请参考原文. SQL Server代理是SQL Server的作业调度和告警服务,如果使用得当,它可以大大简化DBA的工作量.SQL Serve ...

  4. 我们一起学习WCF 第一篇初识WCF(附源码供对照学习)

    前言:去年由于工作需要我学习了wcf的相关知识,初期对wcf的作用以及为何用怎么样都是一知半解,也许现在也不是非常的清晰.但是通过项目对wcf的运用在脑海里面也算有了初步的模型.今天我就把我从开始wc ...

  5. 【译】第一篇 SQL Server代理概述

    本篇文章是SQL Server代理系列的第一篇,详细内容请参考原文. SQL Server代理是SQL Server的作业调度和告警服务,如果使用得当,它可以大大简化DBA的工作量.SQL Serve ...

  6. android调用第三方库——第一篇 (转载)

    转自:http://blog.csdn.net/jiuyueguang/article/details/9447245 版权声明:本文为博主原创文章,未经博主允许不得转载. 0:前言: 这两天一直在研 ...

  7. 跟初学者学习IbatisNet第一篇

    写在前面的话:我自己也是一个初学者,写这个专题只是为了对学过知识的巩固,如果有什么不对的地方,欢迎大家指正…………………… 第一篇就简单介绍一下什么是IbatisNet,然后写一个简单的Demo,在后 ...

  8. IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

  9. IIS负载均衡-Application Request Route详解第一篇: ARR介绍

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

随机推荐

  1. Python3各种进制之间的转换方法

    一.2/8/10/16进制互转 1.1 2/8/10/16进制赋值 # 二进制赋值以0b打头 a = 0b1000 # 八进制赋值以0o打头,第一个是数字0第二个是字母o b = 0o1100 # 十 ...

  2. cmp的值到底是0还是1还是-1的问题

    返回值不局限于这三个数返回负数,表示第一个参数小于第二个参数返回整数,表示第一个参数大于第二个参数返回0,表示他们相等

  3. linux nat style

      1● nat style 2● link style    

  4. Laravel框架如何去除URL中的/public

    laravel/server.php改名为index.php 并且将public目录下的.htaccess拷贝到Larvael根目下 再访问 如有配置不成功的请加群

  5. linux命令--文件查询

    ls [ -lahid ] [ /* ] ls  --   默认查询当前目录下的显性文件 -l  --  显示文件的详细信息 -a --  显示所有文件(包括隐藏文件) -h --  文件大小显示为 ...

  6. laravel在控制器中动态创建数据表

    Schema::connection('usertable')->create('test', function ($table) { $table->increments('id'); ...

  7. linux用户管理 用户和用户组信息

    用户管理配置文件 用户信息文件  /etc/passwd 密码文件 /etc/shadow 用户配置文件 /etc/login.defs /etc/default/useradd 新用户信息文件 /e ...

  8. js 敏感词过滤

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  9. hdu3518

    题解: 后缀数组 枚举长度为k(1<=k<=len/2)的满足要求的子串个数 代码: #include<cstdio> #include<cmath> #inclu ...

  10. linux:scp从入门到刚入门

    [温馨提示] 此文和ssh配合食用更佳. 首先请小伙伴们连上你要传文件的那台机,用ssh可以免密登录. [传送文件] 我们一般发文件的话可以scp来发一发,比如说我现在要向多个扔很多tomcat包,我 ...