首先,寫一個測試代碼,很簡單的加減程序:

//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 #ifndef SUB_H #define SUB_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) { return a-b; }

//path: cacu/sub/sub_int.c int sub_int(int a, int b) { return a-b; }

//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 float add_float(float a, float b) { return a+b; }

//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網絡編程》-宋敬彬,孫海濱。
我就菜鳥一個,歡迎拍磚