Makefile脚本
编写第一个Makefile脚本文件,本文仅仅为个人学习,记录自己初学makefile的过程,就掌握下面一些常用的命令就可以开始编写属于我们自己的makefile脚本文件了。
言归正传,GNU的make有许多的内容,还是让我们开始吧
一.编译过程中发生了什么
二.Makefile编写规则
三.预定义命令
一.编译过程中发生了什么
1) 在我们编写一个简单的c程序,编译后我们可以发现生成了一个可执行的文件,那么在从编译中具体进行了那些过程呢?
2)预处理->编译(汇编生成)->链接生成可执行文件->运行
下面以一个简单的c程序来介绍编译过程
#include <stdio.h>
int main(void)
{
printf("hello linux\n");
return 0;
}
1 > gcc -E demo.c -o demo.i
2> gcc -S demo.i -o demo.s
3> gcc -c demo.s -o demo.o
4> gcc demo.o -o demo
5> ./demo (运行)
上面执行过程中和此句命令功能一样,只是在执行过程中也默认进行了上面的过程
gcc demo.c -o demo
二.Makefile编写规则
在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
/*
下面就以一个简单的程序来按照编写规则写我们第一个简单的Makefile
注意在编写Makefile时命名第一个必须大写或者都小写file这个不可以大写
Makefile /makefile 这两种写法均可以
*/
target… : prerequisites …
command
…
…
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。
编写Makefile
//下面的例子中用了三个.c文件
//demo.c func1.c func2.c
//1.demo.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
int x,y;
scanf(argv[1],"%d",&x);
scanf(argv[2],"%d",&y);
printf("result1: %d\n",add(x,y));
printf("result2: %d\n",sub(x,y));
return 0;
}
//2.func1.c
#include <stdio.h>
int add(int x ,int y)
{
return x+y;
}
//3.func2.c
#include <stdio.h>
int sub(int x,int y)
{
return (x-y);
}
//注意在Makefile中注释为#并且命令下面必须以tab空格后再开始编写
# create first rule
/********************第一种写法************
pro :demo.c func1.c func2.c
gcc demo.c func1.c func2.c -o pro
*****************************************/
/*******************第二种写法**************
MOBJ = demo.o fucn1.o func2.o
CC = gcc
pro:$(MOBJ) -o pro
$(CC) $(MOBJ) -o pro
$(CC) S^ -O $@
4*****************************************/
/*****************第三种写法*****************/
pro: demo.o func1.o func2.o
gcc demo.o func1.o func2.o -o pro
demo.o:demo.c
gcc -c demo.c
func1.o :func1.c
gcc -c func1.c
func2.o: func2.c
gcc -c func2.c
.PHONY:clean
clean:
rm demo.o func1.o func2.o pro
.PHONY:install
install:
cp pro /usr/local/pro
.PHONY:uninstall
uninstall:
rm /usr/local/pro
运行结果
make clean清除命令
.PHONY 伪目标(没有依耐关系也不会生成文件)
三.预定义命令
下面这些是看视频的时候截得屏
还是以上面的例子编写一个综合命令的Makefile
#create first makefile
MOBJ = demo.o func1.o func2.o
CFLAGS = -g -c
CC = gcc
Pro:$(MOBJ)
ifneq ($(CC),gcc)
gcc $^ -o $@
else
$(CC) $^ -o Pro2
endif
demo.o :demo.c
$(CC) -c demo.c
fucn1.o:func1.c
$(CC) -c func1.c
func2.o:func2.c
$(CC) -c func2.c
.PHONY:clean
clean:
sudo rm $(MOBJ) Pro
.PHONY:install
install:
cp Pro /usr/local/Pro
.PHONY:uninstall
uninstall:
sudo rm /usr/local/Pro
运行结果
四、多级目录编译
ELF=main
CC=gcc
#SRC=$(wildcard *.c)
SRC=$(shell find -name '*.c') #according path to find .c
object=$(SRC:.c=.o) #将.c 变成.o
$(ELF):$(object)
$(CC) $^ -o $@
$(object): #这里使用自定推动方式
.PHONY:clean
clean:
rm -f $(object) $(ELF)
通过上面的知识点快去编写自己的Makefile吧