Makefile编译原理 make 中的路径搜索_1
一.make中的路径搜索
问题:在实际的工程项目中,所有的源文件和头文件都放在同一个文件夹中吗?

实验1 : VPATH 引子
mhr@ubuntu:~/work/makefile1/17$ ll
total 28
drwxrwxr-x 4 mhr mhr 4096 Apr 22 00:46 ./
drwxrwxr-x 7 mhr mhr 4096 Apr 22 00:32 ../
drwxrwxrwx 2 mhr mhr 4096 Jan 23 2018 inc/
-rw-rw-r-- 1 mhr mhr 133 Apr 22 00:46 makefile
drwxrwxrwx 2 mhr mhr 4096 Jan 23 2018 src/
mhr@ubuntu:~/work/makefile1/17$ inc/func.h#include <stdio.h>
#include "func.h"void foo()
{printf("void foo() : %s\n", "This file is from inc ...");
}src/func.c#include <stdio.h>
#include "func.h"void foo()
{printf("void foo() : %s\n", HELLO);
}src/main.c#include <stdio.h>
#include "func.h"int main()
{foo();return 0;
} makefileOBJS := func.o main.ohello.out : $(OBJS)@gcc -o $@ $^@echo "Target File ==> $@"$(OBJS) : %.o : %.c func.h@gcc -o $@ -c $^mhr@ubuntu:~/work/makefile1/17$
mhr@ubuntu:~/work/makefile1/17$ make
make: *** No rule to make target 'func.c', needed by 'func.o'. Stop.
mhr@ubuntu:~/work/makefile1/17$
当前makefile: 要创建的可执行程序 hello.out 依赖于 func.o main.o 两个目标文件(当前目录下搜索不到这两个文件),这两个目标文件是通过 规则中的模式替换:
$(OBJS) : %.o : %.c func.h@gcc -o $@ -c $^
解决办法:

make对VPATH值的处理方式
- 当前文件夹找不到需要的文件时,VPATH就会被使用
- make会在VPATH指定的文件夹中依次搜索文件
- 当多个文件夹存在同名文件时,选择第一次搜索到的文件
实验2 VPATH 初体验, VPATH 只能决定 make 的搜索路径,无法决定命令的搜索路径
OBJS := func.o main.oVPATH := inc srchello.out : $(OBJS)@gcc -o $@ $^@echo "Target File ==> $@"$(OBJS) : %.o : %.c func.h@gcc -o $@ -c $<mhr@ubuntu:~/work/makefile1/17$
mhr@ubuntu:~/work/makefile1/17$ make
src/main.c:2:18: fatal error: func.h: No such file or directory#include "func.h"^
compilation terminated.
makefile:11: recipe for target 'main.o' failed
make: *** [main.o] Error 1
mhr@ubuntu:~/work/makefile1/17$
显然,这次没有提示: make: *** No rule to make target ‘func.c’, needed by ‘func.o’. Stop.的错误,说明 maka找到了 需要的源文件,即
$(OBJS) : %.o : %.c func.h
找到了 需要的源文件,但是该规则的命令却执行失败。
原因:VPATH 只能决定 make 的搜路径,无法决定命令的搜索路径,他对命令没有任何作用,上面得到的编译错误是因为 gcc 在编译.c文件的时候找不到对应的头文件。
实验3:指定编译命令gcc 需要的文件的搜索路径
OBJS := func.o main.oINC := inc
SRC := src
VPATH := $(INC) $(SRC)
CFLAGS := -I $(INC)hello.out : $(OBJS)@gcc -o $@ $^@echo "Target File ==> $@"$(OBJS) : %.o : %.c func.h // 为 make 提供搜索路径 :VPATH := $(INC) $(SRC)@gcc $(CFLAGS) -o $@ -c $< //为 gcc 命令 提供搜索路径,搜索 func.h:-I $(INC)
$(OBJS) : %.o : %.c func.h // 为 make 解释器提供搜索路径 :VPATH := $(INC) $(SRC) ,这样make解释器就得到了需要的文件,并根据规则中的模式替换,生成了最后的规则。
实验4:当多个文件夹存在同名文件时,选择第一次搜索到的文件
假如 inc 头文件文件夹中由于手误也存入了一个 func.c 那么会发生什么
inc/ func.h func.c
这里的func.c 内容如下:
#include <stdio.h>
#include "func.h"void foo()
{printf("void foo() : %s\n", "This file is from inc ...");
}makefile:OBJS := func.o main.oINC := inc
SRC := src
VPATH := $(INC) $(SRC)
CFLAGS := -I $(INC)hello.out : $(OBJS)@gcc -o $@ $^@echo "Target File ==> $@"$(OBJS) : %.o : %.c func.h // 为 make 提供搜索路径 :VPATH := $(INC) $(SRC)@gcc $(CFLAGS) -o $@ -c $< //为 gcc 命令 提供搜索路径,搜索 func.h:-I $(INC)mhr@ubuntu:~/work/makefile1/17$ ./hello.out
void foo() : This file is from inc ...
mhr@ubuntu:~/work/makefile1/17$
VPATH 变量告诉make解释器,当在当前目录找不到需要的文件的时候 首先到 inc文件夹中找,如果找不到 再去src文件夹中去找。如果在inc文件夹中找到了需要的文件,那么就不会继续去src文件夹中寻找了。但是inc 中的文件是我们手误放进去的,所以不是我们想要的结果,那么这种情况怎么办呢?

即说明 .h 头文件在 inc文件夹中去找; .c文件到 src文件夹中去找
实验5:vpath(小写) 初探
OBJS := func.o main.o
INC := inc
SRC := src
CFLAGS := -I $(INC)vpath %.h $(INC)
vpath %.c $(SRC)hello.out : $(OBJS)@gcc -o $@ $^@echo "Target File ==> $@"$(OBJS) : %.o : %.c func.h@gcc $(CFLAGS) -o $@ -c $<mhr@ubuntu:~/work/makefile1/17$
mhr@ubuntu:~/work/makefile1/17$ ./hello.out
void foo() : Hello D.T.
mhr@ubuntu:~/work/makefile1/17$

相关文章:
Makefile编译原理 make 中的路径搜索_1
一.make中的路径搜索 问题:在实际的工程项目中,所有的源文件和头文件都放在同一个文件夹中吗? 实验1 : VPATH 引子 mhrubuntu:~/work/makefile1/17$ ll total 28 drwxrwxr-x 4 mhr mhr 4096 Apr 22 00:46 ./ drwxrwxr-x 7 mhr m…...
蓝桥杯每日一题------背包问题(一)
点击可观看配套视频讲解 背包问题 阅读小提示:这篇文章稍微有点长,希望可以对背包问题进行系统详细的讲解,在看的过程中如果有任何疑问请在评论区里指出。因为篇幅过长也可以进行选择性阅读,读取自己想要的那一部分即可。 前言…...
面试 JavaScript 框架八股文十问十答第八期
面试 JavaScript 框架八股文十问十答第八期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)实现call、apply…...
【机器学习】单变量线性回归
文章目录 线性回归模型(linear regression model)损失/代价函数(cost function)——均方误差(mean squared error)梯度下降算法(gradient descent algorithm)参数(parame…...
《计算思维导论》笔记:10.4 关系模型-关系运算
《大学计算机—计算思维导论》(战德臣 哈尔滨工业大学) 《10.4 关系模型-关系运算》 一、引言 本章介绍数据库的基本数据模型:关系模型-关系运算。 二、什么是关系运算 在数据库理论中,关系运算(Relational Operatio…...
QT+OSG/osgEarth编译之八十四:osgdb_osg+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_osg)
文章目录 一、osgdb_osg介绍二、文件分析三、pro文件四、编译实践一、osgdb_osg介绍 osgDB是OpenSceneGraph(OSG)库中的一个模块,用于加载和保存3D场景数据。osgDB_osg是osgDB模块中的一个插件,它提供了对OSG格式的支持。 OSG格式是OpenSceneGraph库使用的一种二进制文件…...
【Redis快速入门】初识Redis、Redis安装、图形化界面
个人名片: 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️…...
Linux(Ubuntu) 环境搭建:Nginx
注:服务器默认以root用户登录 NGINX 官方网站地址:https://nginx.org/en/NGINX 官方安装文档地址:https://nginx.org/en/docs/install.html服务器的终端中输入以下指令: # 安装 Nginx apt-get install nginx # 查看版本信息 ngi…...
快速手动完成 VS 编写脚本自动化:如何选取最高效的工作方式?
那些不懂技术的朋友们可能会觉得,写代码写脚本不就是敲敲键盘嘛,搞那么高科技做什么,直接手工点点鼠标不就完事了。 这种看法很常见,但实际情况要复杂得多。 首先,手工操作虽然对于短期和小规模的任务来说似乎更快&am…...
FAST角点检测算法
FAST(Features from Accelerated Segment Test)角点检测算法是一种快速且高效的角点检测方法。它通过检测每个像素周围的连续像素集合,确定是否为角点。以下是 FAST 角点检测算法的基本流程: FAST 角点检测算法的基本过程主要包括…...
Python中使用opencv-python进行人脸检测
Python中使用opencv-python进行人脸检测 之前写过一篇VC中使用OpenCV进行人脸检测的博客。以数字图像处理中经常使用的lena图像为例,如下图所示: 使用OpenCV进行人脸检测十分简单,OpenCV官网给了一个Python人脸检测的示例程序,…...
牛客网 DP3跳台阶扩展问题
在原始跳台阶问题上,我们知道只走1,2阶台阶的话,可以推出来斐波那契数列的形式进行计算操作。但是,在这里就是1,2,3,...n阶台阶了。其实思路是一样的。 在原始台阶问题,我们的状态方…...
ARM汇编[1] 打印格式化字符串(printf
文章目录 写在前面关键知识简单加减乘除函数调用和循环系统调用栈的使用 GDB调试示例代码 写在前面 如果您对ARM汇编还一无所知的话请先参考ARM汇编hello world 本篇不会广泛详细的列举各种指令,仍然只讲解最关键的部分,然后使用他们来完成一个汇编程序…...
Java 集合、迭代器
Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queu…...
在 Docker 中启动 ROS2 里的 rivz2 和 rqt 出现错误的解决方法
1. 出现错误: 运行 ros2 run rivz2 rivz2 ,报错如下 : No protocol specified qt.qpa.xcb: could not connect to display :1 qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was f…...
使用securecrt+xming通过x11访问ubuntu可视化程序
windows使用securecrtxming通过x11访问ubuntu可视化程序 windows机器IP:192.168.9.133 ubuntu-desktop20.04机器IP:192.168.9.190 windows下载xming并安装 按照图修改xming配置 开始->xming->Xlaunch 完成xming会在右下角后台运行 windows在…...
红队打靶练习:HEALTHCARE: 1
目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、gobuster 2、dirsearch WEB web信息收集 gobuster cms sqlmap 爆库 爆表 爆列 爆字段 FTP 提权 信息收集 本地提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Inte…...
Java IO:概念和分类总结
前言 大家好,我是chowley,刚看完Java IO方面内容,特此总结一下。 Java IO Java IO(输入输出)是Java编程中用于处理输入和输出的API。它提供了一套丰富的类和方法,用于读取和写入数据到不同的设备、文件和…...
【Linux】基本命令(下)
目录 head指令 && tail指令 head指令 tail指令 find指令 grep指令 zip/unzip指令 tar指令 时间相关的指令 date显示 1.在显示方面,使用者可以设定欲显示的格式,格式设定为一个加号后接数个标记,其中常用的标记列表如下&…...
腾讯云游戏联机服务器配置价格表,4核16G/8核32G/4核32G/16核64G
2024年更新腾讯云游戏联机服务器配置价格表,可用于搭建幻兽帕鲁、雾锁王国等游戏服务器,游戏服务器配置可选4核16G12M、8核32G22M、4核32G10M、16核64G35M、4核16G14M等配置,可以选择轻量应用服务器和云服务器CVM内存型MA3或标准型SA2实例&am…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
