第17课 - make 中的路径搜索(上)
第17课 - make 中的路径搜索(上)
1. 问题
在以往的 make 学习中,我们使用到的 .c 文件和 .h 文件都与 makefile 处在同一个路径。在实际的工程项目中,所有的源文件和头文件都放在同一个文件夹中吗?
答案毋庸置疑是否定的,在实际的工程项目中,源文件和头文件的数量可能是成千上万的,必须采用一定的目录结构进行管理,一般按照模块的功能进行分类管理。

因此,实际工程项目中的 makefile 必须能够正确的定位源文件和依赖的文件,最终编译产生可执行程序。
2. 下面的 makefile 能够编译成功吗?

在 linux 下执行 make,产生错误,提示找不到依赖对应的文件。

3. make 中的路径搜索
3.1 特殊的预定义变量 VPATH(全大写)
(1) VPATH 是 make 的预定义变量,该变量的值用于指示 make 如何查找文件
(2)不同文件夹可作为 VPATH 的值同时出现
(3)文件夹的名字之间需要使用分隔符进行区分
- 例1:VPATH := inc src (空格)
- 例2:VPATH := inc src (分号)
- 例3:VPATH := inc:src (冒号)
3.2 make 对于 VPATH 值的处理方式
(1)当前文件夹找不到需要的文件时,VPATH 会被使用
(2)make 会在VPATH 指定的文件夹中依次搜索文件
(3)当多个文件夹存在同名文件时,选择第一次搜索到的文件
3.3 注意事项(重点)
(1) VPATH 只能决定 make 的搜索路径,无法决定命令的搜索路径。
(2) 对于特定的编译命令(gcc),需要独立指定编译搜索路径。make 层面的路径和 gcc 层面的路径是两个不同环境下的路径。makefile 中的命令是在当前 make 启动的新的 shell 中运行的,所以命令的工作路径就是当前 make 的工作路径。

【编程实验】:解决本文第2点(下面的make能够编译成功吗?)出现的问题
OBJS := func.o main.o
INC := inc
SRC := src
VPATH := $(INC) $(SRC)
CFLAGS := -I $(INC) hello.out : $(OBJS)
@gcc -o $@ $^
@echo "Target File ==> $@" $(OBJS) : %.o : %.c func.h
@echo $<
@gcc $(CFLAGS) -o $@ -c $<
makefile
执行 make 后程序的输出:

注意两点:
(1) 观察 echo 打印的自动变量 $< 它们是 .c 文件所处的路径,而不是它们本身,这表明 make 会根据模式规则推导出真正的规则。
func.o : func.c ==> func.o : inc/func.c
(2)编译 main.c 和 func.c 生成的 main.o 和 func.o 文件与 makefile 处在同一个目录下,这表明 gcc 默认生成的 .o文件放在其工作目录下。
3.4 VPATH存在的问题及其解决方案
3.4.1 VPATH 存在的问题
前面提到过,当多个文件夹存在同名文件时,选择第一次搜索到的文件。因为 makefile 中的 VPATH := $(INC) $(SRC) 变量首先包含的是 inc 目录,当 inc 文件夹中意外出现源文件时(C/Cpp文件),如 func.c 文件,那么就会使用该文件夹下同名的 func.c 文件,这就有可能产生编译错误!

3.4.2 解决方案
使用 vpath 关键字(全小写)替换 VPATH 预定义变量(全大写)。这里注意 VPATH 是 make 的预定义变量,而 vpath 是 make 中的关键字,要能够区分两者。
(1)vpath 为不同类型的文件指定不同的搜索路径
(2)语法:在 Directory 中搜索符合 Pattern 的规则的文件
(3)取消搜索规则
— 取消已经设置的某个搜索规则
- vpath Pattern
例:vpath %.h inc # 在 inc 中搜索 .h 文件
vpath %.h # 不再到 inc 中搜索 .h 文件
— 取消所有已经设置的规则
- vpath
【编程实验】:vpath 的使用
OBJS := func.o main.o
INC := inc
SRC := src
CFLAGS := -I $(INC) vpath %.h $(INC) # 使用vpath 关键字定义 .h 文件的搜索路径
vpath %.c $(SRC) # 使用vpath 关键字定义 .c 文件的搜索路径 hello.out : $(OBJS)
@gcc -o $@ $^
@echo "Target File ==> $@" # vpath %.h # 取消 vpath 关键字定义的 .h 文件的搜索路径 $(OBJS) : %.o : %.c func.h
@gcc $(CFLAGS) -o $@ -c $<
vpath 关键字的使用
注:本文整理于《狄泰12月提升计划》课程内容
狄泰QQ群:199546072
第17课 - make 中的路径搜索(上)的更多相关文章
- 第18课 - make 中的路径搜索(下)
第18课 - make 中的路径搜索(下) 1. 问题一 当 VPATH 和 vpath 同时出现,make 会如何处理? 工程项目的目录结构如下图所示,src1 和 src2 中都包含了 func. ...
- 第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数
第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; ...
- SQL 必知必会-- 第17课:创建和操作表
我这里用的是oracle 10g,PL/SQL来做的. 第17课 创建和操纵表 14517.1 创建表 14517.2 更新表 15017.3 删除表 15317.4 重命名表 1 ...
- 切记ajax中要带上AntiForgeryToken防止CSRF攻击
在程序项目中经常看到ajax post数据到服务器没有加上防伪标记,导致CSRF被攻击,下面小编通过本篇文章给大家介绍ajax中要带上AntiForgeryToken防止CSRF攻击,感兴趣的朋友一起 ...
- Linq to Sql:N层应用中的查询(上) : 返回自定义实体
原文:Linq to Sql:N层应用中的查询(上) : 返回自定义实体 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候,我们使 ...
- javaWeb中,文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- JavaWeb中文件的上传和下载
JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...
- JavaWeb中的文件上传和下载功能的实现
导入相关支持jar包:commons-fileupload.jar,commons-io.jar 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上 ...
- antd pro table中的文件上传
概述 示例代码 列表页面 form 页面 model.js service.js 总结 概述 项目中经常会遇到在表格中展示图片的需求(比如展示用户信息时, 有一列是用户的头像). antd pro t ...
随机推荐
- [Hadoop] mapper数量的控制
确定map任务数时依次优先参考如下几个原则: 1) 每个map任务使用的内存不超过800M,尽量在500M以下 比如处理256MB数据需要的时间为10分钟,内存为800MB,此时如果处理12 ...
- 设计模式:装饰者模式介绍及代码示例 && JDK里关于装饰者模式的应用
0.背景 来看一个项目需求:咖啡订购项目. 咖啡种类有很多:美式.摩卡.意大利浓咖啡: 咖啡加料:牛奶.豆浆.可可. 要求是,扩展新的咖啡种类的时候,能够方便维护,不同种类的咖啡需要快速计算多少钱,客 ...
- 机器学习 | 详解GBDT在分类场景中的应用原理与公式推导
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第31篇文章,我们一起继续来聊聊GBDT模型. 在上一篇文章当中,我们学习了GBDT这个模型在回归问题当中的原理.GBD ...
- unity探索者之socket传输protobuf字节流(二)
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/6977935.html 上一篇主要说的是protobuf字节流的序列化和解析,将pr ...
- 【Flutter 实战】一文学会20多个动画组件
老孟导读:此篇文章是 Flutter 动画系列文章第三篇,后续还有动画序列.过度动画.转场动画.自定义动画等. Flutter 系统提供了20多个动画组件,只要你把前面[动画核心](文末有链接)的文章 ...
- javaWeb项目之图书管理系统(附视频讲解)
视频播放地址:javaWeb图书系统 本系统为"Swing项目之图书管理系统"(此源码已共享)的Web版,网页框架用采用EasyUI 数据库为MysqL,写Web项目摒弃了火狐浏览 ...
- 经典的 Fork 炸弹解析
原文出处: saymagic Jaromil 在 2002 年设计了最为精简的一个Linux Fork炸弹,整个代码只有13个字符,在 shell 中运行后几秒后系统就会宕机: ::(){:|:&am ...
- 如何理解算法时间复杂度的表示法O(n²)、O(n)、O(1)、O(nlogn)等?
先从 来说,理论上哈希表就是O(1).因为哈希表是通过哈希函数来映射的,所以拿到一个关键字,用哈希函数转换一下,就可以直接从表中取出对应的值.和现存数据有多少毫无关系,故而每次执行该操作只需要恒定的时 ...
- Alpha阶段项目复审(鸽牌开发小分队)
团队:鸽牌开发专业小分队 项目:必备记 集合帖:集合帖 项目复审: 团队名字 项目链接 优点 缺点和bug报告 最终名次 歪瑞古德小队 海岛漂流 1.功能齐全,上手简单2.界面简洁美观3.想法新颖,可 ...
- muduo源码解析6-condtion类
condition class condition:noncopyable { }; 作用: 实现了最简单condtion操作,包括init,destroy,wait,notify,notifyAll ...