makefile 指定文件的生成目录[通俗易懂]

makefile 指定文件的生成目录[通俗易懂]1.上一篇博客虽然简单实现了自动处理依赖关系,但是生成的各种临时文件都混在一起,太乱了。假定我们的源文件放在src目录,头文件放在inc目录,.o文件放在obj目录,.d文件放在dmk目录,Makefile和上述4个目录为同一级别。则定义如下变量:D_SRC=srcD_INC=-I./incD_OBJ=objD_MK=dmk2.自动遍历src目录下的所有.c

大家好,又见面了,我是你们的朋友全栈君。

1.上一篇博客虽然简单实现了自动处理依赖关系,但是生成的各种临时文件都混在一起,太乱了。

假定我们的源文件放在src目录,头文件放在inc目录,.o文件放在obj目录,.d文件放在dmk目录,Makefile和上述4个目录为同一级别。

则定义如下变量:

D_SRC = src
D_INC = -I./inc
D_OBJ = obj
D_MK  = dmk

2.自动遍历src目录下的所有.c文件

SRC_C   = $(wildcard $(D_SRC)/*.c)
         # wildcard表示把$(D_SRC)目录下的.c文件遍历出来

SRC_C   = $(foreach dir, $(D_SRC), $(wildcard $(dir)/*.c))
       # foreach表示遍历$(D_SRC)的所有子目录同时把子目录下的.c文件遍历出来

假设src目录中有a.c,b.c,则$(SRC_C) 表示 src/a.c src/b.c

3.生成所有的.o文件依赖和.d文件集合

OBJ_C   = $(addprefix $(D_OBJ)/,$(patsubst %.c,%.o,$(notdir $(SRC_C))))
SRC_MK  = $(addprefix $(D_MK)/, $(patsubst %.c,%.d,$(notdir $(SRC_C))))

notdir表示去除目录,则$(notdir $(SRC_C))表示a.c b.c

patsubst表示把$(notdir $(SRC_C))中的.c替换成.o,即a.o b.o

addprefix表示增加前缀$(D_OBJ)/,则OBJ_C变量表示为obj/a.o obj/b.o

4.明白了上述语句之后我们可以把makefile写成如下状态

D_SRC = src
D_INC = -I./inc
D_OBJ = obj
D_MK  = dmk
TATGET = hello

SRC_C   = $(foreach dir, $(D_SRC), $(wildcard $(dir)/*.c))
OBJ_C   = $(addprefix $(D_OBJ)/,$(patsubst %.c,%.o,$(notdir $(SRC_C))))
SRC_MK  = $(addprefix $(D_MK)/, $(patsubst %.c,%.d,$(notdir $(SRC_C))))

$(TATGET):$(OBJ_C)
	gcc -o $@ $^

$(D_OBJ)/%.o:$(D_SRC)/%.c
	gcc -c -Wall $(D_INC) $< -o $@

$(D_MK)/%.d:$(D_SRC)/%.c
	@set -e; rm -f $@; \
	$(CC) -MM $(D_INC) $< > $@.$$$$; \
	sed 's,\($*\)\.o[ :]*,$(D_OBJ)/\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$

include $(SRC_MK)

.PHONY: clean
clean:
	rm -f $(D_OBJ)/* $(TATGET) $(D_MK)/*

多出来的几行依赖关系其实就是一个字符串匹配的模式,clean就不需要解释了。

5.vpath 自动变量的使用,第一个参数是查找的类型,第二个是查找的目录

vpath %.c src #查找依赖时如果遇到%.c,则自动到src目录下寻找
D_SRC = src
D_INC = -I./inc
D_OBJ = obj
D_MK  = dmk
TATGET = hello

SRC_C   = $(foreach dir, $(D_SRC), $(wildcard $(dir)/*.c))
OBJ_C   = $(addprefix $(D_OBJ)/,$(patsubst %.c,%.o,$(notdir $(SRC_C))))
SRC_MK  = $(addprefix $(D_MK)/, $(patsubst %.c,%.d,$(notdir $(SRC_C))))

$(TATGET):$(OBJ_C)
	gcc -o $@ $^

$(D_OBJ)/%.o:%.c  #自动去src目录下找.c结尾的文件。
	gcc -c -Wall $(D_INC) $< -o $@

$(D_MK)/%.d:%.c
	@set -e; rm -f $@; \
	$(CC) -MM $(D_INC) $< > $@.$$$$; \
	sed 's,\($*\)\.o[ :]*,$(D_OBJ)/\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$

include $(SRC_MK)

.PHONY: clean
clean:
	rm -f $(D_OBJ)/* $(TATGET) $(D_MK)/*

查找多个目录用下面的写法

vpath %.c src:src1:src2

大写VPATH只能指定依赖的查找目录,不能指定类型,所以也可以写成

VPATH = src
D_SRC = src
D_INC = -I./inc
D_OBJ = obj
D_MK  = dmk
TATGET = hello

SRC_C   = $(foreach dir, $(D_SRC), $(wildcard $(dir)/*.c))
OBJ_C   = $(addprefix $(D_OBJ)/,$(patsubst %.c,%.o,$(notdir $(SRC_C))))
SRC_MK  = $(addprefix $(D_MK)/, $(patsubst %.c,%.d,$(notdir $(SRC_C))))

$(TATGET):$(OBJ_C)
	gcc -o $@ $^

$(D_OBJ)/%.o:%.c
	gcc -c -Wall $(D_INC) $< -o $@

$(D_MK)/%.d:%.c  #自动去VPATH指定的目录查找,指定多个路径 写成VPATH = src:src1:src2
	@set -e; rm -f $@; \
	$(CC) -MM $(D_INC) $< > $@.$$$$; \
	sed 's,\($*\)\.o[ :]*,$(D_OBJ)/\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$

include $(SRC_MK)

.PHONY: clean
clean:
	rm -f $(D_OBJ)/* $(TATGET) $(D_MK)/*
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143708.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab griddata插值太慢,griddata在二维插值中的应用问题,有待解决~

    matlab griddata插值太慢,griddata在二维插值中的应用问题,有待解决~>>x=rand(100,1)*4-2;>>y=rand(100,1)*4-2;>>z=x.*exp(-x.^2-y.^2);>>ti=-2:.25:2;>>[xi,yi]=meshgrid(ti,ti);>>zi=griddata(x,y,z,xi,yi,’cubic’);>>mesh(xi,yi,…

    2022年5月18日
    69
  • html怎么让无序列表横向排列_一个人把敌人的炮兵阵地

    html怎么让无序列表横向排列_一个人把敌人的炮兵阵地司令部的将军们打算在 N×M 的网格地图上部署他们的炮兵部队。一个 N×M 的地图由 N 行 M 列组成,地图的每一格可能是山地(用 H 表示),也可能是平原(用 P 表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示:如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响

    2022年8月8日
    6
  • WEBAPP开发技巧总结

    WEBAPP开发技巧总结自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词-WebApp(意为基于WEB形式的应用程序,运行在高端的移动终端设备)。开发者们都知道在高端智能手机系统中有两种应用程序:一种是基于本地(操作系统)运行的APP;一种是基于高端机的浏览器运行的WebApp,本文将主要讲解后者。WebApp与Native App有何区别呢?Nat

    2022年6月25日
    25
  • 【6】进大厂必须掌握的面试题-Hibernate

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 1.什么是Hibernate Framework? 对象关系映射或对象关系管理(ORM)是将应用程序域模型对象映射到…

    2021年6月23日
    96
  • linux中systemctl详细理解及常用命令

    linux中systemctl详细理解及常用命令一、systemctl理解Linux服务管理两种方式service和systemctlsystemd是Linux系统最新的初始化系统(init),作用是提高系统的启动速度,尽可能启动较少的进程,尽可能更多进程并发启动。systemd对应的进程管理命令是systemctl1.systemctl命令兼容了service即systemctl也会去/etc/init.d目录下…

    2022年5月9日
    72
  • Python练习题 025:判断回文数[通俗易懂]

    Python练习题 025:判断回文数[通俗易懂]【Python练习题025】 一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。做题做到现在,这种题目已经很轻车熟路了。希望下一题能增加点难度啊~~~

    2022年7月5日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号