Makefile tutorial

工作中主要是通过ndk交叉编译生产arm平台的可执行程序及库,但实际调试代码时还是在x86上会更方便一些,因此对于自己编写或者移植过来的代码中没有makefile的就需要自己编写makefile来进行编译。

(一)单目录多文件Makefile编写

目录机构如下:

├── Libusb.c
├── Libusb.h
├── main.c
├── makefile
├── Makefile
├── mybluetooth.c
├── mybluetooth.h
├── obex.c
├── ObexDef.h
├── obex.h
├── ObexPack.c
└── ObexPack.h

一、 执行gcc分别编译

CFLAGS:= -g #-fshort-wchar

all : main
main : main.o mybluetooth.o Libusb.o obex.o ObexPack.o
    gcc $(CFLAGS) -o main main.o mybluetooth.o Libusb.o obex.o ObexPack.o -lbluetooth `pkg-config --cflags --libs libusb-1.0` -lusb

main.o : main.c
    gcc $(CFLAGS) -c main.c

Libusb.o: Libusb.c
    gcc $(CFLAGS) -c Libusb.c `pkg-config --libs --cflags libusb-1.0` -lusb

mybluetooth.o : mybluetooth.c
    gcc $(CFLAGS) -c mybluetooth.c -lbluetooth

obex.o: obex.c
    gcc $(CFLAGS) -c obex.c 

ObexPack.o: ObexPack.c
    gcc $(CFLAGS) -c ObexPack.c

clean:
    rm -rf *.o main .*.swp

二、使用makefile的自动推导功能

CC = gcc
CFLAGS = -g -Wall -I/usr/include/libusb-1.0  -lusb-1.0 -lusb -lbluetooth

OBJS= Libusb.o  main.o  mybluetooth.o  obex.o  ObexPack.o

main: $(OBJS)
    $(CC) -o main $(OBJS) $(CFLAGS)

#以下可以不用写
#main.o: ObexDef.h
#obex.o: obex.h
#ObexPack.o: ObexPack.h ObexDef.h
#Libusb.o: Libusb.h
#mybluetooth.o: mybluetooth.h

.PHONY: clean
clean:
    rm $(OBJS) main

(二)多目录多文件makefile编写

以下引用自博客园多目录下多文件 makefile编写
在编写多目录的makefile时,一般会用到如下的几个函数和变量;
函数:

wildcard 这是扩展通配符函数,功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔;比如:罗列出src下的所有.c文件:$(wildcard ${SRC}/*.c)

patsubst 这是匹配替换函数, patsubst ( 需要匹配的文件样式,匹配替换成什么文件,需要匹配的源文件)函数。比如:用src下的*.c替换成对应的 *.o文件存放到obj中:$(patsubst  %.c, ${OBJ}/%.o, $(notdir $(SOURCE)))

notdir 这是去除路径函数,在上面patsubst函数中已经使用过,去除SOURCE中文件的所有目录,只留下文件名;

变量:

$@:表示目标文件;一般是在规则中这么用:gcc  -o $@  $(object);

$^:表示所有依赖文件;一般是在规则中这么用:gcc -o $@  $^  ;用所有依赖文件链接成目的文件;

$<:表示第一个依赖文件;在规则中使用:gcc -o $@ -c $< ;其实这个时候就是每个依赖文件生成一个目的文件;

makefile模板:

#把所有的目录做成变量,方便修改和移植   
 BIN = ./bin  
 SRC = ./src  
 INC = ./include  
 OBJ = ./obj  

#提前所有源文件(即:*.c文件)和所有中间文件(即:*.o)  
 SOURCE = $(wildcard ${SRC}/*.c)  
 OBJECT = $(patsubst %.c,${OBJ}/%.o,$(notdir ${SOURCE}))  

#设置最后目标文件  
 TARGET = main  
 BIN_TARGET = ${BIN}/${TARGET}  

 CC = gcc   
 CFLAGS = -g -Wall -I${INC}   

#用所有中间文件生成目的文件,规则中可以用 $^替换掉 ${OBJECT}  
 ${BIN_TARGET}:${OBJECT}  
     $(CC) -o $@ ${OBJECT}  

#生成各个中间文件  
 ${OBJ}/%.o:${SRC}/%.c   
     $(CC) $(CFLAGS) -o $@ -c $<  

 .PHONY:clean  
 clean:  
     find $(OBJ) -name *.o -exec rm -rf {} \; #这个是find命令,不懂的可以查下资料  
     rm -rf $(BIN_TARGET)