07 Android系统之Android.bp条件编译

举报
王建峰 发表于 2021/11/19 01:19:57 2021/11/19
【摘要】 基本概念 1、 背景 条件编译为我们提供了一种一套代码兼容多个版本的解决方案,提高代码的复用率。 在Android7.0之前使用的是Makefle编译,makefile语法支持条件编译,配置到Andro...

基本概念

1、 背景
条件编译为我们提供了一种一套代码兼容多个版本的解决方案,提高代码的复用率。
在Android7.0之前使用的是Makefle编译,makefile语法支持条件编译,配置到Android.mk文件。
在那以后,开始使用Ninja编译框架,只需要我们配置Android.bp文件,但是bp文件就是一个配置文件,不支持条件编译。
但条件编译又是强需求,所以 google 还是提供了一种条件编译的方法,下面我们就来学习一下。

2、 目的
把 platform sdk version 传给一个 Android.bp 模块的 cpp 代码。

3、 文件组织结构

hinzer@ubuntu:android-10$ tree ./device/mi/pure/hello
./device/mi/pure/hello  # 我们要编译的hello模块
├── Android.bp      # 
├── hello.cpp 		 # 
└── hello.go 		# 

0 directories, 3 files

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

关键步骤

1、 模块编译规则(Android.bp)

// add start
bootstrap_go_package {
    name: "soong-hello",
    pkgPath: "android/soong/hello",
    deps: [
        "soong-android",
        "soong-cc",
    ],
    srcs: [
          "hello.go",
    ],
    pluginFor: ["soong_build"],
}

cc_hello_binary {
    name: "hello_defaults",
}
// add end



cc_binary {
    name: "hello",

    // add start
    defaults: ["hello_defaults"],
    // add end

    srcs: ["hello.cpp"],
    vendor: true,
    shared_libs: [
    ],
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

查看Android.bp中已知的模块类型,其中

  • 类型为bootstrap_go_package的模块名soong-hello,指定了源文件hello.go
  • 类型cc_hello_binary是在hello.go里面进行定义,这里相当于编译条件。
  • 类型cc_binary的模块名hello,通过hello_defaults模块合入配置,并编译源文件hello.cpp成二进制文件。

2、 添加hook机制(hello.go)

package hello

import (
        "android/soong/android"
        "android/soong/cc"
        "fmt"
)

func init() {
    android.RegisterModuleType("cc_hello_binary", helloDefaultsFactory)
}

func helloDefaultsFactory() (android.Module) {
    module := cc.DefaultsFactory()
    android.AddLoadHook(module, helloHook)
    return module
}

func helloHook(ctx android.LoadHookContext) {
    //AConfig() function is at build/soong/android/config.go
    fmt.Println("PlatformSdkVersion = ", ctx.AConfig().PlatformSdkVersion())
    fmt.Println("DeviceName = ", ctx.AConfig().DeviceName())

    type props struct {
        Cflags []string
    }
    p := &props{}
    p.Cflags = append(p.Cflags, "-DPLATFORM_SDK_VERSION=" + ctx.AConfig().PlatformSdkVersion())
    ctx.AppendProperties(p)
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

hello.go文件中配置hook机制,首先定义模块类型cc_hello_binary,然后是hook处理函数helloHook。如果这个cc_hello_binary被定义,表示编译条件成立,触发hook处理函数

  • init()里面注册了一个新的模块类型 cc_hello_binary
  • 对应的函数是helloDefaultsFactory(),需要注意的是其中cc.DefaultsFactory要根据模块类型的不同而不同,参考build/soong/cc/xxx.go中的定义
  • 最后我们希望的条件编译内容可以在hook中定义,通过ctx来获取和添加配置信息,可添加的配置类型参考类型props的定义

3、 使用传入的配置(hello.cpp)

#include <cstdio>

int main() {
    printf("PLATFORM_SDK_VERSION = %d\n", PLATFORM_SDK_VERSION);
    return 0;
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、 将模块添加到Build系统(product.mk)
将模块添加到product.mk文件中的PRODUCT_PACKAGES变量(模块会随着编译打包到android系统中)。

编译验证

hinzer@ubuntu:android-10$ mm hello
...
hinzer@ubuntu:android-10$ emulator -wipe-data
...
hinzer@ubuntu:android-10$ adb shell
adb server version (41) doesn't match this client (39); killing...
* daemon started successfully
pure:/ # hello 					# 模块加载
PLATFORM_SDK_VERSION = 29
pure:/ # ^C
130|pure:/ # exit

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

思考总结

Android.bp只是一个json格式的配置文件,不支持条件语句,不支持控制流程语句。所有复杂问题都由用Go编写的编译逻辑处理。
对于bp文件,了解json格式,其他的靠以后慢慢积累;对于go语言,也不用单独学习,以后多写几个demo,总结套路就好。

参考资料

文章来源: blog.csdn.net,作者:hinzer,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/feit2417/article/details/105376894

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。