首先,写一个测试代码,很简单的加减程序:
//path: cacu/main.c
//path: cacu/main.c #include <stdio.h> #include "add.h" #include "sub.h" int main() { int a=10,b=12; float x=1.23456,y=9.87654; printf("int a+b IS:%d\n",add_int(a,b)); printf("int a-b IS:%d\n",sub_int(a,b)); printf("float x+y IS:%f\n",add_float(x,y)); printf("float x-y IS:%f\n",sub_float(x,y)); return 0; }
//path: cacu/sub/sub.h
//path: cacu/sub/sub.h #ifndef SUB_H #define SUB_H extern float sub_float(float a, float b); extern int sub_int(int a, int b); #endif
//path: cacu/sub/sub_float.c
float sub_float(float a, float b) { return a-b; }
//path: cacu/sub/sub_int.c
//path: cacu/sub/sub_int.c int sub_int(int a, int b) { return a-b; }
//path: cacu/add/add.h
//path: cacu/add/add.h #ifndef ADD_H #define ADD_H extern int add_int(int a, int b); extern float add_float(float a, float b); #endif
//path: cacu/add/add_float.c
//path: cacu/add/add_float.c float add_float(float a, float b) { return a+b; }
//path: cacu/add/add_int.c
//path: cacu/add/add_int.c int add_int(int a, int b) { return a+b; }
接下来看看怎么写makefile文件。
第一种:搜索路径式
该方法使用了VPATH变量,VPATH的格式如下:
VPATH=path1:path2:...
VPATH等号右边的路径名以冒号(:)分割,如
VPATH = add:sub:.
使用该方法实现前面给出的例子的makefile文件如下:
CFLAGS = -Iadd -Isub -O2 OBJSDIR = .objs VPATH = add:sub:. OBJS = add_int.o add_float.o sub_int.o sub_float.o main.o TARGET = cacu
$(OBJSDIR): mkdir -p ./$@ $(TARGET):$(OBJSDIR) $(OBJS) $(CC) -o $(TARGET) $(OBJSDIR)/*.o $(CFLAGS) $(OBJS):%.o:%.c $(CC) -c $(CFLAGS) $< -o $(OBJSDIR)/$@ clean: -$(RM) $(TARGET) -$(RM) $(OBJSDIR)/*.o
makdir命令的那一行是建立一个.bojs文件。
$(OBJS):%.o:%.c
$(CC) -c $(CFLAGS) $< -o $(OBJSDIR)/$@
这里也使用了搜索路径。
其他的$<,$@等介绍请参考:http://baike.baidu.com/view/974566.htm,百度文库把基本用法已经写的很清楚了。
第二种:递归式
为了实现每个目录下的代码具有独立的makefile,且根目录下的makefile可以一次执行子目录下的makefile,就有了递归式的方法来写父目录下的makefile了,该方法的实现是使用的$(MAKE)变量,使用格式如下:
add:
cd add && $(MAKE)
也可以这样写:
add:
$(MAKE) -C add
这样就可以递归调用子目录add下面make命令来执行add目录下的makefile文件,我们先把add和sub两个子目录下的makefile文件写好来,如下:
OBJS = add_int.o add_float.o CFLAGS = -O2 all:$(OBJS) $(OBJS):%.o:%.c $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) clean: $(RM) $(OBJS)
OBJS = sub_int.o sub_float.o CFLAGS=-O2 all:$(OBJS) $(OBJS):%.o:%.c $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) clean: $(RM) $(OBJS)
接下来就是写主目录cacu下面的makefile文件了,使用前面递归调用格式,makefile文件如下:
CC = gcc CFLAGS = -O2 TARGET = cacu export OBJSDIR = ${shell pwd}/.objs $(TARGET):$(OBJSDIR) main.o $(MAKE) -C add $(MAKE) -C sub $(CC) -o $(TARGET) $(OBJSDIR)/*.o main.o:%.o:%.c $(CC) -c $< -o $(OBJSDIR)/$@ $(CFLAGS) -Iadd -Isub $(OBJSDIR): mkdir -p $(OBJSDIR) clean: -$(RM) $(TARGET) -$(RM) $(OBJSDIR)/*.o
“$(MAKE) -C add” “$(MAKE) -C sub”这两句实现的就是在执行下面的命令前先执行子目录下的makefile文件。
测试结果:
搜索路径式的测试结果:
递归式的测试结果:
这个不算我原创的,借用了书上的,算是学习笔记吧。参考书《Linux网络编程》-宋敬彬,孙海滨。
我就菜鸟一个,欢迎拍砖