makefile的粗浅理解

来源:互联网 发布:雪利酒 知乎 编辑:程序博客网 时间:2024/05/22 12:21

最近学习了makefile,写一点点对makefile的理解

linux下:

mkdir  demo

在demo下面写了几个文件


vi add.c

int add(int a,int b)

{

return a+b;

}


vi sub.c

int sub(int a,int b)

{

return a-b;

}


vi mul.c

int mul(int a,int b)

{

return a*b;

}


vi del.c

int del(int a,int b)

{

return a/b;

}


vi head.h

#ifndef

#define

int add(int a,int b);

int sub(int a,int b);

int mul(int a,int b);

int del(int a,int b);

#endif


vi main.c

int main(int argc,char **argv)

{

int a=12,b=3;

printf("a+b=%d",add(a,b));

printf("a-b=%d",sub(a,b));

printf("a*b=%d",mul(a,b));

printf("a/b=%d",del(a,b));

return 0;

}

接下来写makefile

写makefile的思路(或者是规则):目标文件(target) 依赖于.o文件并且经过gcc -o的编译后才能生成target。.o文件依赖.c文件并且经过gcc -c的编译后才能生成.o文件

(1)

target = main     //target英文是目标的意思,在这起的只是一个替换作用,写成其他也可以(比如targe或tar),main也一样(写成m也行)为了方便理解这是一个目标文件(所以写成target)

objs = add.o sub.o mul.o del.o main.o   //objs 和target一样的道理

$(target):$(objs)       //“:”前面的表示你生成的文件,“:”后面的表示生成前面的文件需要什么文件,下面的cc是要执行什么操作才能生成目标文件(“:”前面的文件)

  cc -o $(target) $(objs)  //写cc -o的时候,如果不写$(target),cc(gcc)会给出预设的可执行文件a.out,写上之后就会生成可执行的文件main了。如果你想生成.a.out,那就把target=main改写成target=a.out

main.o :main.c head.h   //要生成main.o依赖于main.c和head.h

cc -c main.c

add.o: add.c          //要生成add.o文件需要依赖于add.c文件,同时你也要编译add.c 才能生成add.o嘛,下面的类似

cc -c add.c

sub.o :sub.c

cc -c  sub.c

mul.o: mul.c

cc -c mul.c

del.o :del.c

cc -c del.c

.PHONY : clean  // .PHONY意思表示clean是一个“伪目标”,。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然,clean的规则不要放在文件的开头,不然,这就会变成make的默认目标,相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后”。 

clean:                //执行make clean 就可以把clean中包含的文件去掉了,重新修改再编译时会很方便

-rm -rf $(objs) $(target)


(2)make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。 只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile再也不用写得这么复杂。当我们把所有的.c文件和cc -c 或者-o去掉之后,新的makefile又出炉了。

target=main

objs = add.o sub.o mul.o del.o main.o //只要看到.o文件,那么.c文件和cc -c .c   make都会自动找到编译,不需要你写

$(target):$(objs)

main.o: head.h

.PHONY:clean   

clean:

-rm -rf $(objs) $(target)

(3)如果我们要写的是大的项目中有几十个,几百个.c,.o的时候,还像上面的objs那样写,肯定会很麻烦,于是有了下面的这种写法

http://blog.sina.com.cn/s/blog_60cbc1700100nuhz.html打开这个链接会有wildcard以及patsubst的详细解释

target =main     //目标文件

src = $(wildcard *.c)  //所有的.c文件

objs = $(patsubst %.c ,%.o,$(src)) //把src中的所有.c文件转换成.o文件

$(target) :$(objs) //要想生成目标文件 需要依赖.o文件,而.o文件就是$(objs)

main.o : head.h  //要想生成main.o ,需要依赖head.h和 main.c

.PHONY:clean   

clean:

-rm -rf $(objs) $(target) //-rm -rf必须写上,不写的话,make clean 会报错。我们在终端下删除的时候是用rm -rf(这样目录,文件都能删除)make clean只是一个提示,进入clean:里面后的内容才是开始执行什么动作。如果只写要删除的内容($(objs)),不写删除的指令(rm -rf).就会出错。还有一个要注意的是clean之后的内容要写到第二行,如果和clean写在同一行,就会报错(有知道原因的老哥,留个言微笑

-rm -rf也可替换成$(RM),$(RM)表示rm -f ,你也可以写成rm -i,每次make clean会提示你是否要删除目标文件。

all的用法:当你要生成多个目标时,用all方便

如果想看更详细的makefile可以打开这个链接:http://blog.csdn.net/ethan_novice/article/details/7202484


1 0
原创粉丝点击