在MTK平台下工作,很多东西都只是需要配置一下就可以了,因为MTK的东西太完善了,各种工具,各种配置文件都有,所以很多时候,我们需要了解在这些工具的背后,到底修改的是什么,以及他是如何实现的。
每个在MTK平台下工作的人,都应该知道有个针对项目的配置文件,叫做ProjectConfig.mk,目录是mediatek/config/xxx/ProjectConfig.mk,其中的xxx表示你的项目名称,在这个文件中,你可以配置很多东西,各个外围ic所使用的型号以及参数等,例如lcd的分辨率,tp的型号,前后摄像头的型号,这个很容易,但是这些配置是如何生效的,同时在配置时,有三个类型,AUTO_ADD_GLOBAL_DEFINE_BY_NAME,AUTO_ADD_GLOBAL_DEFINE_BY_NAME_VALUE和AUTO_ADD_GLOBAL_DEFINE_BY_VALUE,他们之间有什么区别。
根据现象可以明显知道,这个配置文件最后会生成各种宏定义,甚至你可以直接在c文件中去判断这个宏值是否存在,我在网上百度了一下,到底是什么文件去解析这个mk的配置文件,结果发现是mediatek/build/tools/codegen.pl下的这个perl脚本的功劳,到这个脚本中,可以明显的看到三条解析。
my $flags = "";
foreach ($ENV{AUTO_ADD_GLOBAL_DEFINE_BY_NAME})
{
my @defArray = split(/\s+/);
foreach my $def (@defArray)
{
$flags .= "-D$def " if ($ENV{$def} ne "" and $ENV{$def} ne "no");
}
}
foreach ($ENV{AUTO_ADD_GLOBAL_DEFINE_BY_VALUE})
{
my @defArray = split(/\s+/);
foreach my $def (@defArray)
{
my @valueArray = split(/\s+/,$ENV{$def});
foreach my $value (@valueArray)
{
$flags .= "-D$value " if ($value ne "" and $value ne "no");
}
}
}
foreach ($ENV{AUTO_ADD_GLOBAL_DEFINE_BY_NAME_VALUE})
{
my @defArray = split(/\s+/);
foreach my $def (@defArray)
{
$flags .= "-D$def=\"$ENV{$def}\" " if ($ENV{$def} ne "" and $ENV{$def} ne "no");
}
}
我除了能够看得懂一点shell脚本,perl确实没怎么看过,不过脚本相差都不大,所以我硬着头皮看了下,不会可以谷歌嘛。
首先可以确定的是,这三段代码分别对应这三个变量的解析,初步一看,解析的代码比较相似,有少量区别。
先分析第一段
my $flags = "";
foreach ($ENV{AUTO_ADD_GLOBAL_DEFINE_BY_NAME})
{
my @defArray = split(/\s+/);
foreach my $def (@defArray)
{
$flags .= "-D$def " if ($ENV{$def} ne "" and $ENV{$def} ne "no");
}
}
首先定义了一个flags的变量为空,然后使用foreach函数,$ENV{AUTO_ADD_GLOBAL_DEFINE_BY_NAME},这里的ENV表示环境变量,也就是取得AUTO_ADD_GLOBAL_DEFINE_BY_NAME所代表的值。foreach,就是每个AUTO_ADD_GLOBAL_DEFINE_BY_NAME开头的都要取,后面的
my @defArray = split(/\s+/);
使用了一个正则表达式来定义了一个数组,让defArray等于AUTO_ADD_GLOBAL_DEFINE_BY_NAME的每一个赋值,关于split(/\s+/)这个表达式的理解
/\s+/这是正则表达式。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
+匹配前面的子表达式一次或多次。
split( )分割字符串函数;
代码接下来又是一个foreach函数,让def等于defArray数组中的每个取值
$flags .= "-D$def " if ($ENV{$def} ne "" and $ENV{$def} ne "no");
这句代码我还不是特别理解,但是猜测他的意思是,用$ENV{$def}去获取配置文件中,def所指的值是否有定义,如果定义为空或no,就不去定义def这个宏。定义宏的时候,是没有初始值的,仅仅类似于:
#define $def
分析了第一段代码,第二段和第三段代码就很容易了,他们的区别在于,第三段代码,定义宏的时候,是有初始值的定义,类似于:
#define $def $ENV{$def}
第二段代码的区别在于会去将$ENV{$def}分段,然后对于每一个分开的$ENV{$def}用来宏定义。
由此就知道这三种配置文件的区别:
AUTO_ADD_GLOBAL_DEFINE_BY_NAME类型: 将它后面的名字,定义为宏
AUTO_ADD_GLOBAL_DEFINE_BY_VALUE类型: 将他后面的名字对应的每个值,都定义为宏
AUTO_ADD_GLOBAL_DEFINE_BY_NAME_VALUE类型:将它后面的名字,定义为宏,同时宏的值是配置文件中的值
备注:后面发现脚本中的-D,有可能是将所有字母大写的意思