目录搜索

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

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. 一、从Windows消息机制说起

      一,消息       消息(Message)指的就是Windows 操作系统发给应用程序的一个通知,它告诉应用程序某个特定的事件发生了.比如,用户单击鼠标或按键都会引发Windows 系统发送相应 ...

  2. git 超前一个版本 落后一个版本的解决方案

    在使用SourceTree的时候经常会遇见超前一个版本,落后N个版本的情况,遇见这种情况应该怎么办呢? 首先打开终端,最好是从SourceTree里面打开,菜单栏有个终端按钮. 然后输入: $ git ...

  3. Centos6.8配置svn

    svn的安装:yum -y install subversion 一.一个仓库放所有的项目 创建仓库,以后所有代码都放在这个下面,创建成功后在svn下面多了几个文件夹.1.创建仓库:svnadmin ...

  4. KRBTabControl

    This article explains how to make a custom Windows Tab Control in C#. Download demo project - 82.4 K ...

  5. C# this.Hide()

    C# this.Hide() 第一次用的时候是在_Load函数里: BookSystem bs = new BookSystem();             bs.ShowDialog();     ...

  6. [Angular] Extract Implementation Details of ngrx from an Angular Application with the Facade Pattern

    Extracting away the implementation details of ngrx from your components using the facade pattern cre ...

  7. 正则表达式匹配a标签或div标签

    这里以a标签为例 a标签的href var a='<P><A href=\'~abc/ccg/ab.jpg\' width="3">文字</A> ...

  8. activemq5.14.5单节点安装Demo

    什么情况下使用ActiveMQ? 1     多个项目之间集成 (1) 跨平台 (2) 多语言 (3) 多项目 2     降低系统间模块的耦合度,解耦 软件扩展性 3     系统前后端隔离 前后端 ...

  9. jQuery中,实现css格式的改变

    jQuery中,实现属性值的改变 (1)prop属性实现,html中标签的class属性值发生改变: 语法:$(元素标识).prop("class",类属性值); 例子:$(&qu ...

  10. 001-使用idea开发环境安装部署,npm工具栏,脚本运行

    一.概述 参看官方文档:https://ant.design/docs/spec/introduce-cn 其中包含了设计价值观.设计原则.视觉.模式.可视化.动态等. 其中Ant Design 的 ...