当前位置: 首页 > news >正文

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中的路径搜索 问题&#xff1a;在实际的工程项目中&#xff0c;所有的源文件和头文件都放在同一个文件夹中吗&#xff1f; 实验1 &#xff1a; VPATH 引子 mhrubuntu:~/work/makefile1/17$ ll total 28 drwxrwxr-x 4 mhr mhr 4096 Apr 22 00:46 ./ drwxrwxr-x 7 mhr m…...

蓝桥杯每日一题------背包问题(一)

点击可观看配套视频讲解 背包问题 阅读小提示&#xff1a;这篇文章稍微有点长&#xff0c;希望可以对背包问题进行系统详细的讲解&#xff0c;在看的过程中如果有任何疑问请在评论区里指出。因为篇幅过长也可以进行选择性阅读&#xff0c;读取自己想要的那一部分即可。 前言…...

面试 JavaScript 框架八股文十问十答第八期

面试 JavaScript 框架八股文十问十答第八期 作者&#xff1a;程序员小白条&#xff0c;个人博客 相信看了本文后&#xff0c;对你的面试是有一定帮助的&#xff01;关注专栏后就能收到持续更新&#xff01; ⭐点赞⭐收藏⭐不迷路&#xff01;⭐ 1&#xff09;实现call、apply…...

【机器学习】单变量线性回归

文章目录 线性回归模型&#xff08;linear regression model&#xff09;损失/代价函数&#xff08;cost function&#xff09;——均方误差&#xff08;mean squared error&#xff09;梯度下降算法&#xff08;gradient descent algorithm&#xff09;参数&#xff08;parame…...

《计算思维导论》笔记:10.4 关系模型-关系运算

《大学计算机—计算思维导论》&#xff08;战德臣 哈尔滨工业大学&#xff09; 《10.4 关系模型-关系运算》 一、引言 本章介绍数据库的基本数据模型&#xff1a;关系模型-关系运算。 二、什么是关系运算 在数据库理论中&#xff0c;关系运算&#xff08;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安装、图形化界面

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…...

Linux(Ubuntu) 环境搭建:Nginx

注&#xff1a;服务器默认以root用户登录 NGINX 官方网站地址&#xff1a;https://nginx.org/en/NGINX 官方安装文档地址&#xff1a;https://nginx.org/en/docs/install.html服务器的终端中输入以下指令&#xff1a; # 安装 Nginx apt-get install nginx # 查看版本信息 ngi…...

快速手动完成 VS 编写脚本自动化:如何选取最高效的工作方式?

那些不懂技术的朋友们可能会觉得&#xff0c;写代码写脚本不就是敲敲键盘嘛&#xff0c;搞那么高科技做什么&#xff0c;直接手工点点鼠标不就完事了。 这种看法很常见&#xff0c;但实际情况要复杂得多。 首先&#xff0c;手工操作虽然对于短期和小规模的任务来说似乎更快&am…...

FAST角点检测算法

FAST&#xff08;Features from Accelerated Segment Test&#xff09;角点检测算法是一种快速且高效的角点检测方法。它通过检测每个像素周围的连续像素集合&#xff0c;确定是否为角点。以下是 FAST 角点检测算法的基本流程&#xff1a; FAST 角点检测算法的基本过程主要包括…...

Python中使用opencv-python进行人脸检测

Python中使用opencv-python进行人脸检测 之前写过一篇VC中使用OpenCV进行人脸检测的博客。以数字图像处理中经常使用的lena图像为例&#xff0c;如下图所示&#xff1a; 使用OpenCV进行人脸检测十分简单&#xff0c;OpenCV官网给了一个Python人脸检测的示例程序&#xff0c;…...

牛客网 DP3跳台阶扩展问题

在原始跳台阶问题上&#xff0c;我们知道只走1&#xff0c;2阶台阶的话&#xff0c;可以推出来斐波那契数列的形式进行计算操作。但是&#xff0c;在这里就是1&#xff0c;2&#xff0c;3&#xff0c;...n阶台阶了。其实思路是一样的。 在原始台阶问题&#xff0c;我们的状态方…...

ARM汇编[1] 打印格式化字符串(printf

文章目录 写在前面关键知识简单加减乘除函数调用和循环系统调用栈的使用 GDB调试示例代码 写在前面 如果您对ARM汇编还一无所知的话请先参考ARM汇编hello world 本篇不会广泛详细的列举各种指令&#xff0c;仍然只讲解最关键的部分&#xff0c;然后使用他们来完成一个汇编程序…...

Java 集合、迭代器

Java 集合框架主要包括两种类型的容器&#xff0c;一种是集合&#xff08;Collection&#xff09;&#xff0c;存储一个元素集合&#xff0c;另一种是图&#xff08;Map&#xff09;&#xff0c;存储键/值对映射。Collection 接口又有 3 种子类型&#xff0c;List、Set 和 Queu…...

在 Docker 中启动 ROS2 里的 rivz2 和 rqt 出现错误的解决方法

1. 出现错误&#xff1a; 运行 ros2 run rivz2 rivz2 &#xff0c;报错如下 &#xff1a; 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&#xff1a;192.168.9.133 ubuntu-desktop20.04机器IP&#xff1a;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:概念和分类总结

前言 大家好&#xff0c;我是chowley&#xff0c;刚看完Java IO方面内容&#xff0c;特此总结一下。 Java IO Java IO&#xff08;输入输出&#xff09;是Java编程中用于处理输入和输出的API。它提供了一套丰富的类和方法&#xff0c;用于读取和写入数据到不同的设备、文件和…...

【Linux】基本命令(下)

目录 head指令 && tail指令 head指令 tail指令 find指令 grep指令 zip/unzip指令 tar指令 时间相关的指令 date显示 1.在显示方面&#xff0c;使用者可以设定欲显示的格式&#xff0c;格式设定为一个加号后接数个标记&#xff0c;其中常用的标记列表如下&…...

腾讯云游戏联机服务器配置价格表,4核16G/8核32G/4核32G/16核64G

2024年更新腾讯云游戏联机服务器配置价格表&#xff0c;可用于搭建幻兽帕鲁、雾锁王国等游戏服务器&#xff0c;游戏服务器配置可选4核16G12M、8核32G22M、4核32G10M、16核64G35M、4核16G14M等配置&#xff0c;可以选择轻量应用服务器和云服务器CVM内存型MA3或标准型SA2实例&am…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...