1.hello.c
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
2.Makefile
hello : hello.o
cc -o hello hello.o
hello.o : hello.c
cc -c hello.c
clean :
rm hello.o
说明:cc -o hello hello.o前面是一个tab的空格
3.执行make,产生可执行文件hello
输出如下:
cc -c hello.c
cc -o hello hello.o
4.执行make clean,删除产生的中间文件hello.o
输出如下:
rm hello.o
另转:http://hi.baidu.com/s_rlzheng/blog/item/4bc10a06892e217d030881ef.html
本来早就应该学Makefile了,只是我偷懒,现在才学呵呵^_^makefile的好处叫我说,老实说我也说不出什么之所以然来,但是可以肯定的是它是linux平台的软件工程师都要必备的知识^_^
一、程序的编译及链接
我们编译程序,无非是想要得到一个可执行文件,而这个过程则是经过这两步:
***.c->编译->***.o->链接->可执行文件。即.c经过编译得到.o文件,.o文件是一个中间文件,再对这些中间文件进行链接最终可得到可执行文件。
二、Makefile的规则
首先,来看一看Makefile的书写规则:
target ... : prerequisites ...
command
...
...
target也就是一个目标文件,可以是.o文件,也可以是执行文件,还可以是一个标签(Label)。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令(任意的Shell命令)。这里要注意的是在命令前面要加上一个tab键,不是空格,是按一个tab键按出来的空格。
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比 target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则,也就是Makefile中最核心的内容。这是Makefile的主线和核心,但要写好一个Makefile还得继续努力。
三、一个最简单的Makefile例子
如有一个工程,含有3个头文件及四个c文件,那为了生成所需的可执行文件,这时的Makefile可以这样写:
test:main.o t1.o t2.o t3.o
gcc –o test main.o t1.o t2.o t3.o
main.o:main.c
gcc –c main.c
t1.o:t1.c t1.h
gcc –c t1.c
t2.o:t2.c t2.h
gcc –c t2.c
t3.o:t3.c t3.h
gcc –c t3.c
clean:
rm test main.o t1.o t2.o t3.o
到这里一个最简单的makefile就写好了,把它的名字保存为Makefile就可以了,这时你只要在终端敲一下make,它就自动帮你编译链接了^_^如果敲入make clean,它将删掉那些中间文件及可执行文件。***************************************************************************
工程中的代码分别存放在add/add_int.c、add/add_float.c、add/add.h、sub/sub_int.c、sub/sub_float.c、sub/sub.h、main.c中。
文件main.c
#include <stdio.h>
#include "add.h"
#include "sub.h"
intmain(void)
{
}
加操作
#ifdef __ADD_H__
#define __ADD_H__
extern int add_int(int a, int b);
extern float add_float(float a, float b);
#endif
float add_float(float a, float b)
{
}
intadd_int(int a, int b)
{
}
减操作
#ifdef __ADD_H__
#define __ADD_H__
extern float sub_float(float a, float b);
extern int sub_int(int a, int b);
#endif
float sub_float(float a, float b)
{
}
intsub_int(int a, int b)
{
}
命令行编译程序:
#gcc-c add/add_int.c -o add/add_int.o
#gcc-c add/add_float.c -o add/add_float.o
#gcc-c sub/sub_int.c -o sub/sub_int.o
#gcc-c sub/sub_float.c -o sub/sub_float.o
#gcc-c main.c -o main.o
#gcc-o casu add/add_int.o add/add_float.o sub/sub_int.o sub/sub_float.omain.o
#链接生成cacu
多文件的makefile:
#生成casu,“;”右边为目标
casu:add_int.o add_float.o sub_int.o sub_float.omain.o
#生成add_int.o的规则,将add_int.c编译生成目标文件add_int.o
add_int.o:add/add_int.c add/add.h
#生成add_float.o的规则
add_float.o:add/add_float.c add/add.h
#生成sub_int.o的规则
sub_int.o:sub/sub_int.c sub/sub.h
#生成sub_float.o的规则
sub_float.o:sub/sub_float.c sub/sub.h
#生成main.o的规则
main.o:main.c add/add.h sub/sub.h
#清理规则
clean:
使用自定义变量的makefile文件:
CC = gcc
CFLAGES =
OBJS = add/add_int.o add/add_float.o \
TARGET = casu
RM = rm -f
$(TARGET):$(OBJS)
$(OBJS):%.o:%.c
clean:
使用预定义变量的makefile文件:
CFLAGES =
OBJS= add/add_int.o add/add_float.o \
TARGET = casu
$(TARGET):$(OBJS)
$(OBJS):%.o:%.c
clean:
使用自动变量的makefile文件:
CFLAGES =
OBJS= add/add_int.o add/add_float.o \
TARGET = casu
$(TARGET):$(OBJS)
$(OBJS):%.o:%.c
clean:
使用搜索路径的makefile文件:
CFLAGES =
OBJSDIR = .objs
VPATH = add:sub:.
OBJS= add_int.o add_float.o sub_int.o sub_float.o main.o
TARGET = casu
$(TARGET):$(OBJSDIR) $(OBJS)
$(OBJS):%.o:%.c
$(OBJSDIR):
clean:
使用自动推导规则的makefile:
CFLAGS = -Iadd -Isub -O2
VPATH=add:sub
OBJS= add_int.o add_float.o sub_int.o sub_float.o main.o
TARGET = cacu
$(TARGET):$(OBJS)
clean:
使用函数的makefile文件:
CC =gcc
VPATH =add:sub
CFLAGES =
TARGET = casu
DIRS= sub add .
FILES = $(foreach dir, $(DIRS),$(wildcard$(dir)/*.c))
OBJS = $(patsubst %.c,%.o,$(FILES))
$(TARGET):$(OBJS)
clean: