转载:http://c.biancheng.net/view/7051.html

我们都知道一个工程文件中的源文件有很多,并且存放的位置可能不相同(工程中的文件会被放到不同的目录下),所以按照之前的方式去编写 Makefile 会有问题。

我们之前列举的例子,所有的源文件基本上都是存放在与 Makefile 相同的目录下。只要依赖的文件存在,并且依赖规则没有问题,执行 make命令整个工程就会按照对我们编写规则去编译,最终会重建目标文件。那如果需要的文件是存在于不同的路径下,在编译的时候要去怎么办呢(不改变工程的结构)?这就用到了 Makefile 中为我们提供的目录搜索文件的功能。

常见的搜索的方法的主要有两种:一般搜索VPATH和选择搜索vpath。乍一看只是大小写的区别,其实两者在本质上也是不同的。

VPATH 和 vpath 的区别:VPATH 是变量,更具体的说是环境变量,Makefile 中的一种特殊变量,使用时需要指定文件的路径;vpath 是关键字,按照模式搜索,也可以说成是选择搜索。搜索的时候不仅需要加上文件的路径,还需要加上相应限制的条件。

VPATH的使用

在 Makefile 中可以这样写:

VPATH := src

我们可以这样理解,把 src 的值赋值给变量 VPATH,所以在执行 make 的时候会从 src 目录下找我们需要的文件。

当存在多个路径的时候我们可以这样写:

VPATH := src car

或者是

VPATH := src:car

多个路径之间要使用空格或者是冒号隔开,表示在多个路径下搜索文件。搜索的顺序为我们书写时的顺序,拿上面的例子来说,我们应该先搜索 src 目录下的文件,再搜索 car 目录下的文件。

注意:无论你定义了多少路径,make 执行的时候会先搜索当前路径下的文件,当前目录下没有我们要找的文件,才去 VPATH 的路径中去寻找。如果当前目录下有我们要使用的文件,那么 make 就会使用我们当前目录下的文件。

实例:

  1. VPATH=src car
  2. test:test.o
  3. gcc -o $@ $^

假设 test.c 文件没有在当前的目录而在当前文件的子目录 "src" 或者是 "car" 下,程序执行是没有问题的,但是生成的 test 的文件没有在定义的子目录文件中而是在当前的目录下,当然生成文件路径可以指定。

vpath的使用

学习了 VPATH的使用,我们再来了解一下关键字搜索 vpath 的使用,这种搜索方式一般被称作选择性搜索。使用上的区别我们可以这样理解:VPATH 是搜索路径下所有的文件,而 vpath 更像是添加了限制条件,会过滤出一部分再去寻找。
 
具体用法:

1) vpath PATTERN DIRECTORIES 
2) vpath PATTERN
3) vpath

( PATTERN:可以理解为要寻找的条件,DIRECTORIES:寻找的路径 )

首先是用法一,命令格式如下:

vpath test.c src

可以这样理解,在 src 路径下搜索文件 test.c。多路径的书写规则如下:

vpath test.c src car         或者是         vpath test.c src : car

多路径的用法其实和 VPATH 差不多,都是使用空格或者是冒号分隔开,搜索路径的顺序是先 src 目录,然后是 car 目录。

其次是用法二,命令格式如下:

vpath test.c

用法二的意思是清除符合文件 test.c 的搜索目录。

最后是用法三,命令格式如下:

vpath

vpath 单独使的意思是清除所有已被设置的文件搜索路径。

另外在使用 vpath 的时候,搜索的条件中可以包含模式字符“%”,这个符号的作用是匹配一个或者是多个字符,例如“%.c”表示搜索路径下所有的 .c 结尾的文件。如果搜索条件中没有包含“%" ,那么搜索的文件就是具体的文件名称。
 
使用什么样的搜索方法,主要是基于编译器的执行效率。使用 VPATH 的情况是前路径下的文件较少,或者是搜索的文件不能使用通配符表示,这些情况下使用VPATH最好。如果存在某个路径的文件特别的多或者是可以使用通配符表示的时候,就不建议使用 VPATH 这种方法,为什么呢?因为 VPATH 在去搜索文件的时没有限制条件,所以它回去检索这个目录下的所有文件,每一个文件都会进行对比,搜索和我们目录名相同的文件,不仅速度会很慢,而且效率会很低。我们在这种情况下就可以使用 vpath 搜索,它包含搜索条件的限制,搜索的时候只会从我们规定的条件中搜索目标,过滤掉不符合条件的文件,当然查找的时候也会比较的快。

Makefile目标文件搜索(VPATH和vpath的更多相关文章

  1. Makefile之文件搜索

    Makefile之文件搜索 1.Makefile 文件中的"VPATH"变量 如果没有指明这个变量,make只会在当前目录下查找依赖文件和目标文件: 如果定义了这个变量,make会 ...

  2. makefile之VPATH和vpath的使用

    来自阅读陈皓的<跟我一起写makefile> VPATH变量 在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中.所以,当 make 需要去找寻文 ...

  3. Makefile目标,伪目标,头文件自动依赖

    目标 即我们最终要生成的文件,make默认生成第一个目标,注意 makefile中tab和空格不是一回事,规则使用tab缩进,编辑器不要设置诸如"将tab替换为空格之类的选项",目 ...

  4. 实现目标文件与源码分开的makefile测试实验

    uboot提供了两种编译策略,即可以将生成的目标文件与源码混在一起,也可以将生成的目标文件与源码分开.通过对uboot Makefile的分析,笔者编写了一个简单的实现这种功能的Makfile. 顶层 ...

  5. makefile之目录搜索&自动依赖

    目录搜索 在一个大工程中,一般会将源文件和中间生成文件放在不同的目录,而且不会污染源码所在的目录.当需要编译不同目录下的源文件时,就需要指定路径,那么怎样让路径的表示以及源文件的引用更加灵活.就要用到 ...

  6. gcc编译时头文件和库文件搜索路径

    特殊情况:用户自定义的头文件使用#include"mylib"时,gcc编译器会从当前目录查找头文件 一.头文件 gcc 在编译时寻找所需要的头文件 :    ※搜寻会从-I开始( ...

  7. [转]Linux学习笔记——例说makefile 头文件查找路径

    0.前言     从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助 ...

  8. C#如何获取快捷方式指向的目标文件

    前几天,做个小程序时遇到的问题,在百度上搜索了很久,没有发现好的解决方案,在英文网站上立刻搜到办法,看来还是国外的资源要全面一些,只是Google经常访问不正常,没办法啊. “C#如何获取快捷方式指向 ...

  9. 查看目标文件是否是以-fPIC编译的, ar 打包命令将多个静态库打包到一个里面

    readelf --relocs foo.o | egrep '(GOT|PLT|JU?MP_SLOT)' 上句大多数时候(和平台有关)可以正确判断是否是以fPIC选项编译的,如果输出为空,基本可以表 ...

随机推荐

  1. go的database/sql库中db.Exce()

    db.Exec(query string, args ...interface{}) Db.Exec(`CREATE TABLE IF NOT EXISTS STU(ID int(8) PRIMARY ...

  2. systemctl添加自定义系统服务

    [Service] Type=forking ExecStart=绝对路径 ExecStop=绝对路径 ExecReload=绝对路径 以上最精简版,文件/usr/lib/systemd/system ...

  3. 现在互联网好多bug 想到都烦

    我接触计算机十多年了,只是在15年前发布一篇给计算机有关的技术文章,后来就在也不发表了,今天在163博客写个备录,,写到一半结果误 关了,,浪费了好几个小时,还以为像以前那样,又要重写,,这也是我不爱 ...

  4. 记一次docker compose的低级错误

    记一次docker compose的低级错误 问题 ​ 今天在学习dockercompose的时候,启动docker compose up,结果却出现异常 Error response from da ...

  5. xml字符串转成数组(php)

    1 $str = '<xml> 2 <ToUserName> <![CDATA[gh_fc0a06a20993]]> </ToUserName> 3 & ...

  6. Java线程类

    基础知识 线程状态 根据Thread.State类中的描述,Java中线程有六种状态:NEW,RUNNABLE,WAITING,TERMINATED,BLOCKED. 就绪状态(NEW):当线程对象调 ...

  7. 检验appium环境是否正常:使用appium自动给手机安装app(注意:如果已存在该app,再执行会将原来的卸载再重装,需谨慎)

    (注意:如果已存在该app,再执行会将原来的卸载再重装.泪的教训,我的微信被卸载重装了o(╥﹏╥)o,自动安装app这个步骤需谨慎操作) hi,前面几篇已经讲了appium环境的搭建.设备的连接, 那 ...

  8. AT1983-[AGC001E]BBQ Hard【dp,组合数学】

    正题 题目链接:https://www.luogu.com.cn/problem/AT1983 题目大意 给出\(n\)个数对\((a_i,b_i)\) 求 \[\sum_{i=1}^n\sum_{j ...

  9. 关于Windows操作系统重定向

    在用C++做一个文件遍历的时候发现,当我遍历C:\Windows\system32文件夹时,获取到的文件数目和实际总是对不上.在通过他人帮助后了解到了重定向这个概念,我百度了一下,下面为粘贴内容. S ...

  10. 关于zimbra的复现以及突破

    Zimbra未登录RCE漏洞利用 首先我是根据这个PDF进行复现的,但是复现过程出现很多问题 首先使用这个XXE读取文件 <!DOCTYPE xxe [ <!ELEMENT name AN ...