uboot 中没有Kconfig ,条件编译也就只能在makefile 中完成了,但是makefile 的语法是不支持像C语言中的预编译的宏运算
目标是实现不同的芯片编译对应的驱动程序,这些驱动是互斥的。
CONFIG_SOC_1 或者 CONFIG_SOC_2 -> a.c
CONFIG_SOC_3 或者 CONFIG_SOC_4 -> b.c
ifdef CONFIG_SOC_1 || CONFIG_SOC_2
+=a.o
else
+=b.o
endif
因为makefile 不支持以上的语法,只能通过其他方法绕,
最容易的想法是
ifdef CONFIG_SOC_1
+=a.o
endif
ifdef CONFIG_SOC_2
+=a.o
endif
ifdef CONFIG_SOC_3
+=b.o
endif
ifdef CONFIG_SOC_4
+=b.o
endif
简直没法看,也不好维护
最终发现了一个外国友人的方法
https://stackoverflow.com/questions/5584872/complex-conditions-check-in-makefile
ifndef_any_of = $(filter undefined,$(foreach v,$(1),$(origin $(v))))
ifdef_any_of = $(filter-out undefined,$(foreach v,$(1),$(origin $(v))))
then the following conditions:
ifdef VAR1 || VAR2
ifdef VAR1 && VAR2
can be written respectively using call function:
ifneq ($(call ifdef_any_of,VAR1 VAR2),)
ifeq ($(call ifndef_any_of,VAR1 VAR2),)
我的需求实现就变成:
ifeq ($(call ifndef_any_of,CONFIG_SOC_1 CONFIG_SOC_2),)
+=a.o
else
+=b.o
endif
非常的简便。
实现的原理:
核心函数 ifndef_any_of =
(
f
i
l
t
e
r
u
n
d
e
f
i
n
e
d
,
(filter undefined,
(filterundefined,(foreach v,
(
1
)
,
(1),
(1),(origin $(v))))
filter: 过滤功能,filter undefined ,undefined 就是filter的一个参数,后面是另一个参数,功能是将后面参数中的字符过滤掉undefined 后如果还有剩余的就返回1,否0 ,这里的作用是看后面的参数中是否都有undefined .
foreach 循环功能, foreach a,b,c 功能是将b中空格分隔的参数从a 变到b,
$(1) 函数输入的参数
origin $() 是获取整个环境中定义环境变量,如果定义了就返回defined ,如果没定义就undefined,
整体的功能就变成 获取环境变量,循环查找输入参数是否在环境变量中定义,返回的就是一堆的defined undefined 等字符,
整体的功能就是,输入参数经过在环境变量中查找,返回defined 和undefined ,再filer 过滤掉undefined 如果有defined 就返回1,说明你输入的参数是定义过的,也就是需要编译对应的驱动的。