文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android.bp正确姿势添加宏控制编译指南

2022-06-06 13:33

关注

       Android.bp正确姿势添加宏控制编译指南

前言

  随着Android版本的迭代,越来越多的移动终端都用上了香喷喷的Android 9和10系统。相对于原来的Android版本,9和10越来越多的使用Android.bp替换以前的Android.mk编译脚本。我们知道 Android.mk采用Makefile的语言,所以为了控制条件编译和多版本适配,我们可以在不同产品直接在Android.mk中采用Makefile语言控制编译。虽然我们也可以通过Android的内置工具androidmk将Android.mk转换为Android.bp脚本,但是对于有宏控制的条件编译,androidmk是无能为力的。这是因为Android.bp是类似JSON的纯文本形式.对于Android.mk里面流控制部分,在Android.bp里要借助使用go语言文件去进行控制。好了说了这么多了,我想读者应该知道这个篇章要写什么了,那就是手把手带领大伙手撸Android.bp添加宏控制编译。



一.实战开始

我们知道在Android原来的编译脚本Android.mk中添加宏控制有两种场景,分别是:

无条件控制的宏添加 有条件控制的宏添加,即满足某个条件才添加对应的宏,这个场景比较多

下面我们分别从上述两种场景出发,来说明在Android.bp中如何添加。


1.1 无条件控制的宏添加

这里我会以实际案例来说明,怎么一步步添加无条件控制的宏。

1.1.1 编写源文件main.c
#include
int main()
{
    #ifdef PRINT  //宏控制
    printf("Hello world\n");
    #endif
    #ifdef PAX //宏控制
    printf("PAX\n");
    #endif
    printf("This is AndroidBp Test\n");
    return 0;
}

代码非常简单,就是一个简单的打印。在我们正式在Android.bp中添加宏前,我们先看看Android.mk应该怎么编写。

1.1.2 编写Android.mk编译脚本
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := AndroidBp
LOCAL_SRC_FILES := main.c
ANDROIDBP_FUN=YES
#有条件的添加宏控制
ifeq ($(ANDROIDBP_FUN), "YES") 
    LOCAL_CFLAGS += -DPAX
endif
#无条件宏控制
LOCAL_CFLAGS += -Wno-error=implicit-function-declaration  -DPRINT
LOCAL_SHARED_LIBRARIES :=  libcutils liblog     libutils 
include $(BUILD_EXECUTABLE)

这个也非常简单,就是编译一个可执行文件,并有条件和无条件的添加宏控制。

1.1.3 将Android.mk转换为Android.bp

在前面的博客中,我们知道Android内置的androidmk工具能将Android.mk转换为对应的Android.bp,但是当Android.mk中有宏条件控制时就无能为力了。下面让我们转换一下看看是否如此:


[SPRD] tangkw@pd:~/ssd/A50/ap/idh.code/paxdroid/external/AndroidBp$ androidmk  Android.mk  > Android.bp
[SPRD] tangkw@pd:~/ssd/A50/ap/idh.code/paxdroid/external/AndroidBp$ 

查看转换后生成的Android.bp文件如下,可以看到androidmk的转换失效了,

ANDROIDBP_FUN = ["YES"]
cc_binary {
    name: "AndroidBp",
    srcs: ["main.c"],
    // ANDROIDMK TRANSLATION ERROR: unsupported conditional
    // ifeq ($(ANDROIDBP_FUN), "YES")
    cflags: ["-DPAX"] + [ // ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
    // endif
        "-Wno-error=implicit-function-declaration",
        "-DPRINT",
    ],  
    shared_libs: [
        "libcutils",
        "liblog",
        "libutils",
    ],  
}
1.1.4 Android.bp直接添加宏

通过前面的章节我们可以直接,Android.bp直接添加宏非常简单,只需要在cflags后面添加对应的宏就OK了。

    cflags: ["-DPAX"] + [ // ANDROIDMK TRANSLATION ERROR: endif from unsupported contitional
    // endif
        "-Wno-error=implicit-function-declaration",
        "-DPRINT",
    ],  

1.2 有条件控制的宏添加

根据前面的章节我们知道,在Android.bp中需要有条件的添加宏是不能直接做到的,必须借助go脚本实现动态控制编译项,那么让我们看看怎么动态添加如下的宏:

#有条件的添加宏控制
ifeq ($(ANDROIDBP_FUN), "YES") 
    LOCAL_CFLAGS += -DPAX
endif
1.2.1 添加go脚本

我们在Android.bp同级目录添加go脚本文件paxparser.go,其内容如下:

package  paxparser
import (
        "android/soong/android"
        "android/soong/cc"
)
func init() {
    // resister a module "paxdroid_defaults"
    android.RegisterModuleType("paxparser_defaults", paxdroidDefaultsFactory)
}
func paxdroidDefaultsFactory() (android.Module) {
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, paxdroidDefaults)
    return module
}
func paxdroidDefaults(ctx android.LoadHookContext) {
   type props struct {
        Cflags []string
    }   
    p := &props{}
    p.Cflags = globalDefaults(ctx)
    ctx.AppendProperties(p) 
}
func globalDefaults(ctx android.BaseContext) ([]string) {
    var cppflags []string
    if ctx.AConfig().Getenv("ANDROIDBP_FUN") == "YES" {
          cppflags = append(cppflags,"-DPAX")
    }   
    return cppflags
}
1.2.2 Android.bp使用go脚本

在Android.bp开头位置引入go脚本文件paxparser.go,如下:

//引入go脚本
bootstrap_go_package {
    name: "soong-paxparser",
    pkgPath: "android/soong/paxparser",
    deps: [
    "blueprint",
    "blueprint-pathtools",
    "soong",
    "soong-android",
    "soong-cc",
    "soong-genrule",
    ],  
    srcs: [
        "paxparser.go",
    ],  
    pluginFor: ["soong_build"],
}
paxparser_defaults {
    name: "paxparser_defaults",
}
ANDROIDBP_FUN = ["YES"]
cc_binary {
    defaults: ["paxparser_defaults"],
    name: "AndroidBp",
    srcs: ["main.c"],
    cflags: ["-Wno-error=implicit-function-declaration"],
    shared_libs: [
        "libcutils",
        "liblog",
        "libutils",
    ],
}

以上语句可以保证运行Android.bp时,先编译对应的paxparser.go运行go脚本时,会首先运行init函数,将 paxdroidDefaultsFactory函数注册到module中,之后调用paxdroidDefaultsFactory函数时,会将回调函数 paxdroidDefaults注册进去之后调用 privateParserDefaults 时,我们可以从 ctx.AConfig() 中获取好多属性
(参考 build/soong/android/config.go 中对 build/soong/android/module.go中的 androidBaseContext interface的各种函数实现),其中有一项是获取宏值的,之后回调paxdroidDefaults添加宏信息。

1.2.3 演示运行

在正式进行编译之前,让我们对编译环境设置环境变量,我这里使用的是ubuntu编译,所以这个不用多说怎么配置环境变量了,如下:


[SPRD] tangkw@pd:~/ssd/A50/ap/idh.code$ export  ANDROIDBP_FUN=YES
[SPRD] tangkw@pd:~/ssd/A50/ap/idh.code$ echo $ANDROIDBP_FUN
YES
[SPRD] tangkw@pd:~/ssd/A50/ap/idh.code$ 

执行可执行文件,查看输出结果,完美。

1|A77:/system/bin # ./AndroidBp
PAX
This is AndroidBp Test
A77:/system/bin #


写在最后

Android.bp正确姿势添加宏控制编译指南中介绍的两种添加宏的场景就到这里了,我想通过这个文档大伙一定能构建自己的Android.bp脚本了。好了最后如果文章对你有帮助麻烦点个赞,如果觉得很low也可以拍个砖一起探讨。


作者:进阶的凯子


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯