我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

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

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

       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_class="lazy" data-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",
    class="lazy" data-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",
    ],  
    class="lazy" data-srcs: [
        "paxparser.go",
    ],  
    pluginFor: ["soong_build"],
}
paxparser_defaults {
    name: "paxparser_defaults",
}
ANDROIDBP_FUN = ["YES"]
cc_binary {
    defaults: ["paxparser_defaults"],
    name: "AndroidBp",
    class="lazy" data-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

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

Android.bp正确姿势添加宏控制编译指南前言随着Android版本的迭代,越来越多的移动终端都用上了香喷喷的Android 9和10系统。相对于原来的Android版本,9和10越来越多的使用Android.bp替换以前的Androi
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录