Makefile自动依赖写法

来源:互联网 发布:windows资源管理器停止 编辑:程序博客网 时间:2024/06/06 09:07

从开始学习到了解到makefile自动依赖到目前为止总算是掌握了makefile的自动依赖写法

因为接触的项目代码分布的问题源文件和头文件不在同一个目录下,,网上很多makefile自动依赖的方案不能直接拿来用.所以是在其基础上进行的改编

总体来说 是这么个过程 

先决条件 工程目录结构为 顶层中放置

1 Makefile 

2 src目录放置源文件 

3 inc目录 

4 可能有lib目录  

生成的程序在顶层目录中

第一步 写好你的环境变量 一般设置如下参数即可

CC=gccCFLAGS=-g -rdynamic -W -WallSRC=srcINC=-I. -I./incLIB=lib/xxxx.a   #如果有TARGET=demo

第二步 获取所有参与编译的源文件 

在这步中我所使用的是makefile提供的函数 

SOURCES = $(wildcard src/*.cpp)
OBJ=$(patsubst %.cpp, %.o,$(SOURCES))
这样在SOURCES中获取到的是所有参加编译的cpp文件 但是如果有多个目录放置的话 可以使用追加方式添加其他的目录下的源文件,最好在做完这一步之后进行验证

两个函数的用途分别是  获取匹配的文件列表  和对匹配的字符串进行替换 将.cpp替换成.o,具体的详细内容可以百度,不赘述

第三步 写下如下语句

ALL: $(TARGET)$(TARGET):$(OBJ)$(CC) $(CFLAGS) -o $(TARGET) $(OBJ) $(LIB) 

很明显是申明要生成的文件 为TARGET也就是demo

第四步 设置自动依赖关系

%d:%cpp@$(CC) -MM $(CFLAGS) $< $(INC) > $@.dd;@sed -i 's,\($(*F)\)o[ :]*,$(*D)/\1o: ,g'  $@.dd ;@sed 's,\($*\)o[ :]*,\1o $@ : ,g' < $@.dd > $@;@echo "\t$(CC) -c -o $*o $< $(INC)" >>$@;@$(RM) $@.dd-include $(patsubst %.cpp, %.d,$(SOURCES))
这个地方有几个位置需要注意 第一点也就是最重要的一点 

就是%d:%cpp  是没有.

%d:%cpp  是没有.

%d:%cpp  是没有.

重要的事情说三遍

当然如果要加点的话可是可行的,但是需要对整个结构进行一些变形,在这里就不展开了

解释一下上面语句发生的事情

@$(CC) -MM $(CFLAGS) $< $(INC) > $@.dd;
这句是非常通用的获取依赖头文件的方法,不过在最后的写入文件里面我没有用$$$$作为进程号设置文件名,我觉得这样比较麻烦还需要\来支持写在一行,直接指定一个不会重复的就可以了

@sed -i 's,\($(*F)\)o[ :]*,$(*D)/\1o: ,g'  $@.dd ;
这一句也是十分常见 第一句的结果为 a.o: src/a.cpp inc/a.h 这句话的意思为将其替换成  src/a.o: src/a.cpp inc/a.h 

这个替换对下面的有关键性帮助 ,因为OBJ里面存的变量都是形如src/a.o的 与这个相对应起来

@sed 's,\($*\)o[ :]*,\1o $@ : ,g' < $@.dd > $@;
这一句不展开讲,也很通用 将  src/a.o: src/a.cpp inc/a.h 替换为   src/a.o src/a.d: src/a.cpp inc/a.h 

@echo "\t$(CC) -c -o $*o $< $(INC)" >>$@;

这一句是分目录src和inc编译的关键,没有这一句编译将不能正常进行.这是在src/a.d中手动添加inc目录进编译选项中,没有这个 将在编译的时候报找不到头文件

@$(RM) $@.dd-include $(patsubst %.cpp, %.d,$(SOURCES))
这两句都不说了  一个是删除,另外一个是包含src/a.d的makefile规则的文件

到这里我们的makefile自动依赖就完成了,可以作用于多个目录,有着比较良好的通用性,可以试试

当然少不了clean 这个就自己写吧



0 0
原创粉丝点击