我的Makefil

1. Makefile-exe

CC:=gcc
CXX:=g++
RM:=rm -rf

OUTDIR:=$(EXEDIR)
EXENAME:=$(PROJNAME)
EXESRCS:=$(COMPILE_FILES)
CFLAGS:=$(COMPILE_FLAGS)
LDFLAGS:=$(LINK_FLAGS)
DEBUG:=Y

EXEOBJS:=$(patsubst %.cpp,%.oo,$(EXESRCS))
EXEOBJS:=$(patsubst %.c,%.o,$(EXEOBJS))
EXEDEPS:=$(patsubst %.cpp,%.dd,$(EXESRCS))
EXEDEPS:=$(patsubst %.c,%.d,$(EXEDEPS))

ifeq ($(DEBUG),Y)
CFLAGS+=-O0 -ggdb3
else
CFLAGS+=-O3 -fomit-frame-pointer
endif

.PHONY:all clean
all:$(OUTDIR).dir $(OUTDIR)/$(EXENAME)
 
$(OUTDIR)/$(EXENAME):$(EXEDEPS) $(EXEOBJS) 
	$(CXX)  $(EXEOBJS) -o $@ $(LDFLAGS)

-include $(EXEDEPS)
%.d: %.c
	@$(CC) -MM $(CFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: \([0-9a-zA-Z._-]*/\),\1&,' -e 's,^\([0-9a-zA-Z._-/]*\)\.o:,\1.o \1.d:,' > $@
%.dd: %.cpp
	@$(CXX) -MM $(CFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: \([0-9a-zA-Z._-]*/\),\1&,' -e 's,^\([0-9a-zA-Z._-/]*\)\.o:,\1.oo \1.dd:,' > $@
%.o:%.c
	$(CC) $(CFLAGS)  -c $< -o $@
%.oo:%.cpp
	$(CXX) $(CFLAGS)  -c $< -o $@
%.dir:
	@echo "Checking directory $*"
	@if [ ! -d $* ]; then \
		echo "Making directory $*"; \
		mkdir -p $* ;\
	fi;

clean:
	-$(RM) $(EXEOBJS) $(EXEDEPS) $(OUTDIR)/$(EXENAME)

2. Makefile-so

CC:=gcc
CXX:=g++
LD:=ld
RM:=rm -rf

OUTDIR:=$(LIBDIR)
LIBNAME:=lib$(PROJNAME)
LIBSRCS:=$(COMPILE_FILES)
CFLAGS:=$(COMPILE_FLAGS)
LDFLAGS:=$(LINK_FLAGS)
DEBUG:=Y

LIBOBJS:=$(patsubst %.cpp,%.oo,$(LIBSRCS))
LIBOBJS:=$(patsubst %.c,%.o,$(LIBOBJS))
LIBDEPS:=$(patsubst %.cpp,%.dd,$(LIBSRCS))
LIBDEPS:=$(patsubst %.c,%.d,$(LIBDEPS))
CFLAGS+=-I. -Wall

ifeq ($(DEBUG),Y)
CFLAGS+=-O0 -ggdb3
else
CFLAGS+=-O3 -fomit-frame-pointer
endif

.PHONY:all clean
all:$(OUTDIR).dir $(OUTDIR)/$(LIBNAME)
 
$(OUTDIR)/$(LIBNAME):$(LIBDEPS) $(LIBOBJS)
	$(CC) -shared -fPIC  $(LIBOBJS) -o $@.so $(LDFLAGS)

-include $(LIBDEPS)
%.d: %.c
	@$(CC) -MM $(CFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: \([0-9a-zA-Z._-]*/\),\1&,' -e 's,^\([0-9a-zA-Z._-/]*\)\.o:,\1.o \1.d:,' > $@
%.dd: %.cpp
	@$(CXX) -MM $(CFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: \([0-9a-zA-Z._-]*/\),\1&,' -e 's,^\([0-9a-zA-Z._-/]*\)\.o:,\1.oo \1.dd:,' > $@
%.oo:%.cpp
	$(CXX) $(CFLAGS) $(DEFS) -c $< -o $@	
%.o:%.c
	$(CC) $(CFLAGS) $(DEFS) -c $< -o $@
%.dir:
	@echo "Checking directory $*"
	@if [ ! -d $* ]; then \
		echo "Making directory $*"; \
		mkdir -p $* ;\
	fi;

clean:
	-$(RM) $(OUTDIR)/* $(LIBOBJS) $(LIBDEPS)

3. Makefile-src

PROJNAME:=engine
LIBDIR:=../lib
LINK_FLAGS:=-lSDL -lGL -lGLU -lGLEW -lstdc++ -lMagick++ -lassimp
COMPILE_FLAGS:=-I/usr/include/SDL -I/usr/include/ImageMagick -I/usr/local/include/assimp -I../include -D_GNU_SOURCE=1 -D_REENTRANT -DARCH_X86=1 -Wno-int-to-pointer-cast
COMPILE_FILES:= util/Array.c\
	        util/Timer.c
include ../Makefile-so

4. 编译静态库

如果是编译静态库,使用下面的命令进行编译:

AR:=ar

RANLIB:=ranlib

(OUTDIR)/$(LIBNAME):$(DEPS) $(OBJS)
$(AR) cr $@ (OBJS)
        $(RANLIB) $@

基本上上面的用法就足够了,多多使用就好。

5. gcc 选项

-I :头文件位置(编译时用)
-l: 引用的库的名称(链接时用)

-L:引用的库的位置(链接时用)

-Wall: 打开所有警告

-Wno-xxx:关闭某个警告

-O0 -ggdb3:没有编译优化,加入gdb调试信息

-O3:最优化编译优化

-g或者-ggdb3生成调试信息

-D:定义的预编译的变量名

-M:生成文件关联的信息

-MM:同上,但是去除#include <...h>这样的关联信息

CFLAGS LDFLAGS:gcc内部定义的变量
自动化变量:

$@ 目标文件 $^ 所有依赖文件  $< 第一个依赖文件

6. 依赖文件

生成依赖.d文件:

需要生成这个文件的原因:有时候如果头文件发生了改动,但是.c文件没有发生改动,如果单纯的依赖.c文件会导致头文件的更新无法反映到可执行程序中去。

应采用下面这种方式来实现:

$EXENAME: $DEPENDENCE $OBJS

%.d:%.c

$(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$

其中$@.$$$$表示以.d+进程号作为一个临时文件($$表示进程号,至于为什么要用4个,这是因为首次要经过shell的处理,shell中$$表示$);

sed使用的是替换功能 sed 's/{old_string}/{new_string}/g' 或者采用逗号作为分隔符sed 's,{old_string},{new_string},g', 分割符自己定义,只要和匹配模式里面的字符不冲突就好

其中的匹配用到了正则表达式(正则表达式确实很强大,在grep, awk中均用到了,grep用于找到行,awk用于找到列)

这个是GNU Makefile中文手册上的用法,比较好理解(一个sed命令,两个重定向);

上面的脚本中是老师的用法:

  @$(CC) -MM $(CFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: \([0-9a-zA-Z._-]*/\),\1&,' -e 's,^\([0-9a-zA-Z._-/]*\)\.o:,\1.o \1.d:,' > $@

分两步进行:第一步,先选出字符串中符合 XXX: aaa bbb格式的字符串;第二步,替换,将xxx.o替换成xxx.o xxx.d

7. Makefile内置函数

wildcard: 通配符 ,用法 $(wildcard *.c),获取当前目录下的所有的.c文件
patsubst: 模式替换,用法$(patsubst %.cpp %.oo $(SRCFILES)),将SRCFILES中所有的cpp换成.oo
ar xxxx.a a.o b.o :将a.o b.o加入到静态库中
ranlib xxxx.a :为库文件创建索引表
(ar t xxx.a:显示库中有哪些目标文件, nm -s xxx.a 显示索引表)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值