欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux下的make和Makefile

程序员文章站 2024-03-11 19:52:13
...

Linux下的make和Makefile

背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编
    译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
  • Makefile—是一个普通的文本文件,这个文件中记录着一个项目的编译流程以及规则
  • make—是Makefile的解释器(make是一个程序),他会找到Makefile文件,按照逐行解释执行其中记录的项目构建规则,最终完成项目的构建
  • 所以make/Makefile要说的就是Makefile的编写规则以及make的解释执行规则

什么是make和Makefile

  • 无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到make。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且如此多的源文件,如果每次都要借助gcc命令进行编译的话,那对程序员来说简直就是一场灾难。而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。因此,有效的利用make和makefile工具可以大大提高项目开发的效率。
  • make及其描述文件makefile. Makefile文件Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。
  • Makefile文件作为一种描述文档一般需要包含以下内容:◆ 宏定义◆ 源文件之间的相互依赖关系◆ 可执行的命令Makefile中允许使用简单的宏指代源文件及其相关编译信息,在Linux中也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()

Makefile

Makefile的编写规则
hello:hello.o
    gcc hello.o -o hello
hello.o:hello.s
    gcc -c hello.s -o hello.o
hello.s:hello.i
    gcc -S hello.i -o hello.s
hello.i:hello.c
    gcc -E hello.c -o hello.i
test:test.c
    gcc test.c -o test
(保存并退出就可以了)
make就是找到目标对象,去执行指令
依赖关系
  • 上面的文件hello(也就是即将要生成的文件),它依赖hell.o
  • hello.o , 它依赖hello.s hello.s , 它依赖hello.i
  • hello.i , 它依赖hello.c
举个例子
  • 有下个几个文件:main.c ; add.c ; cout.c ; hello.c main.h 共5个文件。之间的关系为每个.c文件中都include main.h文件在main.c文件中调用了其他3个.c文件,makefile如下:
    Linux下的make和Makefile
    执行make之后,文件目录下就有main.o ;add.o ;hello.o ;cout.o ;test test就是可执行文件,./test 就能输出结果。这里前几行也可以这样写:
    Linux下的make和Makefile
  • 伪对象----上面的clean被称为伪目标,makefile不生成这个文件,它一般也没有依赖文件,因此make无法生成它的依赖关系和决定它是否要执行。只有通过显示地指明这个目标才能让其生效。即:make clean 就能执行clean下的命令;注意的是伪目标的取名不能和文件名重名;也可以用.PHONY来声明伪目标
预定义变量—make中预先定义好的变量,通常是使用在命令中的变量
  • $^----所有的依赖对象
  • $<—依赖对象的第一个
  • aaa@qq.com—目标对象

make

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

  • make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  • 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件,并把这个文件作为最终的目标文件。
  • 如果hello文件不存在,或是hello所依赖的后面的hello.o文件的文件修改时间要比hello这个文件新(可以用touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
  • 如果hello所依赖的hello.o文件不存在,那么make会在当前文件中找目标为hello.o文件的依赖性,如果找到则再根据那一个规则生成hello.o文件。(这有点像一个堆栈的过程)
  • 当然,你的C文件和H文件是存在的啦,于是make会生成 hello.o 文件,然后再用 hello.o 文件声明
    make的终极任务,也就是执行文件hello了。
  • 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  • 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  • make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
    Linux下的make和Makefile

make的执行规则

  • 可以理解成一个递归的过程
  • 但是如果多个目标对象依赖于同一个依赖对象的话,那么他只会生成第一个目标对象
    Linux下的make和Makefile
    Linux下的make和Makefile
相关标签: Linux