23.模块独立编译的支持

目录

 

1.问题

2.问题背景

3.解决方案

4.关键技术点

5.makefile中代码复用

6.思路

7.小结


1.问题

一般而言,不同工程师负责不同模块的开发;编译环境中如何支持模块的独立编译?

 

2.问题背景

  • 大型项目的代码文件成千上万,完整编译的时间较长
  • 编写模块代码时,可通过编译检查语法
  • 为了提高开发效率,需要支持指定模块的独立编译

示例:

3.解决方案

  • 将模块(module作为目标名(伪目标)建立规则
  • 目标(module)对应的依赖为build build/module
  • 规则中的命令进入对应的模块文件夹进行编译
  • 编译结果存放于build文件夹下

pro-rule.mk增加以下内容

.PHONY : all compile link clean rebuild $(MODULES)

……………

$(MODULES) :

        @echo "Begin to compile $@"

测试一下

aston@ubuntu:~/disciple$ make main

Begin to compile main

aston@ubuntu:~/disciple$ make common

Begin to compile common

aston@ubuntu:~/disciple$ make module

Begin to compile module

 

4.关键技术点

  • 如何获取make命令行中指定编译的模块名?
  • 预定义变量:

            命令行中指定的目标名(make的命令行参数)

不可以

然后开始写依赖,测试一下:

$(MODULES) : $(DIR_BUILD) $(DIR_BUILD)/$@

        @echo "Begin to compile $@"

aston@ubuntu:~/disciple$ make common

mkdir  build

Begin to compile common

看起来没问题,但是只创建了build目录,并没有创建common目录

怎么解决呢?使用MAKECMDGOALS

$(MODULES) : $(DIR_BUILD) $(DIR_BUILD)/$(MAKECMDGOALS)

        @echo "Begin to compile $@"

测试一下:

make common

mkdir  build

mkdir  build/common

Begin to compile common

接下来就是编译代码了,直接复制就可以了

$(MODULES) : $(DIR_BUILD) $(DIR_BUILD)/$(MAKECMDGOALS)
        @echo "Begin to compile $@"
        @set -e; \
        cd $@ && \
           $(MAKE) all \
           DEBUG:=$(DEBUG) \
           DIR_BUILD:=$(addprefix $(DIR_PROJECT)/, $(DIR_BUILD)) \
           DIR_COMMON_INC:=$(addprefix $(DIR_PROJECT)/, $(DIR_COMMON_INC)) \
           MOD_CFG:=$(addprefix $(DIR_PROJECT)/, $(MOD_CFG)) \
           MOD_RULE:=$(addprefix $(DIR_PROJECT)/, $(MOD_RULE)) \
           CMD_CFG:=$(addprefix $(DIR_PROJECT)/, $(CMD_CFG)) &&\
           cd ..; \

测试一下:

make common

mkdir  build

mkdir  build/common

Begin to compile common

make[1]: Entering directory `/home/aston/disciple/common'

/home/aston/disciple/mod-rule.mk:19: /home/aston/disciple/build/common/common.dep: No such file or directory

/home/aston/disciple/mod-rule.mk:19: /home/aston/disciple/build/common/func.dep: No such file or directory

Creating /home/aston/disciple/build/common/func.dep...

Creating /home/aston/disciple/build/common/common.dep...

make[1]: Leaving directory `/home/aston/disciple/common'

make[1]: Entering directory `/home/aston/disciple/common'

ar crs  /home/aston/disciple/build/common.a /home/aston/disciple/build/common/common.o /home/aston/disciple/build/common/func.o

make[1]: Leaving directory `/home/aston/disciple/common'

aston@ubuntu:~/disciple$ ls build/

common  common.a

5.makefile中代码复用

  • 当不同规则中的命令大量重复时,可以考虑自定义函数
  • makefile中的自定义函数是代码复用的一种方式

上面我们是直接复制粘贴,我们就得考虑代码复用了

define makemodule
    cd $@ && \
    $(MAKE) all \
    DEBUG:=$(DEBUG) \
    DIR_BUILD:=$(addprefix $(DIR_PROJECT)/, $(DIR_BUILD)) \
    DIR_COMMON_INC:=$(addprefix $(DIR_PROJECT)/, $(DIR_COMMON_INC)) \
    MOD_CFG:=$(addprefix $(DIR_PROJECT)/, $(MOD_CFG)) \
    MOD_RULE:=$(addprefix $(DIR_PROJECT)/, $(MOD_RULE)) \
    CMD_CFG:=$(addprefix $(DIR_PROJECT)/, $(CMD_CFG)) &&\
    cd ..; 
endef
…………………..
$(MODULES) : $(DIR_BUILD) $(DIR_BUILD)/$(MAKECMDGOALS)
        @echo "Begin to compile $@"
        @set -e; \
        $(call makemodule, $@)

测试ok

把make  all也改成函数调用

compile : $(DIR_BUILD) $(DIR_BUILD_SUB)
        @echo "Begin to compile..."
        @set -e; \
        for dir in $(MODULES); \
        do \
           $(call makemodule, $$dir) \
        done
        @echo "success compile ..."

测试发现:

make all

Begin to compile...

/bin/sh: 4: cd: can't cd to compile

/bin/sh: 4: cd: can't cd to compile

/bin/sh: 4: cd: can't cd to compile

make: *** [compile] Error 2

解决:问题出在函数定义,我们要使用函数调用时的第一个参数

define makemodule
    cd ${1} && \
    $(MAKE) all \
    DEBUG:=$(DEBUG) \
    DIR_BUILD:=$(addprefix $(DIR_PROJECT)/, $(DIR_BUILD)) \
    DIR_COMMON_INC:=$(addprefix $(DIR_PROJECT)/, $(DIR_COMMON_INC)) \
    MOD_CFG:=$(addprefix $(DIR_PROJECT)/, $(MOD_CFG)) \
    MOD_RULE:=$(addprefix $(DIR_PROJECT)/, $(MOD_RULE)) \
    CMD_CFG:=$(addprefix $(DIR_PROJECT)/, $(CMD_CFG)) &&\
    cd ..; 
endef

测试ok

6.思路

  • 将编译模块的命令集作为自定义函数的具体实现
  • 函数参数为模块名,函数调用后编译参数指定的模块
  • 在不同的规则中调用该函数

7.小结

  • 编写模块代码时可通过模块独立编译快速检查语法错误
  • 自动白能量只能在规则的命令中使用,不能再依赖中使用
  • makefile中的自定义函数是代码复用的一种方式
  • 当不同规则中的命令大量复用时,可考虑自定义函数

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值