Makefile的一些问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、关闭回显$(hide)与@

Makefile的规则:

target... : prerequisites ...
	<tab> command

target: 编译目标
prerequisites: 目标的依赖
command: 使用makefile shell语句混合编写的命令,最终的command命令只包含shell语句,makefile语句在依赖构建时就被解析。例如:
  1 var := a b c
  2 all:
  3         $(foreach m, $(var), \
  4                 if [ 1 ]; then \
  5                         echo "i am $(m)"; \
  6                 fi; \
  7         )

实际上最终的命令:
if [ 1 ]; then echo "i am a"; fi;   if [ 1 ]; then echo "i am b"; fi;   if [ 1 ]; then echo "i am c"; fi;

回显:在linux下使用make进行编译时。先打印command,随后执行command。
对于上述的Makefile执行make命令,结果如下:

if [ 1 ]; then echo "i am a"; fi;   if [ 1 ]; then echo "i am b"; fi;   if [ 1 ]; then echo "i am c"; fi;
i am a
i am b
i am c

这种先打印command命令再执行的方式称为回显,如果只想要显示command执行结果,需要关闭回显。

在Android mk文件中经常会看到$(hide) @两种方式:

#build/make/target/product/gsi/Android.mk

64 include $(CLEAR_VARS)
65 LOCAL_MODULE := update-vndk-list.sh
66 LOCAL_LICENSE_KINDS := legacy_restricted
67 LOCAL_LICENSE_CONDITIONS := restricted
68 LOCAL_MODULE_CLASS := EXECUTABLES
69 LOCAL_MODULE_STEM := $(LOCAL_MODULE)
70 LOCAL_IS_HOST_MODULE := true
71 include $(BUILD_SYSTEM)/base_rules.mk
72 $(LOCAL_BUILT_MODULE): PRIVATE_INTERNAL_VNDK_LIB_LIST := $(INTERNAL_VNDK_LIB_LIST)
73 $(LOCAL_BUILT_MODULE): PRIVATE_LATEST_VNDK_LIB_LIST := $(LATEST_VNDK_LIB_LIST)
74 $(LOCAL_BUILT_MODULE):
75 	@echo "Generate: $@"
76 	@mkdir -p $(dir $@)
77 	@rm -f $@
78 	$(hide) echo "#!/bin/bash" > $@
79 ifeq (REL,$(PLATFORM_VERSION_CODENAME))
80 	$(hide) echo "echo Updating VNDK library list is NOT allowed in API locked branches." >> $@; \
81 	        echo "exit 1" >> $@
82 else
83 	$(hide) echo "if [ -z \"\$${ANDROID_BUILD_TOP}\" ]; then" >> $@; \
84 	        echo "  echo Run lunch or choosecombo first" >> $@; \
85 	        echo "  exit 1" >> $@; \
86 	        echo "fi" >> $@; \
87 	        echo "cd \$${ANDROID_BUILD_TOP}" >> $@; \
88 	        echo "cp $(PRIVATE_INTERNAL_VNDK_LIB_LIST) $(PRIVATE_LATEST_VNDK_LIB_LIST)" >> $@; \
89 	        echo "echo $(PRIVATE_LATEST_VNDK_LIB_LIST) updated." >> $@
90 endif
91 	@chmod a+x $@
build/make/core/config.mk中定义:
hide := @

所以,在Android编译中,$ (hide)就等于@,但在Android 推荐使用$(hide)

下面来看一下@的使用方法和效果:

  1 var := a b c
  2 all:
  3         @$(foreach m, $(var), \
  4                 if [ 1 ]; then \
  5                         echo "i am $(m)"; \
  6                 fi; \
  7         )

执行后:

i am a
i am b
i am c

通过执行结果,关掉了回显。

需要注意的是:
只需要在每一句command的开头使用@,只要用 \ 则可拼接为一句command,下面这种写法是错误:

  1 var := a b c
  2 all:
  3         $(foreach m, $(var), \
  4                 @if [ 1 ]; then \
  5                         @echo "i am $(m)"; \
  6                 @fi; \
  7         )

二、退出命令

在Makefile的command命令中,如果想中止编译,可使用exit 1退出编译
如:

65 $(LIB): $(notdir $(LIBOBJS))
66 	if [ -z "$(strip $^)" ] ; then \
67 		echo "Cowardly refusing to create empty archive"; \
68 		exit 1; \
69 	fi
70 	$(if $(AR),$(AR),ar) -rc "$@" $^
71 	$(if $(RANLIB),$(RANLIB),ranlib) "$@"

三、shell中的分号

command中的shell命令是分不同进程执行,如果要保证顺序,则需要使用 ; \ 拼接为一句命令

分号在shell脚本中是用来隔离代码块的,比如:
if [ -z “$(strip $^)” ] ; then echo “abc”; fi

等价于
if [-z “$(strip $^)”]; then
echo “abc”
fi

但是在Makefile的command拼接时,使用分号对拼接的代码进行分隔。

四、filter使用

$(filter PATTERN…,TEXT) 
在TEXT中过滤出PATTERN,如果存在,则返回,如果不存在则返回空
需要注意的是,makefile中""不可随便用,与python或者其他语言中不同,在其他语言中""一般用来引用字符串,而在makefile中,""也会被认为是普通的字符,例如
$(filter "yes", yes no)
则会返回空,因为不存在"yes"这五个字符。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值