序
linux下的c/c++编译代码通常需要自己写用于本程序的makefile文件,而事先准备好一个通常的、符合自己编程习惯的模板是可以加快你的编译工作。
在我看来,一个通常模板应,应具备几个必要的功能:
- 自动匹配依赖
- 添加目标和依赖的搜索路径
- 允许多目标编译
- 可生成库文件
- c程序和c++程序编译快速切换
模板
#-----------------------------1---------------------------
CC = g++ CFLAGS = -Wall -O2 -g CXXFLAGS = -Wall -O2 -g INCLUDES = -I/usr/local/sqlite/include -I/usr/local/cgic/include LDFLAGS = -L/usr/local/sqlite/lib -lsqlite3 -L/usr/local/cgic/lib -lcgic MAKETMPF = .make_temporary
VPATH = $(HOME):./
#-----------------------------2--------------------------- ifeq ($(CC),gcc) OBJS = $(patsubst %.c,$(MAKETMPF)/%.o,$(wildcard *.c)) else OBJS = $(patsubst %.cc,$(MAKETMPF)/%.o,$(wildcard *.cc)) endif
#-----------------------------3--------------------------- $(shell if [ ! -d $(MAKETMPF) ]; then mkdir $(MAKETMPF); fi;) vpath %.d $(MAKETMPF) vpath %.o $(MAKETMPF) #-----------------------------4--------------------------- TARGETS = systemmain.cgi homepagemain.cgi systemmain_objs = $(MAKETMPF)/systemmain.o homepagemain_objs = $(MAKETMPF)/homepagemain.o
#-----------------------------5--------------------------- all : $(TARGETS) systemmain.cgi : $(systemmain_objs) $(CC) -o $@ $^ $(LDFLAGS) homepagemain.cgi : $(homepagemain_objs) $(CC) -o $@ $^ $(LDFLAGS)
#-----------------------------6--------------------------- $(MAKETMPF)/%.o : %.c $(CC) -o $@ -c $< $(CFLAGS) $(INCLUDES) $(MAKETMPF)/%.o : %.cc $(CC) -o $@ -c $< $(CXXFLAGS) $(INCLUDES)
#-----------------------------7--------------------------- $(MAKETMPF)/%.d : %.c @set -e; rm -f $@; $(CC) -MM $< $(INCLUDES) > $@.$$$$; sed 's,($*).o[ :]*,1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$ $(MAKETMPF)/%.d : %.cc @set -e; rm -f $@; $(CC) -MM $< $(INCLUDES) > $@.$$$$; sed 's,($*).o[ :]*,1.o $@ : ,g' < $@.$$$$ > $@; rm -f $@.$$$$ -include $(OBJS:.o=.d)
#-----------------------------8---------------------------
libdemo.a : $(OBJS) ar -rv $@ $^; libdemo.so : $(wildcard *.c) $(CC) -shared -fpic -o $@ $^
#-----------------------------9---------------------------
.PHONY : clean
clean :
-rm -f $(TARGETS) $(MAKETMPF)/*
说明
第一部分:
CC 编译器名称
CFLAGS 指定gcc编译参数
CXXFLAGS 指定g++编译参数
INCLUDES 指定头文件的搜索路径(-I)
LDFLAGS 指定库文件的搜索路径(-L)、库名(-l)、运行时动态库加载路径(-Wl,-rpath=)
MAKETMPF 编译过程中产生的中间文件的保存路径(.o .d等)
VPATH 这是一个系统变量,指向makefile搜索目标、依赖的额外路径
第二部分:
条件编译,根据使用的编译器类型来区分源文件类型(.c 或.cc)
第三部分:
生成存放中间文件的目录
第四部分:
指定多个编译目标及每个目标的依赖
第五部分:
各目标编译规则
第六部分:
源文件编译规则(自动匹配)
第七部分:
生成各源文件的依赖
第八部分:
编译库文件
第九部分:
伪目标(清理)
补充
指定动态库运行查找路径的两种方法
- "-Wl,-rpath=" ---向链接器直接指定
- 向/etc/ld.so.conf文件尾添加库路径, 执行命令ldconfig生效
显式指定链接静态库
- 链接参数"-static"声明优先使用静态库
参考
makefile中文手册 https://www.cnblogs.com/liangxiaxu/archive/2012/07/31/2617384.html