目录搜索

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

VPATH

VPATH:指定依赖文件的搜索目录,当规则的依赖文件在当前目录不存在时,make会在此变量所指定目录下去寻找这些依赖文件。

#VPATH = src

all: VPATH.o
@echo compile done %.o: %.c
gcc -c $< -o $@

源码路径

依赖文件通常你可以指定全路径,那么执行make时能找到依赖文件,就会编译出对应的目标文件。但是在一个大工程中,源码的目录结构复杂,每个依赖文件都带上绝对路径,makefile看起来会非常繁琐。上面给出的例子中,只有一个依赖文件,或许你可以这样写all: src/VPATH.o, 但是当依赖文件变多,目录结构变复杂,或者需要更改目录结构时,makefile文件的改动很大。但是如果使用VPATH指定搜索目录,那么只需要关注依赖文件的文件名,然后在VPATH中指定搜索路径即可。

vpath

vpath: make的一个关键字,和VPATH的功能类似,都是指定依赖文件的搜索目录。

使用的三种方法:

vpath PATTERN DIRECTORIES

为所有符合PATTERN的文件指定搜索目录DIRECTORIES.多个目录使用空格或冒号(:)分开

vpath PATTERN

清除之前 符合 PATTERN 的文件设置路径 

vpath

清除所有的已被设置的文件搜索路径

#为.c文件指定搜索目录
vpath %.c src all: vpath.o
@echo compile done %.o: %.c
gcc -c $< -o $@

源码路径

#为.c文件指定搜索目录
vpath %.c src
#为.h文件指定搜索目录
vpath %.h include all: vpath.o
@echo compile done %.o: %.c
gcc -MD -I include -c $< -o $@ clean:
rm *.o *.d

源码路径:https://github.com/suonikeyinsuxiao/trunk/tree/master/makefile_project/vpath/vpath/vp2

makefile vpath 中出现的.h文件,仅限于在makefile中有效。对于源文件#include的头文件仍需要使用-I + directory 指定搜索目录。

如果上例子中,将 -I include 去掉,那么make会报“src/vpath.c:2:19: fatal error: vpath.h: No such file or directory”的错误。

自动生成依赖关系

-MD 自动生成目标文件的依赖关系,并保存在*.d文件中。

#为.c文件指定搜索目录
vpath %.c src
#为.h文件指定搜索目录
vpath %.h include all: vpath.o
@echo compile done %.o: %.c
#gcc -MD -c $< -o $@
gcc -MD -I include -c $< -o $@ clean:
rm *.o *.d

修改src/vpath.c前,该源文件是#include "vpath.h"的。生成的vpath.d的内容是:vpath.o: src/vpath.c /usr/include/stdc-predef.h include/vpath.h

修改src/vpath.c后,即将源文件中的#include "vpath.h"注释掉。生成的vpath.d的内容是:vpath.o: src/vpath.c /usr/include/stdc-predef.h

显然少了 include/vpath.h.那使用-MD有什么作用呢。

试想,当在源文件中加入或者删除头文件时,如果不使用MD自动生成依赖关系,就需要手动的修改makefile中显示的依赖关系,显然这是一种低效的方式且容易出错。

gcc 的 "-MD"选项将自动寻找源文件中include的头文件,并生成文件的依赖关系,保存在*.d文件中。

incdirs := include include/src2
srcdirs := src src2 #指定源文件列表(由vpath处理路径问题)
srcs := vpath.c src2.c #指定中间文件目录
objdir := obj #指定目标文件列表
objlist := $(patsubst %.c, $(objdir)/%.o, $(srcs)) #指定gcc头文件路径
INCDIR := $(patsubst %, -I%, $(incdirs)) #为.c文件指定搜索目录
vpath %.c $(srcdirs)
#为.h文件指定搜索目录
vpath %.h $(incdirs) .PHONY: all clean objdir:
@echo "create obj directory"
-mkdir $(objdir) $(objdir)/%.o: %.c
gcc -MD $(INCDIR) -c $< -o $@ all: $(objdir) $(objlist)
@echo compile done clean:
rm $(objdir)/*.o $(objdir)/*.d $(objdir) -rf

源码路径

makefile之目录搜索&自动依赖的更多相关文章

  1. makefile自动依赖生成

    自动依赖生成 基于make的构建环境要正确工作, 一个很重要(也很烦人)的任务是, 在makefile中正确列 举依赖. 这个文档将介绍了一个非常有用的让make自身来创建和维护这些依赖的方法. 文章 ...

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

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

  3. makefile多目录的.c 格式.cpp混合编译

    # # c.cpp混合编译的makefile模板 # # BIN = test.exe CC = gcc CPP = g++ #这里只加入库头文件路径及库路径 INCS = -I"c:/mi ...

  4. Makefile之文件搜索

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

  5. [linux]makefile多目录

    在使用makefile多目录编写前需要掌握几个函数及符号 自定义变量 target=edit 引用的时候直接使用 $(target) 有点像C语言中的#define,这里的 $(target)会被替换 ...

  6. Makefile目标文件搜索(VPATH和vpath

    转载:http://c.biancheng.net/view/7051.html 我们都知道一个工程文件中的源文件有很多,并且存放的位置可能不相同(工程中的文件会被放到不同的目录下),所以按照之前的方 ...

  7. StringBoot整合ELK实现日志收集和搜索自动补全功能(详细图文教程)

    @ 目录 StringBoot整合ELK实现日志收集和搜索自动补全功能(详细图文教程) 一.下载ELK的安装包上传并解压 1.Elasticsearch下载 2.Logstash下载 3.Kibana ...

  8. (E2E_L2)包含目录、库目录、附加包含目录、附加库目录、附加依赖项之详解【正确的目录添加方法】

    VS项目中的包含目录.库目录.附加包含目录.附加库目录.附加依赖项均在"项目->属性->配置属性"下进行配置 一.具体说明如下: 1.VC++目录:     包含目录: ...

  9. Vs中包含目录、库目录、附加包含目录、附加库目录、附加依赖项之详解

    VS项目中的包含目录.库目录.附加包含目录.附加库目录.附加依赖项均在"项目->属性->配置属性"下进行配置,具体说明如下: VC++目录: 包含目录:寻找#inclu ...

随机推荐

  1. iOS中 三种随机数方法详解

    ios 有如下三种随机数方法: //第一种 srand((unsigned)time(0)); //不加这句每次产生的随机数不变 int i = rand() % 5; //第二种 srandom(t ...

  2. Openshift 用户,角色和RBAC

    OCP中的权限管理沿用的Kubernetes RBAC机制,授权模式主要取决于下面几个因数 Rules 针对主要对象的操作权限,比如建立Pod Sets of permitted verbs on a ...

  3. synchronized-异常

    对于web应用程序,异常释放锁的情况,很可能对你的应用程序业务逻辑产生必要严重的错误,比如:执行某个队列任务,很多对象都会去等待第一个对象正常执行的结果返回再次去释放锁,那么其中摸个对象发生执行异常了 ...

  4. jQuery中的动画与效果

    1.基本效果 匹配元素从左上角开始变浓变大或缩小到左上角变淡变小 ①隐藏元素 除了可以设置匹配元素的display:none外,可以用以下函数 hide(speed,[callback])  返回值: ...

  5. Dedecms会员中心注入漏洞

    详细说明: member/buy_action.php   require_once(dirname(__FILE__)."/config.php");   CheckRank(0 ...

  6. WINXP上安装及使用SqlMap之方法

    1.首先下载SqlMap 点击下载.2.其次下载用于Windows系统的Python ……点击这里…… 3.然后安装Python:Python默认安装的路径是“C:\Python”(你也可以修改安装路 ...

  7. springMVC配置静态资源访问的<mvc:resources>标签的使用

    在springmvc中,为了引用资源的访问不会类似Controller一样被拦截,区分出关注的资源的访问,一般我们在springMVC里面的拦截都会配置为"/",拦截所有的.但是这 ...

  8. Java反转单链表

    class Node { private int data; private Node nextNode; public Node(int data) { this.data = data; } pu ...

  9. EffectiveJava(29)优先考虑类型安全的异构容器

    当你的泛型集合需要更多的灵活性,你可以将键进行参数化而不是将容器进行参数化.然后将参数化的键提交给容器,来插入或者获取值.用泛型系统来确保值得类型与它的键相符. 我们创建一个Favorite类来模拟这 ...

  10. win 2003 / IIS6 部署网站的时候,文件IO操作、删除项目文件, 会导致IIS重启,Session丢失问题

    项目中经常需要打些日志(文件IO读写操作),已记录调试.错误等信息.比较方便的有log4net等开源项目. 问题描述: 最近用win 2003 / IIS6,部署了一个2.0 的网站,在操作文件的时候 ...