转载:http://www.cnblogs.com/kulin/archive/2012/07/27/Makefile_Grammer.html
1 #Source file “#”号,注释,完全是注释,跟C语言中的//是一样的 2 SRC = ThreadQueue.cpp 变量的定义,变量名为SRC,变量定义为ThreadQueue.cpp,这样要引用变量时写作“$(变量名)”即可,就等价为变量的定义内容。 3 #Object file 4 OBJ = $(SRC:.cpp=.o) 这里又定义了一个变量,请注意,它的定义引用了SRC变量,同时,用到了变量替换RC:.cpp=.o的意思是指将SRC下所有以.cpp结尾的文件的.cpp替换为. o,也就定义了要输出的所有文件。 5 #Output execution file 6 PROGRAM = ThreadQueue 定义变量,这里顺便再一提,这个就是我们在编译过程中最后要得到的东西,即ThreadQueue.o。 7 #Compiler 8 CC = g++ 变量定义是指CC代表的就是gcc编译器 9 10 11 #Include 12 INCLUDE = -I/usr/include/ncurses –I/usr/include/ 又是一个变量定义,这里就得交待一件事情了:在Makefile中变量的定义是很灵活的,基本可以理解为C语言 下的宏定义,你定义神马都可以,你可以用变量来定义一个文件名列表,定义一个可执行文件名,也可以把变量定义成编译器命令选项。 13 #Linker Parameter 14 LINKPARAM = -lpthread -lncurses 这里也是一个变量的定义,这个变量作为gcc编译时的编译器选项使用。 15 #Options for development 如果你是想自己要调试用的话,你就保 留“options for develop”下面的那一行,把之前的“#”号去掉,而你要是想生成不可调试的发行版 ,那就选择让第十六行生效。 16 #CFLAGS = -g 17 18 #Options for release 19 CFLAGS = -o 20 21 22 all: $(PROGRAM) all是一个标签,你可以理解成一个跳转符号,如果想让make程序在编译时执行某一个特定的指令,就可以把这个指令做成一个标签,这样在命令 行里输入“make Name_of_Your_Label”就可以执行某一特定部分的编译了。 23 24 $(PROGRAM): $(OBJ) 25 26 $(CC) -o $(PROGRAM) $(LINKPARAM) $(OBJ) 27 28 .SUFFIXES : .cpp 这里的“.SUFFIXES”是一个伪目标,它的作用类似于一个标签,在伪目标之后的所有内容将不会被检查是否已经执行,而是将它直接执行。 29 30 .cpp.o: 31 32 $(CC) $(INCLUDE) $(CFLAGS) -c $< 33 34 clean: 35 -rm *.o
这里就不得不提一般的Makefile的书写格式了,这也是为什么我要把三行在一起交待,如下:
目标:依赖
命令
……
必须注意的是,命令前面的不是空格,而是制表符Tab,这是Makefile书写时必须遵循的规则。那我们看到上面的模板中, 我们要生成的是PROGRAM所代表的变量,而所需要的依赖就是OBJ中所有的.o文件,生成时的命令是“$(CC) -o $(PROGRAM) $(LINKPARAM) $(OBJ)”,根据他们各自的变量定义可知,之一段命令可以翻译为“gcc –o ThreadQueue -lpthread –lncurses ThreadQueue.o”,其中前面带有-的几个字母都是gcc编译时的选项,改天再总结一下gcc编译器的使用。
这里.cpp.o是老式的“后缀规则”,编译器将会自动将.cpp识别为源文件后缀,而.o识别为输出文件后缀。,SUFFIXES也是习惯上用来定义后缀规则的伪目标。特别需要注意的是,后缀规则不允许任何依赖文件,但也不能没有命令。
这里定义了clean命令的执行规则,以及所要清除的文件的后缀名,如果你还想在clean时清除什么后缀的文件的话,就再写上”*.post_name”即可,非常方便。
时间: 2024-10-14 01:01:14