在Makefile基础中总结了makefile最常用的基础,利用这些知识点,足矣编写通用makefile运用于c/c++项目中。本文基于这样的文件编写makefile:

编写makefile需要实现:
(1) 将bank.cpp编译成静态库bank.a/动态库bank.so;
(2) 将bank.a和bank.so拷贝/opt/lib目录下;
(3) 将bank.h拷贝到/optinclude目录下;
(4) 将测试程序文件test.c编译成test
makefile文件内容如下:
MAKE = make -s #指定make的方式
CC = gcc #指定编译工具
AR = ar -rcv #指定.o文件打包工具,编译静态库用
RM = /bin/rm -f #指定删除命令
CP = /bin/cp -f #指定拷贝命令
LIBS_INSTALL_DIR = /opt/ #指定目标文件的最终拷贝的目的目录
INCLUDE_LIBS = bank1.h #指定编译时依赖的头文件
CPPFLAGS := -I. -fPIC #指定头文件所在目录
LDFLAGS = -lpthread #链接用的库及所在目录
SO ?= libbank.so #指定生成的目标文件,动态库
A ?= libbank.a #指定生成的目标文件,静态库
TEST ?= test #指定生成的目标文件,测试程序
LIBS = bank1.o #生成的中间文件
.PHONY: SO A TEST #声明SO A TEST为伪规则,这样即使目标文件存在的情况下也是会执行对应的生成规则
all : clean $(SO) $(A) $(TEST) #all是整个makefile的入口,它依赖于SO A TEST
$(TEST) : #编译测试程序test.c文件
$(CC) $(LIBS) test.c -o $@ $(CPPLIAGS) $(LDFLAGS)
$(SO) : $(LIBS) #编译生成动态库
$(CC) -shared -$^ -O $@
$(A) : $(LIBS) #编译生成静态库
$(AR) $@ $(LIBS)
%.o : %.c #将对应的.c文件编译成.o文件
$(CC) -c $< -o $@ $(CPPFLAGS)
clean: #清除
@$(RM) $(SO) $(A) $(TEST) $(LIBS)
install : all #安装,其实就是将目标文件拷贝到目的目录
@$(CP) $(SO) $(A) $(LIBS_INSTALL_DIR)/lib
@$(CP) $(INCLUDE_LIBS) $(LIBS_INSTALL_DIR)/include
uninstall: #卸载,其实就是将目标文件从目的目录中删除
@$(RM) $(LIBS_INSTALL_DIR)/lib/$(SO) $(LIBS_INSTALL_DIR)/lib/$(A) $(LIBS_INSTALL_DIR)/include/$(INCLUDE_LIBS)
这是将一个目录下的文件编译成库文件的makefile,倘若有多个这样的目录都要生成库文件,其目录下makefile几乎是一样的,不一样的只是makefile文件中开头定义的那些变量,所以可以将这些一样的代码抽取出来放在一个config.mk文件(config.mk也是一样makefile文件)中放在顶层目录,然后在不同的目录下的makefile中写每个目录独有的部分,最后包含(include)config.mk文件,这样就可以实现多目录项目的通用makefile了,用到的也是Makefile基础讲到的知识。