虽然使用Linux已有多年时间,但是都是很简单的使用。简单来说是就基于windows的使用。即使在Linux上编程,都是非常简单的程序,只会使用gcc命令来简单编译。但当编写的代码模块划分明确时,文件数量也会增多,如果还只会用简单地编译将会是件非常烦恼的事,而且每次修改文件后,都要重复那种繁琐的操作,这并不是我们想要的结果。
Makefile文件帮助我们解决那想繁琐的操作,只要每次make一下,文件就已经编译成可执行文件了。
由于本人也是初学Makefile,我觉得以初学者的心态来讲述会比较让人接受。
关于Makefile的资料还不少,但对于初学者来说网上的资料都难以让人接受,为何这么说呢?网上资料要么很深入,一下子长篇大论(大哥内容太多,我怎么接受得了);要么太简单,并没有一步一步深入讲解(学回了简单的,想学进阶的,不知道哪个才对口)。
在网上找到了一个长篇大论(网址:http://bbs.chinaunix.net/thread-408225-1-1.html),个人感觉还好,不过就是因为太长篇,看了后面忘了前面,个人认为还是一边实践一边讲述比较好。如果觉得我在废话的可以直接到上面网址学习,我不会有什么意见,我本意也想大家交流学习。
个人认为Makefile并还单只是个文件,它里面隐含了很多内容,如果想一下子学会基本上是天才吧(因为我不聪明),所以如果想逐步认识Makefile,先不要把它当作文件,而要把它当作一种语言,不要低估Makefile的强大能力。
2、了解Makefile中最简单的结构
很多网上都有说这个,很了能更好地了解,我也废话多一次。
target : prerequisites
command //任意的shell 命令(前面空格为[tab]键,否则不能正常make)
1)target为目标名称(部分为自己的理解,叫法上可能不正规,但是表达意思上差不多,下同),即需要被生成的目标,这里可以是一个名称,也可以是一个.o文件;
2)prerequisites 为依赖关系,这里的意思是,要得到target必先要有prerequisites的关系。如果prerequisites为 a.c b.c 就表明要有这两个文件才能得到target。
3)command为目标动作,当达到上面prerequisites的依赖要求后,执行的动作,这里多数为Shell命令。command前面一定要[Tab]键,不能包含其它任何符号。
3、编写第一个Makefile文件
下面将讲述四种比较容易入门的Makefile文件编写,其中第三种是第二种的变形。第四种是第三种的变形,不过本质上1、3、4差别不大。
1.正规的Makefile
在这里简单地总结一下一些使用规则
1)
target : prerequisites
command //任意的shell 命令(前面空格为[tab]键,否则不能正常make)
2)
在Makefile可以通过定义变量来传递值
3)
可以通过简化编写,让make来推导
注:本人在测试时发现部分Makefile会在make时出错,可能是由于Copy时把空格、[Tab]等也放入其中。由于是空白,所以会误以为没字符,但make并这样认为。因此如果想直接测试上面的Makefile,请去掉不必要的空格及[Tab]。
由于自己还在学习当中,只能把学习到的部分写出来,后续将会把一些关于Makefile的使用技巧发上来。
Makefile文件帮助我们解决那想繁琐的操作,只要每次make一下,文件就已经编译成可执行文件了。
由于本人也是初学Makefile,我觉得以初学者的心态来讲述会比较让人接受。
关于Makefile的资料还不少,但对于初学者来说网上的资料都难以让人接受,为何这么说呢?网上资料要么很深入,一下子长篇大论(大哥内容太多,我怎么接受得了);要么太简单,并没有一步一步深入讲解(学回了简单的,想学进阶的,不知道哪个才对口)。
在网上找到了一个长篇大论(网址:http://bbs.chinaunix.net/thread-408225-1-1.html),个人感觉还好,不过就是因为太长篇,看了后面忘了前面,个人认为还是一边实践一边讲述比较好。如果觉得我在废话的可以直接到上面网址学习,我不会有什么意见,我本意也想大家交流学习。
个人认为Makefile并还单只是个文件,它里面隐含了很多内容,如果想一下子学会基本上是天才吧(因为我不聪明),所以如果想逐步认识Makefile,先不要把它当作文件,而要把它当作一种语言,不要低估Makefile的强大能力。
好了,废话少说,准备入正题:
1、创建自己的代码1. hello.h
void hello();
//--------------------------------------------
2. hello.c
#include<stdio.h>
#include"hello.h"
void Hello()
{
printf("Hello, world\n");
}
//--------------------------------------------
3. main.c
#include "hello.h"
int main(void)
{
Hello();
return 0;
}
好了,由于时间关系,这里已经准备了两个.c文件,一个.h文件,文件数里可以非常不确定,可以是1个也可以是N个。
2、了解Makefile中最简单的结构
很多网上都有说这个,很了能更好地了解,我也废话多一次。
target : prerequisites
command //任意的shell 命令(前面空格为[tab]键,否则不能正常make)
1)target为目标名称(部分为自己的理解,叫法上可能不正规,但是表达意思上差不多,下同),即需要被生成的目标,这里可以是一个名称,也可以是一个.o文件;
2)prerequisites 为依赖关系,这里的意思是,要得到target必先要有prerequisites的关系。如果prerequisites为 a.c b.c 就表明要有这两个文件才能得到target。
3)command为目标动作,当达到上面prerequisites的依赖要求后,执行的动作,这里多数为Shell命令。command前面一定要[Tab]键,不能包含其它任何符号。
3、编写第一个Makefile文件
下面将讲述四种比较容易入门的Makefile文件编写,其中第三种是第二种的变形。第四种是第三种的变形,不过本质上1、3、4差别不大。
1.正规的Makefile
helloworld : main.o hello.o #由于没有main.o和hello.o所以先会执行main.o,再到hello.o
gcc -o helloworld main.o hello.o #shell命令,最前面的一定是一个tab键
mian.o : mian.c hello.h #生成main.o文件
gcc -c main.c
hello.o : hello.c hello.h #生成hello.o文件
gcc -c hello.c
clean : #清除下列文件
rm helloworld main.o hello.o
我想不用我多说都明白上面的意思,如果有多个.c文件时,就应该多写N个target,这种方法在Makefile文件的规则里面就最简单的一种,不过,当多个文件时,显示有点不便 。因此有点比较偷懒的方法是用“*”通配符来表达不同的文件。
2.偷懒的Makefilehelloworld :
gcc -o helloworld *.c #shell命令,最前面的一定是一个tab键
clean : #清除下列文件
rm helloworld
其实这种本质上就是Shell命令,只是把它放在Makefile文件中而已,这种方法对于简单,结构关系单一的程序时有用,当程序关系复杂时,将不能使用。
3.较方便更改的Makefileobjects = main.o hello.o #变量声明与赋值
helloworld : $(objects) #使用变量时要用$()
gcc -o helloworld $(objects)
mian.o : mian.c hello.h
gcc -c main.c
hello.o : hello.c hello.h
gcc -c hello.c
clean :
rm helloworld $(objects)
这种方法方便在于当文件增加后,只要增加一个tartget外,只要修改objects就可以了,如果多处调用到objects时,将减少很多琐碎的工作
4.减少写依赖关系的Makefileobjects = main.o hello.o
helloworld : $(objects)
gcc -o helloworld $(objects)
$(objects) : hello.h #所有都依赖hello.h
mian.o : mian.c #make自动推导
print.o : hello.c #make自动推导
clean :
rm helloworld $(objects)
这种方法可以不用写各个文件都依赖的头文件,只要写一次,则可以让make自己推导,方便了不少。
4、总结在这里简单地总结一下一些使用规则
1)
target : prerequisites
command //任意的shell 命令(前面空格为[tab]键,否则不能正常make)
2)
在Makefile可以通过定义变量来传递值
3)
可以通过简化编写,让make来推导
注:本人在测试时发现部分Makefile会在make时出错,可能是由于Copy时把空格、[Tab]等也放入其中。由于是空白,所以会误以为没字符,但make并这样认为。因此如果想直接测试上面的Makefile,请去掉不必要的空格及[Tab]。
由于自己还在学习当中,只能把学习到的部分写出来,后续将会把一些关于Makefile的使用技巧发上来。