相关学习资料:《跟我一起学Makefile》陈皓 、《GNU_Make中文手册》
例子-C代码文件setoffset
//main.c //write 函数测试 #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main() { //返回值为参数nbytes,否则执行error //转义字符\n算两个字符,后面再接一个结束符 if((write(1,"Here is some data\n",20))!=18) { write(1,"A write error has occuredon filescriptor 123\n",46); write(1,"A write error has occuredon filescriptor 123\n",46); write(2,"B write error has occuredon filescriptor 123\n",46); write(2,"C write error has occuredon filescriptor 123\n",54); //参数越界,打印后续字符块hello。。。 write(3,"C write error has occuredon filescriptor 123\n",46); //参数filedes可为0,1,2,可重复,最多2,超过语句无效 printf("hello\n"); printf("hello world\n"); //常量字符串是要按顺序存放在常量区域的,当第一个字符串长度越界就会访问到第二个字符串区域区域 } write(0,"Here is some data\n",19); func1(); exit(0); }
hello.c
#include <stdio.h> #include "hello.h" void func1() { printf("hello world\n"); }
#ifndef _HELLO_H_ #define _HELLO_H_ #include <stdio.h> void func1(); #endif
makefile文件:Makefile
objects=main.o mainfile=main.c final: $(objects) gcc -o final $(mainfile) $(objects): $(mainfile) #unistd.h stdlib.h 系统自带头文件此处不依赖 gcc -c $(mainfile) .PHONY:clean #伪目标 clean: rm final $(objects)
命令如gcc,rm等前面为一个tab按键,其实makefile文件具有自动推导的能力。
只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果一个whatever.o, 那么whatever.c, 就会是whaterver.o的依赖文件。
并且gcc -c whatever.c也会被推导出来,于是,我们的makefile不用写那么复杂了。
objects=main.o mainfile=main.c hello.c final: $(objects) gcc -g -MM -o final $(mainfile) #unistd.h stdlib.h 系统自带头文件此处不依赖 $(objects):$(mainfile) gcc -c -MM $(mainfile) .PHONY:clean #伪目标 clean: -rm file.out final *.o
.PHONY意思表示clean是一个“伪目标”,。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。
即输出结果会提示错误,但不防碍下一条其他动作的执行
rm file.out rm: 无法删除"file.out": 没有那个文件或目录 make: [clean] 错误 1 (忽略) rm final main.o
不成文的规矩是——“clean从来都是放在文件的最后”。
如果命令太长,你可以使用反斜框(‘\’)作为换行符。make对一行上有多少个字符没有限制。规则告诉make两件事,文件的依赖关系和如何成成目标文件。
一般来说,make会以UNIX的标准Shell,也就是/bin/sh来执行命令。
make支持三各通配符:“*”,“?”和“[...]”。
$@,即表示删除所有目标文件
$<表示所有的依赖的文件
注意上面的表示方法用在shell执行命令后面不可行。