Makefile常用知识点总结

Makefile常用知识点总结

1. Makefile的格式

生成的目标(target,...):生成目标所需要的依赖(prerequisites,...)
	生成目标用到的命令(command)
	...
	...

target通常为你要生成的目标文件包括可执行文件或者库文件,(也可以是仅仅是一个标签,即伪目标,不真实存在的目标,常见的伪目标是clean,用于清理编译生成的垃圾文件)。

prerequisites 生成该target 所依赖的文件和或其他target

command 该target 要执行的命令(任意的shell 命令)

Makefile就是一个定义可执行文件生成顺序关系的文件,根据定义的依赖关系,从首个目标开始通过递归的方式,查找需要的依赖,如果没有则调用其他的target的生成,并最终生成Makefile中首个定义的目标文件。每个target的生成通过下面的shell命令实现。

实例

例如我们要利用Makefile编译下main两个文件main.c、welcome.c生成可执行文件main

main.c:

#include<stdio.h>
void welcome();
int main()
{
    printf("Hello World!\n");
    welcome();
    return 0;
}

welcome.c:

#include<stdio.h>
void welcome()
{
    printf("Welcome to QingDao!\n");
}

所用到的gcc编译命令为

gcc -o main main.c welcome.c

这里我们只有一个生成目标,即可执行文件main,所以Makefile应该这样写

main:main.c welcome.c  				#目标:依赖
	gcc -o main main.c welcome.c	#生成目标所执行的命令

请记住这个文件后面的说明全部以它为例

2. Makefile规则

使用变量

变量的含义可以理解成C语言中的宏定义,是一种字符串的替换。

比如上面的例子我们可以这样写:

CC=gcc
OBJ=main.c welcome.c
main:$(OBJ)              		#目标:依赖    
	$(CC) -o main $(OBJ)     	#生成目标所执行的命令

这样写的效果与第一小节的Makefile等价,科学地使用变量可以提高可维护性,便于Makefile的修改。

自动化变量

自动化变量可以理解成是Makefile规则中已经自动定义好的变量。

常见的自动化变量$@、$<、$^、$%和$?,常用的为u含义如下:

$@:目标的遍历值
$<:依赖的遍历值
$^:依赖的集合
$%:当库为生成目标时,库中所包含的成员名,不是库是为空
$?:所有比目标新的依赖目标的集合,以空格分割

常用的为前三个,在1节的Makefile文件中,他们代表的实际变量值

$@:依次代表"main",因为只有一个目标^_^
$<:依次代表"main.c"和"welcome.c"
$^:代表"main.c welcome.c"
清理

每个Make file中都应添加一个清理文件的规则(伪目标)clean,通过rm命令清理不必要的文件,这是建议而不是强制要求,为的是方便重新编译和保持文件的清洁。

通配符

Makefile中支持的通配符为*,?,~。

注意:变量的定义中不能直接使用通配符,需要配合使用函数。

~代表当前用户的家目录,Window下为HOME环境变量的值。

*代表任意字符,*.c代表所有的.c文件,故1节中的Makefile也可以写成这样:

main:*.c  				#目标:依赖
	gcc -o main *.c		#生成目标所执行的命令

3. Makefile中的函数

Makefile中的函数并不多这里我们介绍几个常用的其余可以借鉴《跟我一起写Makefile》。

Makefile中的函数跟变量的使用形式很像,也用$来标识,函数名与变量之间空格分隔,不同变量之间使用逗号,分割,其语法如下:

$(<function> <arguments>)

或是

${<function> <arguments>}

这里我们统一都是用圆括号(好记^_^)。

下面介绍几个常用的函数。

subst

${subst <from>,<to>,<text>}

将<text>这中的<from>字符全部替换成<to>字符,返回替换后的字符串

patsubst

${subst <from>,<to>,<text>}

与subst类似,不同的是patsubst会以单词为单位进行替换,查找单词是否符合<from>的规则,并将其替换成<to>中定义的形式。

filterfilter-out

$(filter <pattern>,<text>)

过滤函数,<pattern>为匹配规则不同的是filter保留符合规则的字符串,而filter-out去除符合规则的字符串。

以下不太常用

sort

$(sort <list>)

排序列表。

word

$(word <n>,<text>)

中的第n个单词。

4. 生成库文件

无论是生成静态库还是动态库第一步都是生成与位置无关的.o文件。

gcc -fPIC -c *.c
生成动态库
gcc -shared -Wl,-soname,lib*so.l -o lib*so.1.10 *.o
生成静态库

静态库的生成依靠ar打包命令,如下:

ar rcs lib*.a *.o

使用动态库或者动态库只需要把库文件当作gcc的输入即可。

使用ldd命令可以查看可执行文件所以来的动态链接库,共享库使用中如果提示找不到动态链接库,需要将共享库所在目录添加到相应的ld.conf文件中,再使用ldconfig -v更新即可,系统会自动生成带主版本号的链接库文件,可执行文件按照编译时的主版本号查找动态链接库,主版本号相同代表可以兼容。

结束语

本文是作者个人对Makefile的学习过程的简单总结,方便新手入门,同时作者本人也在不断学习中,如果存在错误或者疏漏,欢迎大佬来指正错误和补充内容。

如果有大佬或者和我一样对Linux感兴趣的小伙伴欢迎找我私信交流学习经验。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只双鱼儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值