说来惭愧,自诩为一个程序猿,最近才接触makefile,记录一下,也算是卖出了第一步。
之前写c代码,一直用各种IDE,从VS到XCODE,一直傻瓜的点按钮编译,直到最近,才因为要将一些代码编译成SO文件,才第一次接触到makefile,也算是打开了一扇新的大门。
本文参考的博客:
https://www.cnblogs.com/wang_yb/p/3990952.html
https://blog.csdn.net/dongdong0071/article/details/52040559
一、makefile简介
说白了makefile就是将一系列shell命令写到一个文件里,通过make命令来执行,用以指明 .c .h 文件之间的互相依赖关系,从而使用gcc(g++)来编译项目。其作用就是方便我们管理一个项目中的众多文件,处理其互相间的依赖关系,方便编译。
1.1makefile基本格式
target ... : prerequisites ...
command
...
...
其中:
- target - 目标文件, 可以是 Object File, 也可以是可执行文件
- prerequisites - 生成 target 所需要的文件或者目标
- command - make需要执行的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头
1.2 GNU make 的工作方式
- 读入主Makefile (主Makefile中可以引用其他Makefile)
- 读入被include的其他Makefile
- 初始化文件中的变量
- 推导隐晦规则, 并分析所有规则
- 为所有的目标文件创建依赖关系链
- 根据依赖关系, 决定哪些目标要重新生成
- 执行生成命令
二、简单示例
makefile可以用于大型工程的编译,由于本人水平有限,太复杂的怕讲不清楚,本文只介绍入门级的示例。
//现在我要编译一个Hello world,需要如下三个文件:
1. print.h
#include<stdio.h>
void printhello();
2. print.c
#include"print.h"
void printhello()
{
printf("Hello, world\n");
}
3. main.c
#include "print.h"
int main(void)
{
printhello();
return 0;
}
要编译这些代码,对应的makefile如下:
helloworld : main.o print.o #helloword 就是我们要生成的目标
# main.o print.o是生成此目标的先决条件
gcc -o helloworld main.o print.o#shell命令,最前面的一定是一个tab键
mian.o : mian.c print.h
gcc -c main.c
print.o : print.c print.h
gcc -c print.c
clean :
rm helloworld main.o print.o
输入 make,便会调用gcc编译了,输入 make clean就会删除 hellowworld mian.o print.o。
从makefile代码中我们可以看到逻辑十分清晰:
- 要生成helloworld的程序需要main.o和print.o两个文件
- main.o的生成需要main.c和print.h
- print.o的生成需要print.c和print.h
以上便是makefile文件编写的逻辑思路,实际编写中,还有很多语法可以用来简化代码,如以上代码可以简化为:
objects = main.o print.o #应该叫变量的声明更合适
helloworld : $(objects) //声明了变量以后使用就要$()了
gcc -o helloworld$(objects)
mian.o : mian.c print.h
gcc -c main.c
print.o : print.c print.h
gcc -c print.c
clean :
rm helloworld $(objects)
更多的语法,此文就不详细介绍了。
不当之处,敬请大家批评指正!