maekfile初试以及笔记

最近好久没有写博客了,但是最近一直在学习,学了的也挺多的,就是博客写少了,有空把最近学的东西都补补。

打算是最近弄弄 lua VM以及  makefile

要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序

3)如果这个工程的头文件被改变了,那么我们需要编译引用了这个头文件的所有C文件,并
链接目标程序。

一、Makefile的规则

在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...
command

这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisi
tes中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一
个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是 Makefi
le的规则。也就是Makefile中最核心的内容。

如果command不与之前的在同一行,用Tab开头  同一行的画使用;来分隔

这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的
lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自
动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的
名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关
的命令,比如程序的打包,程序的备份,等等。

四、makefile中使用变量

在上面的例子中,先让我们看看edit的规则:

edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)

五、让make自动推导

objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects)

main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h

.PHONY : clean
clean :
rm edit $(objects)

这种方法,也就是make的"隐晦规则"。上面文件内容中,".PHONY"表示,clean是个伪
目标文件。

objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects)

$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h

.PHONY : clean
clean :
rm edit $(objects)

七、清空目标文件的规则


clean:
rm edit $(objects)

更为稳健的做法是:

.PHONY : clean
clean :
-rm edit $(objects)

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

波浪号("~")字符在文件名中也有比较特殊的用途。如果是"~/test",这就表示当前
用户的$HOME目录下的test目录。而"~hchen /test"则表示用户hchen的宿主目录下的te
st目录。(这些都是Unix下的小知识了,make也支持)而在Windows或是MS-DOS 下,
用户没有宿主目录,那么波浪号所指的目录则根据环境变量"HOME"而定。

include <filename>
filename可以是当前操作系统Shell的文件模式(可以保含路径和通配符)


-I -include-dir

在 include前面可以有一些空字符,但是绝不能是[Tab]键开始。include和<filename>可
以用一个或多个空格隔开。举个例子,你有这样几个Makefile:a.mk、b.mk、c.mk,还有
一个文件叫foo.make,以及一个变量$(bar),其包含了e.mk和 f.mk,那么,下面的语句:
include foo.make *.mk $(bar)
等价于:

include foo.make a.mk b.mk c.mk e.mk f.mk


makefile中的行凝视 #    也就是C中的 //  注释

makefile中可以用的   *    ?    [...]    bash shell中也可以的

类Unix系统下的example:

mkdir test    cd test    madir src    mkdir inc    mkdir obj    mkdir bin

gcc -c src/test_main.c -o obj/test_main.o

gcc obj/test_main.o -o bin/test_main

bin/test_main

echo $?













猜你喜欢

转载自blog.csdn.net/u014717398/article/details/80014783