review makefile

今天重新复习了makefile

关于makefile,就是一系列规则,用来规定对文件编译,连接,汇编的规则

先说一下,在gcc后面
-o表示对生成的文件取另外一个名字
-c表示编译不连接
-C表示进入一个目录


首先,在一个文件夹下创建一个main.c函数
实现为
#include "kaito.h"

void main()
{
    printf("This is the main function\n");
    func1();
}

在同一个文件夹下创建kaito.h
实现为
#include

在同一文件夹下创建func1.c
实现为
void func1()
{
    printf("This is the function1!(be the same folder with main)\n");
}

以上三个文件就是我们要操作的文件,需要对他们进行编译、连接,所以在同一文件夹下创建一个makefile(或者Makefile)来按一定规律编译连接他们
实现为
obj=main.o func1.o

mk : $(obj)
gcc $(obj) -o mk
%.o : %.c
gcc $< -c -o $@
clean :
-rm *.o mk

这里面第一行obj是一个变量,在makefile里面,变量都可以看做字符串,我觉得更准确的应该看做宏定义,因为在用变量的时候就相当于把变量后面的内容直接代到里面来用
所以下面出现$(obj)的地方就相当于是main.o func1.o,$()是对一个变量的引用
比如下面两行
mk : $(obj)
gcc $(obj) -o mk
表示我们想要生成mk这个文件,需要有冒号:后面的文件存在作为依赖
具体这些文件的操作就是用gcc来编译,把$(obj)所代表的文件编译、连接成mk文件(在不写-c的情况下,gcc默认会帮你连接的(在存在相互调用的情况下,若不调用想连接则用ld不用gcc))

接下来%.o: %.c表示,对于任何.o文件都由与他名字一样的.c文件作为依赖来编译
gcc $< -c -o $@
其中$<表示对应的依赖.c,$@表示对应的要生成的文件.o

clean :
-rm *.o mk
当执行make clean的时候就是删除所有.o文件 和mk,-rm和rm的区别就在于对-rm对于要删除不存在的文件不会报错,让rm去删除不存在的文件时,她会报错


这样,简单的makefile就算完成了

但是在一个工程里面,往往有许多文件夹,我们要用来作为依赖的文件可能与现在的文件不在同一个文件夹下,我们在make的时候希望进入子目录去用子目录里的文件,这样我们需要在子目录也建一个makefile,来做一些规则

现在我在main所在的文件夹下创建一个子目录lib,里面有func2.c和func3.c
func2.c实现
void func2()
{
    printf("This is the function2!(not the same folder with main)\n");
    func3();
}

func3实现
void func3()
{
    printf("This is function3(used in func2)\n");
}

如果单单要编译这两个文件,并且连接起来(注意没有其他文件调用这两个文件,则不能用gcc,改用ld),makefile则是
obj=func2.o func3.o

lib.o : $(obj)
ld $(obj) -r -o lib.o

%.o : %.c
gcc $< -c -o $@

clean : 
-rm *.o
这里我们要生成的文件叫做lib.o,用来上一层目录的连接用

同样需要修改上一层的main.c函数和makefile
main.c实现
#include "kaito.h"

void main()
{
    printf("This is the main function\n");
    func1();
    func2();
}

顶层makefile实现
obj=main.o func1.o lib/lib.o

mk : $(obj)
gcc $(obj) -o mk
%.o : %.c
gcc $< -c -o $@
lib/lib.o : 
make -C ./lib
clean :
-rm *.o mk
make clean -C ./lib
在这次顶层makefile修改中,第一行中的lib/lib.o表示在子目录lib下的lib.o文件(也作为依赖)
而lib目录下的lib.o文件的生成则依赖于它所在的目录的makefile,所以
lib/lib.o : 
make -C ./lib
-C表示 先进入./lib目录,然后执行相当于在终端下的make一样;就是进入/lib/目录,执行make(这样就会得到lib/lib.o这个文件了),最后的make clean同理

文件结构
顶层目录
review <wbr>makefile
子目录
review <wbr>makefile
而实现的效果是
review <wbr>makefile

review <wbr>makefile

review <wbr>makefile

make clean就不演示了,在我写这篇文章的时候差点浏览器卡死,吓得我就把虚拟机关了(那是已经绝望了,以为辛辛苦苦打了这么多字又要重新写T_T。。。。。。)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章