相关学习资料:《跟我一起学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");
}
hello.h
#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执行命令后面不可行。