解决openwrt package目录下多个文件夹重名编译警告(call subdir 函数)
2017-01-03 14:45
597 查看
1 开发环境
1、软件环境:ubuntu14.042. openwrt版本:openwrt 官方15.05版本SDK开发包(CHAOS CALMER 15.05版本)
2 功能说明
在openwrt的package中,如果出现文件夹重名。例如,出现“package/dir1/a” 和“package/dir2/a” 两个目录结构,在a和a两个目录中分别都含有各自的makefiel和源代码。
如此,则必然出现大量的编译警告:
package/Makefile:196: warning: ignoring old commands for target... package/Makefile:196: warning: overriding commands for target...
这个问题是由于openwrt本身的索引规则有问题导致的。
3 问题分析
3.1 增加打印调试信息
既然问题出现在“package/Makefile:196”,打开Makefile,可以看到,问题出现的代码为:$(eval $(call subdir,$(curdir)))
问题来自于调用 subdir 函数,采用warning对该函数进行调试,修改之后,代码如下。
$(warning $(call subdir,$(curdir))) $(eval $(call subdir,$(curdir)))
3.2 调试信息
增加完打印信息之后,可以看到,信息如下:package/dir1/a/compile: @+ $(SUBMAKE) -C package/dir1/a compile BUILD_VARIANT="" # aliases package/a/compile: package/dir1/a/compilekage/dir2/a/compile: @+ $(SUBMAKE) -C package/dir2/a compile BUILD_VARIANT="" # aliases package/a/compile: package/dir2/a/compile
从调试信息可以看到,问题在与package/a/compile 这个编译规则被定义了两次。
# aliases package/a/compile: package/dir1/a/compile # aliases package/a/compile: package/dir2/a/compile
所以,出现了编译警告,提示“package/a/compile” 的编译规则被覆盖了,重复定义。
3.3 问题分析
通过调试发现,问题的原因在于openwrt的subdir函数有问题,创建编译规则的时候,总是以目录下最后一个文件夹的名称为标准。查看subdir函数代码“include/subdir.mk”
# Parameters: <subdir> 47 define subdir 48 $(call warn,$(1),d,D $(1)) 49 $(foreach bd,$($(1)/builddirs), 50 $(call warn,$(1),d,BD $(1)/$(bd)) 51 $(foreach target,$(SUBTARGETS), 52 $(foreach btype,$(buildtypes-$(bd)), 53 $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(btype)/$(target)) $(call $(1)//$(btyp 54 $(call log_make,$(1)/$(bd),$(target),$(btype),$(filter-out __default,$(variant))) \ 55 $(if $(findstring $(bd),$($(1)/builddirs-ignore-$(btype)-$(target))), || $(call ERROR,$(1), ERROR: $(1)/$(bd) [$(btype)] fai 56 $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(btype)/$(target): $(1)/$(bd)/$(btype)/$( 57 ) 58 $(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(target)) $(call $(1)//$(target),$(1)/$(bd)))) 59 $(foreach variant,$(if $(BUILD_VARIANT),$(BUILD_VARIANT),$(if $(strip $($(1)/$(bd)/variants)),$($(1)/$(bd)/variants),$(if $($(1)/$ 60 $(if $(BUILD_LOG),@mkdir -p $(BUILD_LOG_DIR)/$(1)/$(bd)/$(filter-out __default,$(variant))) 61 $(call log_make,$(1)/$(bd),$(target),,$(filter-out __default,$(variant))) \ 62 $(if $(findstring $(bd),$($(1)/builddirs-ignore-$(target))), || $(call ERROR,$(1), ERROR: $(1)/$(bd) failed to build$(if 63 ) 64 $(if $(PREREQ_ONLY)$(DUMP_TARGET_DB),, 65 # aliases 66 $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(target): $(1)/$(bd)/$(target))) 67 ) 68 ) 69 ) 70 $(foreach target,$(SUBTARGETS),$(call subtarget,$(1),$(target))) 71 endef
其中,问题出现在第66行的“diralias(别名)”函数,该函数的作用为找到最后一个文件夹,取出该文件夹名称。
29 lastdir=$(word $(words $(subst /, ,$(1))),$(subst /, ,$(1))) 30 diralias=$(if $(findstring $(1),$(call lastdir,$(1))),,$(call lastdir,$(1)))
3.4 解决方法
既然问题在于diralias函数总是以最后一个文件夹名称作为返回值,所以有同名文件夹出现警告。那么可以将编译规则修改,让最后的索引方法,采用路径+文件夹名称。这样就不会出现最后的编译规则定义出现重复。我们最终要实现的目标,实现前:
# aliases package/a/compile: package/dir1/a/compile # aliases package/a/compile: package/dir2/a/compile
实现后
# aliases package/dir1@a/compile: package/dir1/a/compile # aliases package/dir2@a/compile: package/dir2/a/compile
解决方法:
(1)在“include/subdir.mk”文件中,增加一行代码,添加重命名函数:
31 dirRename=$(subst /,@,$(1))
(2)修改openwrt之前定义编译名称的代码
# aliases $(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call dirRename,$(bd))/$(target): $(1)/$(bd)/$(target)))
将之前的
$(call diralias,$(bd))/$(target)...
修改为
$(call dirRename,$(bd))/$(target)...
如此,最终编译的时候,创建的编译规则名称如下,问题解决。
# aliases package/dir1@a/compile: package/dir1/a/compile # aliases package/dir2@a/compile: package/dir2/a/compile
相关文章推荐
- AS3 中的package(包)应用实例代码
- Orcle的package中访问其它Schema的表报错ORA-00942解决方法
- Visual Studio 未能加载各种Package包的解决方案
- 完美解决phpdoc导出文档中@package的warning及Error的错误
- Lua中的模块(module)和包(package)详解
- Android package属性、package name和Application ID三者的联系及区别
- Java基础教程之包(package)
- java入门概念个人理解之package与import浅析
- Python开发常用的一些开源Package分享
- Python上传package到Pypi(代码简单)
- 详解Java编程中包package的内容与包对象的规范
- 【编程基础】Java 中的Package和Import
- OpenWrt 15.05 下安装Samba
- Oracle package模板
- 完美解决phpdoc导出文档中@package的warning及Error的错误
- Python中的module,library,package之间的区别
- SVN错误中文对照