原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/

在一个较大的工程中,一般会将源代码和二进制文件(.o 文件和可执行文件)安排在不同的目录来进行区分管理。这种情况下,我们可以使用 make 提供的目录搜索依赖文件功能(在指定的若干个目录下自动搜索依赖文件)。在Makefile中,使用依赖文件的目录搜索功能。当工程的目录结构发生变化 后,就可以做到不更改 Makefile的规则,只更改依赖文件的搜索目录。     在我们上一节出现的问题当中,我们将.c文件统一放在src目录下,没有和Makefile目录在同一目录下,因此没有办法寻找到.o文件的依赖文件。 make程序有一个特殊的变量VPATH,该变量可以指定依赖文件的搜索路径,当规则的依赖文件在当前目录不存在时,make 会在此变量所指定的目录下去寻找这些依赖文件。通常我们都是用此变量来指定规则的依赖文件的搜索路径。
    定义变量 “VPATH”时,使用空格或者冒号(:)将多个需要搜索的目录分开。make搜索目录的顺序是按照变量“VPATH”定义中的目录顺序进行的,当前目录永远是第一搜索目录。例如如下定义

VPATH += ./src

指定了依赖搜索目录为当前目录下的src目录,我们可以在Makefile.rules里面添加给VPATH变量赋值,而在包含该Makefile.rules之前给出当前模块.c文件所在目录。
    其实我们也可以直接指定依赖文件的路径,这样也是可以的,如下:

    $(SRC_OBJ) : $(OBJDIR)/%.o : $(MOD_SRC_DIR)/%.c
>---$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

但是这样在我们更改了工程目录结构之后,对应的依赖文件没有在同一目录下,又变得麻烦了,所以还不如直接给VPATH变量赋值,我们只需要指定源码所在的目录即可。
    其实我们还有另外一种搜索文件路径方法:使用vpath关键字(注意不是VPATH变量), 它和VPATH类似,但是它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。使用方法有三种:
1、vpath PATTERN DIRECTORIES
为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES” 。多个目录使用空格或者冒号(:)分开。
2、vpath PATTERN
清除之前为符合模式“PATTERN”的文件设置的搜索路径。
3、vpath
清除所有已被设置的文件搜索路径。
vapth 使用方法中的“PATTERN”需要包含模式字符“%”;例如上面的定义:

VPATH += ./src

可以写为:

vpath %.c ./src   

现在给一个我们的Makefile.rules:

# Copyright (C) 2014 shallnew \at 163 \dot com                                                                                                                             

# if without a platform defined, give value "unknow" to PLATFORM
ifndef PLATFORM
>---PLATFORM = unknow
endif # define a root build directory base on the platform
# if without a SRC_BASE defined, just use local src directory
ifeq ($(SRC_BASE),)
>---BUILDDIR = $(MOD_SRC_DIR)
>---OBJDIR = $(MOD_SRC_DIR)
>---LIBDIR = $(MOD_SRC_DIR)
>---BINDIR = $(MOD_SRC_DIR)
else
>---ifeq ($(DEBUG_SYMBOLS), TRUE)
>--->---BUILDDIR = $(SRC_BASE)/build/$(PLATFORM)_dbg
>---else
>--->---BUILDDIR = $(SRC_BASE)/build/$(PLATFORM)
>---endif
>---OBJDIR = $(BUILDDIR)/obj/$(MODULE)
>---LIBDIR = $(BUILDDIR)/lib
>---BINDIR = $(BUILDDIR)/bin
endif # update compilation flags base on "DEBUG_SYMBOLS"
ifeq ($(DEBUG_SYMBOLS), TRUE)
>---CFLAGS += -g -Wall -Werror -O0
else
>---CFLAGS += -Wall -Werror -O2
endif VPATH += $(MOD_SRC_DIR) SRC_OBJ = $(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC_FILES))) ifeq ($(MAKELEVEL), 0)
all : msg
else
all : lib bin
endif lib : $(OBJDIR) $(LIBDIR)/$(SRC_LIB) bin : $(OBJDIR) $(BINDIR)/$(SRC_BIN) $(OBJDIR) :
>---mkdir -p $@ ifneq ($(SRC_BIN),)
$(BINDIR)/$(SRC_BIN) : $(SRC_OBJ)
>---$(CC) -o $@ $^ $(LDFLAGS)
endif ifneq ($(SRC_LIB),)
$(LIBDIR)/$(SRC_LIB) : $(SRC_OBJ)
>---$(AR) rcs $@ $^
>---cp $@ $(SRC_BASE)/libs
endif $(SRC_OBJ) : $(OBJDIR)/%.o : %.c
>---$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ msg:
>---@echo "You cannot directily execute this Makefile! This Makefile should called by toplevel Makefile." # clean target
clean:
ifneq ($(SRC_LIB),)
>--->---$(RM) $(SRC_OBJ) $(LIBDIR)/$(SRC_LIB)
endif
ifneq ($(SRC_BIN),)
>--->---$(RM) $(SRC_OBJ) $(BINDIR)/$(SRC_BIN)
endif .PHONY : all clean

makefile--目标搜索(八)的更多相关文章

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

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

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

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

  3. Linux内核配置:Makefile目标

    在顶层Linux源码目录中输入命令make help,它会显示一长串从源码树中生成的目标列表.最常见的使用make的方式是不指定目标,在这种情况下,它会生成内核ELF文件vmlinux和针对所选架构的 ...

  4. Makefile 自动搜索 c 和 cpp 文件, 并生成 .a 静态库文件

    最近 又弄linux 下的 .a 静态库编译, 于是想 做个 一劳永逸的Makefile, 经过一番折腾, 最后成功了 只需要 改两个 参数 就可以执行了(MYLIB 和 VPATH), 代码 如下: ...

  5. 八数码问题:C++广度搜索实现

    毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限 ...

  6. Linux makefile教程之make运行八[转]

    make 的运行 —————— 一 般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让 make重编译某些文件, ...

  7. Makefile 描述的是文件编译的相关规则,它的规则主要是两个部分组成,分别是依赖的关系和执行的命令 PHONY伪目标实践

    Makefile的工作流程 http://c.biancheng.net/view/7091.html Makefile文件是什么? 我们教程主要是讲的是 Makefile .很多 Linux(Uni ...

  8. 【转】Linux makefile 教程 非常详细,且易懂

    From: http://blog.csdn.net/liang13664759/article/details/1771246 最近在学习Linux下的C编程,买了一本叫<Linux环境下的C ...

  9. Makefile经典教程(掌握这些足够)

    makefile很重要 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员 ...

  10. Linux makefile 教程 非常详细,且易懂

    最近在学习Linux下的C编程,买了一本叫<Linux环境下的C编程指南>读到makefile就越看越迷糊,可能是我的理解能不行. 于是google到了以下这篇文章.通俗易懂.然后把它贴出 ...

随机推荐

  1. html,body最顶层元素.

    1,元素百比分是相对父元素,所有元素默认父元素是body. absolute,fixed[只有一个父元素,浏览器窗口]除外[浏览器窗口,为父元素].css3:vh,vw也永远相对,浏览器窗口.heig ...

  2. scikit-learn 机器学习工具包

    scikit-learn官网:http://scikit-learn.org/stable/ scikit-learn初始化学习:  http://scikit-learn.org/stable/in ...

  3. 学习linux与wp8.1——启航

    现在不知不觉已经大三了,而本专业的东西没有多大感兴趣的,我看好wp开发和linux开发. 为什么要学习wp开发?其实就是一种兴趣,我手中有部620而已,学着学着就感兴趣了,所以打算继续学下去.同时,我 ...

  4. lastPathComponent的功能

    下面是官方的说明: 源字符串   --->     结果字符串 “/tmp/scratch.tiff”   --->     “scratch.tiff” “/tmp/scratch”   ...

  5. 前端CSS编程之道-LESS

    由于前端css编写繁琐,最近开始学习LESS,用LESS编写文件.less文件可以直接编译成我们要的.css文件 学习Less 我下面是我练习时的截图,希望小伙伴也能动手自己写一下,而不是复制粘贴模式 ...

  6. vs 折叠跟展开所有方法。

    Ctrl + M + O: 折叠所有方法 Ctrl + M + M: 折叠或者展开当前方法 Ctrl + M + L: 展开所有方法

  7. IOS弹出视图 LewPopupViewController

    LewPopupViewController是一款IOS弹出视图软件.iOS 下的弹出视图.支持iPhone/iPad. 软件截图 使用方法 弹出视图 1 2 3 4 5 PopupView *vie ...

  8. GPIO的8种工作模式

    1.浮空输入GPIO_IN_FLOATING ——浮空输入,可以做KEY识别,RX1 2.带上拉输入GPIO_IPU——IO内部上拉电阻输入 3.带下拉输入GPIO_IPD——IO内部下拉电阻输入 4 ...

  9. Python File I/O

    File is a named location on disk to store related information. It is used to permanently store data ...

  10. PAT 06-2 字符串字母大小写转换

    没什么好说的,记得使用ctype.h就好了,谭浩强那本书就介绍了,再不使用就太对不起他老人家了:有一点小小的地方需要注意一下,&&的优先级比=号高,所以getchar()两边没有括号的 ...