之前一直是用java的,最近工作中需要在Linux中写一个C++程序,之前的写法很不规范,只有一个CPP。记录一下关于makefile的相关知识

想要完整的了解相关内容,推荐看这本书《程序员的自我修养--链接、装载与库》

想要快速的了解可以看这个大神写的博客https://seisman.github.io/how-to-write-makefile/overview.html

写的比较早了,可以挑着看

为什么使用make和makefile

在linux系统中make是一个非常重要的编译命令,不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或makeinstall。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile 带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率

make

1.make的工作原理

当make 命令被执行时,它会扫描当前目录下Makefile或makefile文件找到目标以及其依赖。如果这些依赖自身也是目标,继续为这些依赖扫描Makefile 建立其依赖关系,然后编译它们。一旦主依赖编译之后,然后就编译主目标,假设你对某个源文件进行了修改,你再次执行make 命令,它将只编译与该源文件相关的目标文件,因此,编译完最终的可执行文件节省了大量的时间

## 2.make命令的参数

-f:指定“makefile”文件;

-i:忽略命令执行返回的出错信息;

-s:沉默模式,在执行之前不输出相应的命令行信息;

-r:禁止使用build-in规则;

-n:非执行模式,输出所有执行命令,但并不执行;

-t:更新目标文件;

-q:make操作将根据目标文件是否已经更新返回"0"或非"0"的状态信息;

-p:输出所有宏定义和目标文件描述;

-d:Debug模式,输出有关文件和检测时间的详细信息。

-C dir:在读取makefile 之前改变到指定的目录dir;

-I dir:当包含其他makefile文件时,利用该选项指定搜索目录;

-h:help文挡,显示所有的make选项;

-w:在处理makefile之前和之后,都显示工作目录。

3.make命令的隐藏过程

这部分在上面那本书里有很详细的解释,但是有好几百页,想了解的话自己看吧。

1.预编译

预编译过程相当于执行

gcc -E hello_world.c -o hello_world.i

预编译过程主要处理以#开头的预处理指令,#include #define等,处理过程如下:

1 将所有#define删除,并展开所有宏定义

2 处理所有条件预编译指令#if #ifdef #elif #else #endif等

3 处理#include 预编译指令,将包含的文件插入到预编译指令的位置(递归进行,所包含的文件可能包含其他文件)

4 删除所有注释// /* */

5 添加行号和文件名标识,如:#2 hello_kitty.c 2 ,用于编译时编译器产生调试信息和编译时产生的错误和警告时能显示行号。

6 保留说有的#pragma编译器指令

经过预编译的.i文件,不包含任何宏定义,并且所包含的文件也被插入进来。

宏定义:https://www.cnblogs.com/zhizhiyu/p/10155614.html

make命令的隐藏过程

1.预编译

预编译过程相当于执行

gcc -E hello_world.c -o hello_world.i

预编译过程主要处理以#开头的预处理指令,#include #define等,处理过程如下:

1 将所有#define删除,并展开所有宏定义

2 处理所有条件预编译指令#if #ifdef #elif #else #endif等

3 处理#include 预编译指令,将包含的文件插入到预编译指令的位置(递归进行,所包含的文件可能包含其他文件)

4 删除所有注释// /* */

5 添加行号和文件名标识,如:#2 hello_kitty.c 2 ,用于编译时编译器产生调试信息和编译时产生的错误和警告时能显示行号。

6 保留说有的#pragma编译器指令

经过预编译的.i文件,不包含任何宏定义,并且所包含的文件也被插入进来。

宏定义:https://www.cnblogs.com/zhizhiyu/p/10155614.html

2.编译

编译过程就是将预编译产生的.i文件经过一系列的词法分析,语法分析,语义分析,中间代码生成,目标代码生成与优化。

编译原理

3.汇编

汇编器将汇编代码转换成成机器指令,每一条汇编语句对应一条或几条机器指令,生成目标文件。

4.链接(模块拼装)

将库文件与目标文件链接成可执行文件的过程。

概念

动态链接库:是一种不可执行的二进制程序文件,它允许程序共享执行特殊任务所必需的代码和其他资源。Windows平台上动态链接库的后缀名是”.dll”,Linux平台上的后缀名是“.so”。Linux上动态库一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。

静态链接库:这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

人们将每个源代码模块独立的编译,然后按照需要将它们组装起来,这个组装模块的过程就是链接

连接过程主要包括了地址空间分配、符号决议和重定位等

步骤:

1、 合并段表:将多个二进制可重定位文件中的段信息整合放到一个文件中

2、 调整段偏移:段表经过合并之后大小发生了变化,所以地址需要适当的偏移

3、 合并符号表:将多个二进制可重定位文件中的符号整合到一个文件中

4、 完成符号的重定位:连接器把每个符号定义与一个虚拟地址联系起来,然后修改所有对这些符号的引用,使得它们指向这个存储位置,从而重定位这些节。

makefile

包含内容:

  1. 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

  2. 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。

  3. 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。

  4. 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。

  5. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“/#”。

还有模式规则、自动化变量、检查规则等等很多的内容,由于不是每次都要用,就不再写了。

大概流程:

  1. 执行make指令,在当前目录下找到makefile文件
  2. 进入makefile文件找到最终目标
  3. 逐层查找最终目标的依赖
  4. 编译文件
  5. 链接可执行文件及库文件生成一个最终的可执行文件
  6. 删除中间生成的那些可执行文件

    写的文件不能放出来,可以参考一下这个:https://blog.csdn.net/X_BoLuoPi/article/details/106246779

还有一个常用模板

https://www.cnblogs.com/cyyljw/p/8137015.html

关于make及makefile的工作笔记的更多相关文章

  1. Makefile的学习笔记

    Makefile的学习笔记 标签: makefilewildcard扩展includeshellfile 2012-01-03 00:07 9586人阅读 评论(2) 收藏 举报  分类: Linux ...

  2. Makefile速查笔记

    Makefile速查笔记 Makefile中的几个调试方法 一. 使用 info/warning/error 增加调试信息 a. $(info "some text")打印 &qu ...

  3. 2016年第2周读书笔记与工作笔记 scrollIntoView()与datalist元素

    这一周主要是看了html5网页开发实例与javascript 高级程序设计,供以后翻阅查找.  html5网页开发实例第1章与第二章的2.1部分: 第1章内容: html5在w3c的发展史. 浏览器的 ...

  4. javascript - 工作笔记 (事件四)

    在javascript - 工作笔记 (事件绑定二)篇中,我将事件的方法做了简单的包装,  JavaScript Code  12345   yx.bind(item, "click&quo ...

  5. 工作笔记3.手把手教你搭建SSH(struts2+hibernate+spring)环境

    上文中我们介绍<工作笔记2.软件开发经常使用工具> 从今天開始本文将教大家怎样进行开发?本文以搭建SSH(struts2+hibernate+spring)框架为例,共分为3步: 1)3个 ...

  6. Sencha Touch2 工作笔记

    Sencha Touch2 工作笔记 Ext.dataview.List activate( this, newActiveItem, oldActiveItem, eOpts ) Fires whe ...

  7. 工作笔记5.JAVA图片验证码

    本文主要内容为:利用JAVA图片制作验证码. 设计思路: 1.拷贝AuthImageServlet.class图片验证码 2.配置web.xml 3.JSP中,调用封装好的AuthImageServl ...

  8. 读书笔记——《MySQL DBA 工作笔记》

    关于前言 作者在前言中提出的一些观点很具有参考价值, 梳理完整的知识体系 这是每一个技术流都应该追逐的,完整的知识体系能够使我们对知识的掌握更加全面,而不仅仅局限于点 建立技术连接的思维,面对需求,永 ...

  9. 《工作笔记:移动web页面前端开发总结》

    工作笔记:移动web页面前端开发总结 移动web在当今的发展速度是一日千里,作为移动领域的门外汉,在这段时间的接触后,发现前端开发这一块做一个小小的总结. 1.四大浏览器内核 1.Trident (I ...

随机推荐

  1. placeholder CSS设置

    IE似乎一个冒号才生效,而chrome则是两个冒号才生效 input::-webkit-input-placeholder{ color:red; } input:-ms-input-placehol ...

  2. log4j2.xml配置使用

    jar包: log4j-api-2.10.0.jar log4j-core-2.10.10.jar log4j-1.2-api-2.10.0.jar log4j-slf4j-impl-2.10.10. ...

  3. Microsoft Cloud App Security 微软的云应用安全

    1.概述 微软2015年收购的一家云安全创业公司 Adallom 正式推出产品,同时更名为微软 Cloud App Security.Adallom 成立于 2012年,是一家 SaaS 云安全公司, ...

  4. 删除GIT中的.DS_Store

    转载自:https://www.jianshu.com/p/fdaa8be7f6c3 .DS_Store 是什么 使用 Mac 的用户可能会注意到,系统经常会自动在每个目录生成一个隐藏的 .DS_St ...

  5. vue同时安装element ui跟 vant

    记一个卡了我比较久的问题,之前弄的心态爆炸各种问题. 现在来记录一下,首先我vant是已经安装成功了的. 然后引入element ui npm i element-ui -S 接着按需引入,安装插件 ...

  6. Python continue语句

    Python continue语句: 当执行到 continue 语句时,将不再执行本次循环中 continue 语句接下来的部分,而是继续下一次循环. lst = [7,8,9,4,5,6] for ...

  7. Python os.fpathconf() 方法

    概述 os.fpathconf() 方法用于返回一个打开的文件的系统配置信息.高佣联盟 www.cgewang.com Unix上可用. 语法 fpathconf()方法语法格式如下: os.fpat ...

  8. C/C++编程笔记:inline函数的总结!C/C++新手值得收藏!

    在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间. 在系统下, ...

  9. [SCOI2007]降雨量 线段树和区间最值(RMQ)问题

      这道题是比较经典的 \(RMQ\) 问题,用线段树维护是比较简单好写的.比较难的部分是判断处理.如果没有想好直接打代码会调很久(没错就是我).怎么维护查询区间最大值我就不再这里赘述了,不懂线段树的 ...

  10. Qt 之 Graphics View Framework 简介

    Graphics View Framework 交互式 2D 图形的 Graphics View 框架概述.自 Qt4.2 中引入了 Graphics View,以取代其前身 QCanvas.Grap ...