Makefile文件解析与编写

makefile编写总结 最近在看google开源项目中,发现有部分makefile语法不是很清楚,想想要对make语法规则做一下梳理,以后好查问题,由于本人能力有限,可能有些纰漏。 makefile文件是告诉make如何去编译和链接程序语言文件 make的概念 make是一个工具程序,经由读取叫做makefile的文件,自动话构建软件 make a.txt makefile的文件格式 构建规则都写在makefile文件里面,所以需要学会如何编写makefile 概述 makefile文件有一系列规则构成,每个. 阅读详情

from:http://www.cnblogs.com/luchen927/archive/2012/02/05/2339002.html

相信很多朋友都有过这样的经历,看着开源项目中好几页的makefile文件,不知所云。在日常学习和工作中,也有意无意的去回避makefile,能改就不写,能用ide就用ide。其实makefile并没有想象的那么难写,只要你明白了其中的原理,自己实践几次。你也可以自己写makefile,让别人对你头来羡慕的目光。

  下面本人介绍一下自己的学习成果,初学阶段,欢迎大家多多指正。

  简单的说,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至可以在makefile中执行shell脚本。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

  关于程序的编译和链接

  一般来说,无论是C还是C++,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile),一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

  编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。

  链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来 链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给 中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

  下面我们开始看看如何自己写出makefile。

  Makefile的规则

  目标 : 需要的条件 (注意冒号两边有空格)

    命令  (注意前面用tab键开头)

  解释一下:

  1 目标可以是一个或多个,可以是Object File,也可以是执行文件,甚至可以是一个标签。

  2 需要的条件就是生成目标所需要的文件或目标

  3 命令就是生成目标所需要执行的脚本

  总结一下,就是说一条makefile规则规定了编译的依赖关系,也就是目标文件依赖于条件,生成规则用命令来描述。在编译时,如果需要的条件的文件比目标更新的话,就会执行生成命令来更新目标。

  下面举个简单的例子说明。如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。

  edit : main.o kbd.o command.o display.o /
           insert.o search.o files.o utils.o
            cc -o edit main.o kbd.o command.o display.o /
                       insert.o search.o files.o utils.o

    main.o : main.c defs.h
            cc -c main.c
    kbd.o : kbd.c defs.h command.h
            cc -c kbd.c
    command.o : command.c defs.h command.h
            cc -c command.c
    display.o : display.c defs.h buffer.h
            cc -c display.c
    insert.o : insert.c defs.h buffer.h
            cc -c insert.c
    search.o : search.c defs.h buffer.h
            cc -c search.c
    files.o : files.c defs.h buffer.h command.h
            cc -c files.c
    utils.o : utils.c defs.h
            cc -c utils.c
    clean :
            rm edit main.o kbd.o command.o display.o /
               insert.o search.o files.o utils.o

 

  将上面的内容写入到Makefile文件中,然后执行make就可以进行编译,执行make clean就可以删除所有目标文件。解释一下,也就是说生成最终的目标文件edit,依赖于一系列的.o目标文件,而这些.o文件又是需要用源文件来编译生成的。

  需要注意的是,clean后面没有条件,而clean本身也不是文件,它只不过是一个动作名字,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。

  make是如何工作的

  在默认的方式下,也就是我们只输入make命令。那么,

 

    1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
    2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
    3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
    4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
    5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了。

  makefile中使用变量

  前面的知识已经足以让你自己完成一个简单的makefile了,不过makefile的精妙之处远不止如此,下面来看看如何在makefile中使用变量吧。

  在上面的例子中,先让我们看看edit的规则:

 

      edit : main.o kbd.o command.o display.o /
                  insert.o search.o files.o utils.o
            cc -o edit main.o kbd.o command.o display.o /
                       insert.o search.o files.o utils.o

 

  我们可以看到[.o]文件的字符串被重复了两次,如果我们的工程需要加入一个新的[.o]文 件,那么我们需要在两个地方加(应该是三个地方,还有一个地方在clean中)。当然,我们的makefile并不复杂,所以在两个地方加也不累,但如果 makefile变得复杂,那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败。所以,为了makefile的易维护,在makefile中我们 可以使用变量。makefile的变量也就是一个字符串,理解成C语言中的宏可能会更好。

  于是,我们使用变量objects

  objects = main.o kbd.o command.o display.o /
              insert.o search.o files.o utils.o

  这样一来,原来的makefile变成如下的样子:

  objects = main.o kbd.o command.o display.o /
              insert.o search.o files.o utils.o

    edit : $(objects)
            cc -o edit $(objects)
    main.o : main.c defs.h
            cc -c main.c
    kbd.o : kbd.c defs.h command.h
            cc -c kbd.c
    command.o : command.c defs.h command.h
            cc -c command.c
    display.o : display.c defs.h buffer.h
            cc -c display.c
    insert.o : insert.c defs.h buffer.h
            cc -c insert.c
    search.o : search.c defs.h buffer.h
            cc -c search.c
    files.o : files.c defs.h buffer.h command.h
            cc -c files.c
    utils.o : utils.c defs.h
            cc -c utils.c
    clean :
            rm edit $(objects)

  这样看起来方便多了吧,也更加省事了。如果有新的.o文件怎么办?当然是在objects里面添加了,这样只需要一处改变,很方便吧。

  让make自动推导

  GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。

  只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一 个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile再也不用写得这么复杂。我们的是新的makefile又出炉了。

  objects = main.o kbd.o command.o display.o /
              insert.o search.o files.o utils.o

    edit : $(objects)
            cc -o edit $(objects)

 

    main.o : defs.h
    kbd.o : defs.h command.h
    command.o : defs.h command.h
    display.o : defs.h buffer.h
    insert.o : defs.h buffer.h
    search.o : defs.h buffer.h
    files.o : defs.h buffer.h command.h
    utils.o : defs.h

  clean :
            rm edit $(objects)

  当然,如果你觉得那么多[.o]和[.h]的依赖有点不爽的话,好吧,没有问题,这个对于make来说很容易,谁叫它提供了自动推导命令和文件的功能呢?来看看最新风格的makefile吧。

  objects = main.o kbd.o command.o display.o /
              insert.o search.o files.o utils.o

    edit : $(objects)
            cc -o edit $(objects)

 

    $(objects) : defs.h
    kbd.o command.o files.o : command.h
    display.o insert.o search.o files.o : buffer.h
    clean :
            rm edit $(objects)

  不过话说回来,本人并不推荐这种方法。虽然简单,但是这种方法破坏了文件本身的依赖关系。如果文件过多的话,可能你自己都不清楚了。

  

  怎么样,makefile是不是既简单又强大?其实makefile远比这更强大,容我日后再慢慢介绍,今天就先到这里。

  如果大家觉得看我的文章不解渴,可以去这里看看http://blog.youkuaiyun.com/haoel/article/details/2887,大牛的文章,我个人是很喜欢的。

  最后,欢迎大家拍砖啊。

【33】软考软件设计师——算法题(二):贪心法与回溯法深度精讲|第4题进阶满分攻略 本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第33篇,承接第32篇分治法与动态规划,聚焦**下午第4题算法大题进阶核心**,详解贪心法与回溯法两大高频难点算法。全文超4000字深度拆解贪心法核心原理、贪心选择性质、局部最优推全局最优的底层逻辑,厘清贪心算法适用边界与经典误区;深挖回溯法深度优先遍历思想、递归回溯三步流程、可行性剪枝与最优性剪枝两大核心技巧;全覆盖活动选择、零钱兑换、01背包贪心禁区、八皇后、全排列等软考必考经典题型;配套标准化算法框架代码、考场填空模板、剪枝优化实操案例 阅读详情

相关推荐

自绘CListCtrl时发现ON_WM_MEASUREITEM_REFLECT和DrawItem(LPDRAWITEMSTRUCT lpMeasureItemStruct) 无响应

自绘CListCtrl时发现ON_WM_MEASUREITEM_REFLECT和DrawItem(LPDRAWITEMSTRUCT lpMeasureItemStruct) 无响应 一般情况下,我们都是在 dialog 里面 放一个 list 控件,然后 用自己的类绑定自己的自绘对象,如同下面: 1.  在 dialog 里面 加一个 list 列表 2. 然后 绑定这个列表 哈哈...

mfreesky的专栏 2170

如何自己编写Makefile

如何自己编写Makefile   相信很多朋友都有过这样的经历,看着开源项目中好几页的makefile文件,不知所云。在日常学习和工作中,也有意无意的去回避makefile,能改就不写,能用ide就用ide。其实makefile并没有想象的那么难写,只要你明白了其中的原理,自己实践几次。你也可以自己写makefile,让别人对你头来羡慕的目光。   下面本人介绍一下自己的学习成

草莓在努力!!! 711

CRPR的三种关键影响:从SI、OCV到Min Pulse Width的时序优化实践

本文深入探讨了CRPR(时钟重汇聚悲观度消除)在芯片时序优化中的三种关键影响:信号完整性(SI)、片上变异(OCV)和最小脉宽检查。通过实际案例分析和技术细节,展示了CRPR如何有效修正时序分析中的过度保守估计,提升设计精度。文章特别强调了SI-aware CRPR的调试技巧和OCV补偿的最佳实践,为芯片设计工程师提供了宝贵的时序优化指导。

weixin_30920853的博客 379

C语言程序makefile编译过程

2022-0111 blog_010 C语言程序makefile编译过程 makefile是一些大型linux下开发的项目经常会用到的编译脚本; 可以将makefile理解为类似shell一样的脚本语言,他也有自己的语法规则,注释,可以定义变量等;......

万丈高楼平地起,学习改变命运,加油 ^_^ 3226

西门子S7-1200PLC PID_Temp工艺指令在恒温控制中的实战应用

本文详细介绍了西门子S7-1200PLC中PID_Temp工艺指令在恒温控制系统中的实战应用。从硬件选型、安全接线,到TIA Portal软件组态、编程及核心PID_Temp指令调用,手把手指导搭建系统。重点讲解了利用指令自带的预调节与精确调节功能进行PID参数自整定,最终实现高精度、低波动的温度控制,适用于塑料成型、食品烘烤等多种工业场景。

i1j2k的博客 235

别再手动拆解字节了!用博图这个功能指令,5分钟搞定ARRAY转BOOL数组

本文详细介绍了西门子博图中`ARRAY_TO_BOOL`功能指令的高效应用,帮助工程师快速实现ARRAY到BOOL数组的转换。通过实战案例和参数配置指南,展示了如何5分钟内完成传统方法需半小时的任务,大幅提升PLC编程效率,特别适用于通信报文解析和设备状态监控。

weixin_42653691的博客 262

makefile自动生成

一、Makefile介绍   Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中纪录有文件的信息,在make时会决定在链接的时候需要重新编译哪些文件。   Mak

shifuxinghua的专栏 1116

Star CCM+ 202206 (17.04) 详细安装步骤

StarCCM+ 17.04 安装包和详细安装步骤

薛定谔的alpha狗 3万+

Makefile文件是什么

输入/输出重定向 同标准I/O一样,Shell对于每一个进程预先定义了三个文件描述字(0,1,2)。分别对应于: 0(STDIN)标准输入 1(STDOUT)标准输出 2 (STDERR)标准错误输出 0键盘是标准输入。1,2都是屏幕上面显示的。输入输出重定向就是输入不从键盘输入,输出不从屏幕输出。 >或>>输出重定向 范例:ls -l /tmp ...

小楼一夜听春雨,深巷明朝卖杏花 717

Isaacgym使用操作指南

Isaac Gym 是一个强大的仿真工具,特别适合那些需要进行大规模并行仿真和训练的机器人和强化学习任务。通过 GPU 加速、深度学习集成和丰富的物理仿真能力,Isaac Gym 能够显著提高仿真和训练效率,是机器人学和 AI 研究中的一大利器。

Tony Wey的博客 1万+

汽车TSN时间敏感网络测试技术与探索系列讲座4 -TSN802.1AS同步要求及验证方法

TSN网络各设备类型同步性能要求是什么?各类设备的测试组网及测试内容。也将通过演示来展示相关测试结果,及如何解决上述的测试关注点。

weixin_43903833的博客 761

linux基础篇(一)——GCC和Makefile编译过程

gcc的使用方法 gcc [选项] 文件名 一个c/c++文件要经过预处理、编译、汇编和链接才能变成可执行文件。 (1)预处理 C/C++源文件中,以#开头的命令被称为预处理命令,如"#include"、宏定义命令"#define"、条件编译命令"#if、#ifdef"等。预处理是将包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到......

sinat_31039061的博客 1万+

RK3588平台MIPI DSI屏幕调试记录

本文是基于RK3588平台,MIPI屏调试总结。调试过程中遇到的问题:一开始很久没亮,测量了电源电压和波形都正常。后来换了一组板子和屏幕做对比。最后是因为屏幕的座子没焊接好,二是接MIPI屏幕的排线太长会影响数据传输。换了一根短的线之后屏幕亮起。vp2vp3。

bingdund的博客 1389

makefile文件编写

Makefile 中的变量用于存储常用的路径、编译选项、源文件列表等,方便后续引用和修改。

qq_56842330的博客 1028

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

读懂和编写Makefile需掌握的关键基础知识(常用符号、先解析再执行、make命令的第一个动作、规则的概念、目标及伪目标的相关概念、文件更新机制、几个重要的自动化变量等知识)

在 Makefile 中,同一个目标可以出现多次。后面的规则会扩展或覆盖前面的规则。__build: # 空规则 __build: touch examplemake 会最终使用最后的__build目标定义,即带有依赖的规则。关于上面命令中的touch的介绍见博文Makefile中遇到的touch命令是怎么回事儿?

昊虹AI笔记 1037

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

多文件,多头文件时gcc与makefile的编写经验

经常在一个项目中包含多个.c源文件,而且一个.c源文件包含了一堆的头文件,这种情况下如何编写makefile,使得能成功编译整个项目?本博文对这些问题提出自己浅析的理解。涉及到对gcc命令使用与编译流程理解及多文件时makefile的编写示例。 ==============================================================================

GMPY_Tiger的博客 1万+

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Makefile编写实例

1.实例所需文件 1.1 head.hadd.cpp sub.cppmain.cpp在同一目录下 head.h 1 int add(int a, int b); 2 int sub(int a, int b); add.cpp 1 #include "head.h" 2 3 int add(int a, int b) 4 { ...

aixiaoql的博客 1773

【linux环境下】【C语言编译】【使用makefile】【详细版】

前言 这是一个简单地演示C语言如何使用makefile在linux下进行编译。 目录 前言 一、C语言编译 1、编写add.c文件 2、编写sub.c文件 3、编写test.h文件 4、编写makefile文件 5、执行makefile文件 6、高级一点的makefile文件写法 7、makefile模板 一、C语言编译 整个流程: 1、编写add.c文...

qq_36417014的博客 9117

【Linux基础】make / Makefile的使用与编写(多文件的编写)

本文介绍了make/makefile在多文件中的使用,有两种方法的makefile模板,以及程序编译过程的简要解释和gcc的ESc对应关系等

卜及中的博客 2068

深入解析Makefile

行下面gcc -c main.c -o main.o这一指令,然后生成main.o这一文件,作为app后面的依赖项;app这一行是第一条规则,后面所有的规则都是为他服务的,app是即将要生成的目标文件,后。一个main.o文件是否存在,如果不存在,往下找其他的规则,找到了main.o这一规则,所以他会执。之前生成的main.o要晚,所以执行该规则下面的指令,同理可得,对于第一个规则app而言,app。个规则,生成app的第二个依赖向,依次类推,只有当app后面所有的依赖向都存在的时候,才会。

qq_74390043的博客 850

Linux基础----Makefile文件的编写

编写规则 Makefile文件是由一条条规则组成的 每一条规则格式如下 target : dependency (Tab)command 一个目标(target):即make最终需要创建的文件,如可执行文件和目标文件;目标也可以是要执行的动作,如clean。 一个或多个依赖文件(dependency)列表:通常是编译目标文件所需要的其他文件。 一系列命令(command):是make执行的动作...

1900的博客 1223

Makefile的编写规则

Makefile的好处: 修改源文件或者头文件,只需要重新编译牵涉的文件,就可以重新生成APP Makefile文件编写规则 目标(target)...:依赖(prerequiries) <tab>命令(command) 目标通常是要生成的文件的名称,可以是可执行文件或OBJ文件,也是一个执行动作的名称,如“clean”。 依赖是用来产生目标的材料(比如源文件),一个目标经常有几个依赖。 命令是生成目标执行时的动作,一个规则可以含几个命令,每个命令占一行。 注意:每个命令行前面必须是一个tab

H_A666的博客 1080

makefile文件的编写规则及实例 (转)

makefile文件的编写规则及实例  (2007-07-18 01:18) 分类: Linux系统及编程   1.一个简单的makefile例子   假设一个程序有两个文件file1.c,file2.c,每个文件都包含head.h,生成file可执行文件   file:file1.o file2.o                  附属行(文件的...

Everything is possible--博客的内容只是作为一种备忘 549

Makefile编写指南

commandtarget这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。makefile的换行符是 ‘\’

qq_62051388的博客 391

Liunx操作-Record09—makefile文件的编写

本质:解决生成命令的问题!

恋蛩音的博客 560

《Linux驱动》最简单的驱动编写与makefile

#include <linux/init.h> /*包含初始化宏定义的头文件,代码中的module_init和module_exit在此文件中*/ #include <linux/module.h> /*包含初始化加载模块的头文件,代码中的MODULE_LICENSE在此头文件中*/ MODULE_LICENSE("Dual BSD/GPL"); /*声明是开源的,没有内核版本限制*/ MODULE

学编程找莫离,莫离老师更懂你! 2742
上一篇: 使用友元,编译出错fatal error C1001: INTERNAL COMPILER ERROR (compiler file 'msc1.cpp', line 1786) 的解决
Opengs7
博客等级 码龄16年 4粉丝 10原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值