Makefile编写

程序的编译和链接

使用C、C++编写可执行文件,首先要把源文件编译成中间代码文件,Linux下是.o文件,即Object File,这个动作叫做编译(complie)

然后再把大量的Object File合成执行文件,这个动作叫链接(link)

一个项目会拥有成百上千个源程序文件,再使用G++ or GCC会很麻烦。于是Makefile闪亮登场。

Makefile确定整个工程的编译规则,只需要一个make命令,就可以实现“自动化编译”。

make是一个解释Makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下的GNU的make。


Make工作原理

通常在一个项目中,我们的规则是:

  1. 如果这个工程没有被编译过,那么我们的所有C文件都要编译并被链接。
  2. 如果这个工程的某几个C文件被修改过,那么我们只需要编译被修改的那几个C文件,并链接成生可执行文件。(链接目标程序)
  3. 如果这个工程的头文件被改变了,那么我们需要编译引用了这个几个头文件的C文件,并链接生成可执行文件。(链接目标程序)

只要我们的Makefile写的够好,我们只用一个make命令就可以完成,make命令会自动智能地根据当前文件的修改情况来确定哪些文件需要重新编译,从而自己编译需要的文件和链接生成可执行文件。

Makefile的规则:

target … :prerequisites…

command

  • target是一个目标文件,可以是Object File,也可以是可执行文件。还可以是一标签。
  • prerequisites就是要生成那个target所需要的文件或是目标。
  • command就是make需要执行的命令。(任意的Shell命令)

这是一个文件依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义要在command中。说白一点,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。

这就是Makefile的规则,也就是Makefile中最核心的内容。

示例:

test_demo:test01.o test02.o main.ogcc -o test_demo test01.o test02.o main.otest01.o:test01.h test01.cgcc -c test01.ctest02.o:test02.h test02.cgcc -c test02.cmain.o: test01.h test01.c test02.h test02.c main.cgcc -c test01.c test02.c main.cclean:rm test_demo test01.o test02.o main.o

Make工作流程

  1. make会在当前目录下找到名字叫做"Makefile" 或 "makefile"的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),例如上面示例中的test_demo,并把这个文件作为最终的目标文件。
  3. 如果目标文件(target)不存在,或是target后依赖的.o文件的文件修改时间要比目标文件新,那么,它就会执行后面所定义的命令来重新生成目标文件。
  4. 如果目标文件(target)所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖,如果找到则再根据那个规则生成.o文件。
  5. 如果文件依赖都齐全,则会正常执行,先生成.o文件,再链接生成目标文件。


Make变量

一个Makefile中我们发现经常会有重复的内容,例如上面示例中的:

test01.o test02.o main.o

如果我们需要再加入一个新的.o文件,那么好几个地方都需要修改,可能会忘记并导致编译失败。

所以,为了makefile的易维护,在makefile中我们可以使用变量。makefile的变量也就是一个字符串。可以理解为C语言中的宏。

变量定义:

objects = test01.o test02.o main.o # 使用Shell script的语法

示例:

objects = test01.o test02.o main.otest_demo: $(objects)gcc -o test_demo $(objects)test01.o:test01.h test01.cgcc -c test01.ctest02.o:test02.h test02.cgcc -c test02.cmain.o: test01.h test01.c test02.h test02.c main.cgcc -c test01.c test02.c main.cclean:rm $(objects) test_demo

Make自动推导

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

只要make看到一个.o文件,它就会自动地把.c文件加在依赖关系中,如果make找到一个test01.o,那么test01.c就是它的依赖文件。并且gcc -c test01.c也会被推导出来。

示例:

objects = test01.o test02.o main.otest_demo: $(objects)gcc -o test_demo $(objects)
test01.o:test01.h
test02.o:test02.h
main.o: test01.h test02.h
clean:rm $(objects) test_demo

还可以再简洁些

objects = test01.o test02.o main.otest_demo: $(objects)gcc -o test_demo $(objects)$(objects):test01.h test02.hclean:rm $(objects) test_demo


关于我:

  1. 我的博客半生瓜のblog or 半生瓜のblog
  2. 我的微信公众号【四次猿口袋】
  3. 我的QQ交流群:805814463

【Makefile】简单的Makefile编写相关推荐

  1. 一个简单的makefile编写VCS仿真

    一个简单的makefile编写VCS仿真 1 VCS简介 VCS是编译型Verilog模拟器,它完全支持OVI标准的Verilog HDL语言.PLI和SDF. VCS具有行业中较高的模拟性能,其出色 ...

  2. 简单的makefile文件编写

    习惯了windows下ide创建工程已经代码的编写,然后一键运行,很简单,因为很多事ide都帮我们做了,但是linux下不一样,需要手动编译,执行一条条的命令,一般工程都是由于很多文件组成的,比如c+ ...

  3. Makefile编写及一个简单的Makefile架构实现

    Makefile编写及一个简单的Makefile架构实现 Makefile常用命令 GCC/G++常用编译参数 简单Makefile框架实现 使用CMake构建项目 Makefile常用命令 make ...

  4. 手动建立makefile简单实例解析

    假设我们有一个程序由5个文件组成,源代码如下: /*main.c*/ #include "mytool1.h" #include "mytool2.h" int ...

  5. mac linux makefile,Makefile简单入门

    最近工作编译程序一直在用别人写的Makefile,但是没有系统的学习过,趁着放假学一波 makefile 0x00 Makefile 概述 一个企业级项目,通常会有很多源文件,有时也会按功能.类型.模 ...

  6. 一个最简单的Makefile例子(转)

    原文地址:http://hi.baidu.com/hellosim/blog/item/42e78341b40c3e8db2b7dce3.html 转载请注明出处 1.hello.c #include ...

  7. 【Linux系统编程学习】 Makefile简单入门

    此为牛客网Linux C++课程1.10&1.11&1.12 的课程笔记. 0. Makefile介绍 1. Makefile文件命名与规则 示例: 使用vim编写如下名为Makefi ...

  8. 生成简单的Makefile文件(Python实现)

    在linux下写几个测试程序,还要一行行的输入g++命令进行编译,当经常改测试代码的时候,那一次次的敲(或者一次次的上线箭头选)也感觉不爽,不如make来的快.用Makefile的好处就不用多说了,这 ...

  9. 简单的makefile模板

    makefile不是总用到,每次用到的时候总要重新找资料,有点麻烦(怪自己基础知识不扎实,汗).留一个通用模板放这,方便以后使用 CC = gcc CXX = g++ LINK = g++ CFLAG ...

  10. Makefile:简单的makefile列子

    现在我要编译一个Hello world,需要如下三个文件: 1. print.h #include<stdio.h> void printhello(); 2. print.c #incl ...

最新文章

  1. Maven学习总结(七)——eclipse中使用Maven创建Web项目
  2. android152 笔记 2
  3. MATLAB从入门到精通-matlab图像处理标记点追踪识别程序
  4. 每天一道LeetCode-----判断一个数是否是happy number(每一位的平方和最终为1)
  5. 机器学习经典算法实践_服务机器学习算法的系统设计-不同环境下管道的最佳实践
  6. ROS入门_1.10 理解ROS服务和参数
  7. 动手学PaddlePaddle(4):MNIST(手写数字识别)
  8. 社交app应用开发 客户端+服务器源码
  9. java方法报错_.setUndecorated 方法报错
  10. Simulink之三相桥式全控整流电路
  11. maven向本土仓库导入jar包(处理官网没有的jar包)
  12. 2021年秋季Python程序设计相关课程教材推荐
  13. isupper()函数
  14. linux grep多条件查询
  15. 小白刷LeeCode(算法篇)7
  16. linux装回win10系统无法开机,Win10/Linux双系统删除之后出现grub无法开机修复方法...
  17. jstack 工具 查看JVM堆栈信息
  18. git runner 配置_GitLab Runner安装注册配置管理
  19. 解密Uber自动驾驶系统,警方披露撞人案细节
  20. CSC7715 同步整流

热门文章

  1. 如何快速把英语单词导入有道词典
  2. 1301_两种方式为开发板增加串口监控功能
  3. 【Python游戏】Python各大游戏合集:超级玛丽、天天酷跑、我的世界、魔塔、雷霆战机 | 附带源码
  4. CentOS7.4 更改SSH端口号
  5. 计算机基础知识五笔,教你简单快速学习五笔打字
  6. 有意思的域名Hack网站
  7. 基于华为SMProxy开发cmpp2.0(跳坑版)
  8. 这届抢票软件为什么不行?
  9. Win10注册.bat或.exe成为系统服务(NSSM)
  10. maven本地仓库地址更改