从头开始写项目Makefile(九):目录搜索

【版权声明:转载请保留出处:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】    

    在一个较大的工程中,一般会将源代码和二进制文件(.o 文件和可执行文件)安排在不同的目录来进行区分管理。这种情况下,我们可以使用 make 提供的目录搜索依赖文件功能(在指定的若干个目录下自动搜索依赖文件)。在Makefile中,使用依赖文件的目录搜索功能。当工程的目录结构发生变化后,就可以做到不更改 Makefile的规则,只更改依赖文件的搜索目录。

    在我们上一节出现的问题当中,我们将.c文件统一放在src目录下,没有和Makefile目录在同一目录下,因此没有办法寻找到.o文件的依赖文件。make程序有一个特殊的变量VPATH,该变量可以指定依赖文件的搜索路径,当规则的依赖文件在当前目录不存在时,make 会在此变量所指定的目录下去寻找这些依赖文件。通常我们都是用此变量来指定规则的依赖文件的搜索路径。
    定义变量 “VPATH”时,使用空格或者冒号(:)将多个需要搜索的目录分开。make搜索目录的顺序是按照变量“VPATH”定义中的目录顺序进行的,当前目录永远是第一搜索目录。例如如下定义
[html]  view plain copy
  1. VPATH += ./src  
指定了依赖搜索目录为当前目录下的src目录,我们可以在Makefile.rules里面添加给VPATH变量赋值,而在包含该Makefile.rules之前给出当前模块.c文件所在目录。
    其实我们也可以直接指定依赖文件的路径,这样也是可以的,如下:
[html]  view plain copy
  1. $(SRC_OBJ) : $(OBJDIR)/%.o : $(MOD_SRC_DIR)/%.c                                                                                                                            
  2. >---$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@  
    但是这样在我们更改了工程目录结构之后,对应的依赖文件没有在同一目录下,又变得麻烦了,所以还不如直接给VPATH变量赋值,我们只需要指定源码所在的目录即可。
    其实我们还有另外一种搜索文件路径方法:使用vpath关键字(注意不是VPATH变量), 它和VPATH类似,但是它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。使用方法有三种:
1、vpath PATTERN DIRECTORIES 
为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES” 。多个目录使用空格或者冒号(:)分开。 
2、vpath PATTERN 
清除之前为符合模式“PATTERN”的文件设置的搜索路径。 
3、vpath 
清除所有已被设置的文件搜索路径。
vapth 使用方法中的“PATTERN”需要包含模式字符“%”;例如上面的定义:
[html]  view plain copy
  1. VPATH += ./src  
可以写为:
[html]  view plain copy
  1. vpath %.c ./src  
现在给一个我们的Makefile.rules:
[html]  view plain copy
  1. # Copyright (C) 2014 shallnew \at 163 \dot com                                                                                                                             
  2.   
  3. # if without a platform defined, give value "unknow" to PLATFORM  
  4. ifndef PLATFORM  
  5. >---PLATFORM = unknow  
  6. endif  
  7.   
  8. # define a root build directory base on the platform  
  9. # if without a SRC_BASE defined, just use local src directory  
  10. ifeq ($(SRC_BASE),)  
  11. >---BUILDDIR = $(MOD_SRC_DIR)  
  12. >---OBJDIR = $(MOD_SRC_DIR)  
  13. >---LIBDIR = $(MOD_SRC_DIR)  
  14. >---BINDIR = $(MOD_SRC_DIR)  
  15. else  
  16. >---ifeq ($(DEBUG_SYMBOLS), TRUE)  
  17. >--->---BUILDDIR = $(SRC_BASE)/build/$(PLATFORM)_dbg  
  18. >---else  
  19. >--->---BUILDDIR = $(SRC_BASE)/build/$(PLATFORM)  
  20. >---endif  
  21. >---OBJDIR = $(BUILDDIR)/obj/$(MODULE)  
  22. >---LIBDIR = $(BUILDDIR)/lib  
  23. >---BINDIR = $(BUILDDIR)/bin  
  24. endif  
  25.   
  26. # update compilation flags base on "DEBUG_SYMBOLS"  
  27. ifeq ($(DEBUG_SYMBOLS), TRUE)  
  28. >---CFLAGS += -g -Wall -Werror -O0  
  29. else  
  30. >---CFLAGS += -Wall -Werror -O2  
  31. endif  
  32.   
  33. VPATH += $(MOD_SRC_DIR)  
  34.   
  35. SRC_OBJ = $(patsubst %.c, $(OBJDIR)/%.o, $(notdir $(SRC_FILES)))  
  36.   
  37. ifeq ($(MAKELEVEL), 0)  
  38. all : msg  
  39. else  
  40. all : lib bin  
  41. endif  
  42.   
  43. lib : $(OBJDIR) $(LIBDIR)/$(SRC_LIB)  
  44.   
  45. bin : $(OBJDIR) $(BINDIR)/$(SRC_BIN)  
  46.   
  47. $(OBJDIR) :  
  48. >---mkdir -p $@  
  49.   
  50. ifneq ($(SRC_BIN),)  
  51. $(BINDIR)/$(SRC_BIN) : $(SRC_OBJ)  
  52. >---$(CC) -o $@ $^ $(LDFLAGS)  
  53. endif  
  54.   
  55. ifneq ($(SRC_LIB),)  
  56. $(LIBDIR)/$(SRC_LIB) : $(SRC_OBJ)  
  57. >---$(AR) rcs $@ $^  
  58. >---cp $@ $(SRC_BASE)/libs  
  59. endif  
  60.   
  61. $(SRC_OBJ) : $(OBJDIR)/%.o : %.c  
  62. >---$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@  
  63.   
  64. msg:  
  65. >---@echo "You cannot directily execute this Makefile! This Makefile should called by toplevel Makefile."  
  66.   
  67.   
  68. # clean target  
  69. clean:  
  70. ifneq ($(SRC_LIB),)  
  71. >--->---$(RM) $(SRC_OBJ) $(LIBDIR)/$(SRC_LIB)  
  72. endif  
  73. ifneq ($(SRC_BIN),)  
  74. >--->---$(RM) $(SRC_OBJ) $(BINDIR)/$(SRC_BIN)  
  75. endif  
  76.   
  77. .PHONY : all clean      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值