曲径通幽论坛

标题: 分号 ; [打印本页]

作者: beyes    时间: 2011-4-17 21:07
标题: 分号 ;
在 Makefile 中,一般的语法形式如:
helloworld:file1.o file2.o FORCE
        gcc file1.o file2.o -o helloworld

file1.o:file1.c file2.h
        gcc -c file1.c -o file1.o

file2.o:file2.c file2.h
       gcc -c file2.c -o file2.o
像 gcc 这些命令往往会另起一行并且要 TAB 键开头。如果不想这么书写,还可以在依赖文件的后面接一个分号,然后再接命令,如下所示:
helloworld:file1.o file2.o FORCE
        gcc file1.o file2.o -o helloworld

file1.o:file1.c file2.h
        gcc -c file1.c -o file1.o

file2.o:file2.c file2.h;gcc -c file2.c -o file2.o

另外,Makefile 中的分号也能像 shell 里一样用来分隔命令,比如:
clean:  
        rm -rf *.o helloworld; echo "This is ok"

执行 make :
$ make clean
rm -rf *.o helloworld; echo "This is ok"
This is ok

分号不但可以像上面一样分隔命令,它还可以起着像 C 语言中空语句的作用。内核 Makefile 中对此有一处用法:
# We need some generic definitions (do not try to remake the file).
$(srctree)/scripts/Kbuild.include: ;
include $(srctree)/scripts/Kbuild.include
这里,可以看到第 2 行后面紧接着一个分号。从第 1 行的注释中可以了解到:“我们需要一些通用的定义(不要试图去 remake 这个文件) 。” 换句话说,你即使 remake Kbuild.include 这个文件也不会成功。为了更详细的了解这里的细节,我们模拟这一做法:
1. 在当前 Makefile 目录下也建立一个 scripts/Kbuild.include 。
2. 给 Kbuild.include 文件里只添加一行 VERSION = 1
3. 先书写一个 Makefile 文件,内容如下:
srctree := $(CURDIR)
include $(srctree)/scripts/Kbuild.include

all:
@echo $(VERSION)
运行输出:
[beyes@SLinux temp]$ make
1
很正常的,输出了变量 VERSION 的值 1 。

现在再改一下 Makefile 文件,内容如下:
srctree := $(CURDIR)
$(srctree)/scripts/Kbuild.iniclude:
include $(srctree)/scripts/Kbuild.include

all:
@echo $(VERSION)
注意上面,第 2 行中 kbuild.include: 后面没有接分号。现在 make 一下:
[beyes@SLinux temp]$ make
make: Nothing to be done for `/home/beyes/Makefile/temp/scripts/Kbuild.iniclude'.
这时候,提示,对这个/home/beyes/Makefile/temp/scripts/Kbuild.iniclude 目标啥都不做,因为 Kbuild.include 后面有一个冒号,所以它是一个目标文件。自然的,底下的 all 目标不会执行。

最后,在 Kbuild.include: 后面添加一个分号,即:
srctree := $(CURDIR)
$(srctree)/scripts/Kbuild.iniclude: ;
include $(srctree)/scripts/Kbuild.include

all:
@echo $(VERSION)

再 make 一下:
[beyes@SLinux temp]$ make
make: `/home/beyes/Makefile/temp/scripts/Kbuild.iniclude' is up to date.
这时候提示 Kbuild.inlcude 这个目标已经是最新了。

所以,在内核的 Makefile 中,如上面注释所说,不要试图去 remake 这个 Kbuild.include 这个文件,否则你同样会看到“该目标已经是最新“的提示 ,同时也知道,Kbuild.include 这个文件只是用来提供一些 make 时会用到的常用定义。因此,分号接在一个目标后,它相当于一个空的依赖,而空的依赖则永远是不会被更改的,且永保持最新,从而它对应的目标也永远保持最新。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2