Makefile学习笔记(一)

Makefile学习笔记(一)

概述

​ Makefile在Linux环境开发中时常被用到,虽然有各种功能强大的IDE帮我们做了make这一步,但很多开源代码依旧还在使用makefile,makefile定义了整个项目的编译规则,了解makefile不仅可以加深对于源码结构的理解,也能从makefile文件中了解到源码之间的依赖关系以及编译次序。

显式规则

​ Makefile中最常见的就是显式规则,即由Makefile编写者显式指定的源码编译规则。Makefile文件由一组或者多组依赖关系和规则组成,每个依赖关系由一个目标及该目标所依赖的源文件组成,给个简单的例子:

main.o: main.cpp

​ 上面的表达表示了目标main由其依赖的main.cpp文件组成,目标一般是一个单独的可执行文件,这个例子表达的仅仅是一个依赖关系,仅有依赖关系对于源码的编译并无用。这时就需要规则了,规则是详细表达依赖关系具体创建过程的一组语句,更具体点,也可以说是一些shell命令。对于上面的依赖关系,其完整的表达形式应如下:

main.o: main.cpp

​ clang++ -o main.o -c main.cpp

​ 编译器gcc/g++还是clang/clang++都无所谓,对于makefile,只要依赖关系下的规则能正确生成相应的可执行文件即可。

make命令常用选项及参数

​ make命令有很多选项,但常用的仅有3个:

  • -k: make发现错误时,仍继续进行,附加此选项可以一次发现项目源码中的所有未编译成功的源文件;
  • -n: 列出make将要执行的操作步骤,但并不执行这些步骤,附加此选项可以用来检验makefile将要执行的命令是否如我们预期;
  • -f filename: 用于为make命令指定执行的makefile文件,若无此选项,make则按默认方式选择makefile文件。

​ 在未指定特定目标时,make仅会创建makefile中出现的第一个目标,这里有个例子可以说明下,有时候有些开源软件的编译安装步骤在文档中会写作:

make all

这是在make之后显式地指定生成的目标。如果不指定,则默认创建makefile中出现的第一个目标。因此如果项目源码需要创建多个目标,则会失败,这里更好地解决办法是使用一个伪目标all作为第一个目标,all不会生成名为all的可执行文件,但其依赖的多个目标则会被创建,举个例子,如果项目需要生成可执行文件main以及手册main.1,则可以这样写:

all: main main.1

​ 如此,就可以使make创建多个makefile中指定的目标了。

一个完整的例子

main: main.o test.o 
    clang++ -o main main.o test.o 
main.o: main.cpp 
    clang++ -o main.o -c main.cpp 
test.o: test.cpp test.h 
    clang++ -o test.o -c test.cpp 

你可能感兴趣的:(C/C++)