Android开发Android开发经验谈Android开发

[Mediapipe]bazel编译与aar文件生成

2020-04-22  本文已影响0人  CangWang

为何我突然钟情于mediapipe?
因为mediapipe综合了很多新进技术的方向,实时人脸识别,实时物体识别,实时手部识别,每一个的应用都是非常前沿的,并且涉及到opencv检测,机器学习,C++编程,一个能够跨平台 Android ios 桌面,甚至web框架的应用,每一样的学习都是让人神往的。并且拥有这些必要只是技能和储备,将会在未来得以施展。

这次要说一下Mediapipe的打包,上一节提及的,mediapipe打包是使用bazel。
bazel是Google开源的一套编译构建工具,广泛应用于Google内部,包括TensorFlow项目。修改TensorFlow内部源码,需要使用bazel来编译,故有必要了解下bazel。bazel优点很多,主要有

1.构建快。支持增量编译。对依赖关系进行了优化,从而支持并发执行。
2.可构建多种语言。bazel可用来构建Java C++ Android ios等很多语言和框架,并支持mac windows linux等不同平台
3.可伸缩。可处理任意大小的代码库,可处理多个库,也可以处理单个库
4.可扩展。使用bazel扩展语言可支持新语言和新平台。

那么通过基本去读懂bazel对aar的配置来,来对构建一些理解。
如果不知道bazel怎么配置在AS,可以阅读[Mediapipe]Mediapipe的Android配置

根目录workspace文件
要进行构建的文件系统,根目录下必须包含一个文件名为WORKSPACE的文件,即使它内容为空。它指明了构建的根目录。文件系统中包括源文件,头文件,输出目录的符号链接等。WORKSPACE采用类似Python的语法。

//workspace名字
workspace(name = "mediapipe")
//从.bazel加载一些内容,
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

//下载bazel文件,然后解压它
skylib_version = "0.8.0"
http_archive(
    name = "bazel_skylib",
    type = "tar.gz",
    url = "https://github.com/bazelbuild/bazel-skylib/releases/download/{}/bazel-skylib.{}.tar.gz".format (skylib_version, skylib_version),
    sha256 = "2ef429f5d7ce7111263289644d233707dba35e39696377ebab8b0bc701f7818e",
)
//加载maven下载
maven_install(
    artifacts = [
        "androidx.annotation:annotation:aar:1.1.0",
        "androidx.appcompat:appcompat:aar:1.1.0-rc01",
        "androidx.camera:camera-core:aar:1.0.0-alpha06",
        "androidx.camera:camera-camera2:aar:1.0.0-alpha06",
        "androidx.constraintlayout:constraintlayout:aar:1.1.3",
        "androidx.core:core:aar:1.1.0-rc03",
        "androidx.legacy:legacy-support-v4:aar:1.0.0",
        "androidx.recyclerview:recyclerview:aar:1.1.0-beta02",
        "com.google.android.material:material:aar:1.0.0-rc01",
    ],
    repositories = [
        "https://dl.google.com/dl/android/maven2",
        "https://repo1.maven.org/maven2",
    ],
)
//maven服务器
maven_server(
    name = "google_server",
    url = "https://dl.google.com/dl/android/maven2",
)

//单独下载maven jar包
maven_jar(
    name = "androidx_lifecycle",
    artifact = "androidx.lifecycle:lifecycle-common:2.0.0",
    sha1 = "e070ffae07452331bc5684734fce6831d531785c",
    server = "google_server",
)

//配置Android的sdk和ndk
# You may run setup_android.sh to install Android SDK and NDK.
android_ndk_repository(
    name = "androidndk",
)

android_sdk_repository(
    name = "androidsdk",
)

在每一个子工程里面,还需要配置自身的workspace文件。你可以理解和android的build.gradle配置类似。
以facedetectiongpu为例

package(default_visibility = ["//visibility:private"])

//编译并添加mediapipe_jni.so
cc_binary(
    name = "libmediapipe_jni.so",
    linkshared = 1,
    linkstatic = 1,
    //依赖于calculators文件
    deps = [
        "//mediapipe/graphs/face_detection:mobile_calculators",
        "//mediapipe/java/com/google/mediapipe/framework/jni:mediapipe_framework_jni",
    ],
)

//添加mediapipe_jni
cc_library(
    name = "mediapipe_jni_lib",
    srcs = [":libmediapipe_jni.so"],
    alwayslink = 1,
)

//添加mediapipe流程图
# Maps the binary graph to an alias (e.g., the app name) for convenience so that the alias can be
# easily incorporated into the app via, for example,
# MainActivity.BINARY_GRAPH_NAME = "appname.binarypb".
genrule(
    name = "binary_graph",
    srcs = ["//mediapipe/graphs/face_detection:mobile_gpu_binary_graph"],
    outs = ["facedetectiongpu.binarypb"],
    cmd = "cp $< $@",
)

//添加mediapipe_lib library
android_library(
    name = "mediapipe_lib",
    srcs = glob(["*.java"]),
    //assets文件
    assets = [
        ":binary_graph",
        "//mediapipe/models:face_detection_front.tflite",
        "//mediapipe/models:face_detection_front_labelmap.txt",
    ],
    assets_dir = "",
    //指定AndroidManifest
    manifest = "AndroidManifest.xml",
    resource_files = glob(["res/**"]),
    //依赖的第三方库
    deps = [
        ":mediapipe_jni_lib",
        "//mediapipe/java/com/google/mediapipe/components:android_camerax_helper",
        "//mediapipe/java/com/google/mediapipe/components:android_components",
        "//mediapipe/java/com/google/mediapipe/framework:android_framework",
        "//mediapipe/java/com/google/mediapipe/glutil",
        "//third_party:androidx_appcompat",
        "//third_party:androidx_constraint_layout",
        "//third_party:androidx_legacy_support_v4",
        "//third_party:androidx_recyclerview",
        "//third_party:opencv",
        "@androidx_concurrent_futures//jar",
        "@androidx_lifecycle//jar",
        "@com_google_code_findbugs//jar",
        "@com_google_guava_android//jar",
    ],
)

//编译application
android_binary(
    name = "facedetectiongpu",
    manifest = "AndroidManifest.xml",
    //applicationId
    manifest_values = {"applicationId": "com.google.mediapipe.apps.facedetectiongpu"},
    multidex = "native",
    //依赖库
    deps = [
        ":mediapipe_lib",
    ],
)

其实仔细看一下,很容易就可以看懂。
编写完这些之后,还需要配置编译命令,


Bazel Command.png

然后需要配置命令


Bazel Command.png

这里面facedetectiongpu:facedetectiongpu,[文件名:执行的编译命名],mobile-install是安装命令,有run和build等其他命令。编译成功后,可以在下面目录找到安装文件


apk.png

接下来,如何封装一个第三方库供外部使用,这里需要注意的mediapipe已经提供了aar生成的脚本命令mediapipe_aar的命令。
那么我新建一个简单的文件夹以及一个Workspace文件

load("//mediapipe/java/com/google/mediapipe:mediapipe_aar.bzl", "mediapipe_aar")

mediapipe_aar(
    name = "mp_face_detection_aar",
    calculators = ["//mediapipe/graphs/face_detection:mobile_calculators"],
    assets = [
            "//mediapipe/models:face_detection_front.tflite",
            "//mediapipe/models:face_detection_front_labelmap.txt",
        ],
)

我们查看mediapipe_aar文件的定义,自己阅读其实不难发现也是声明一下文件编译的流程,有android开发的经验,基本是能读懂命令的涵盖文件的。
这里原来的命令是不带有assets编译进去的,这里我修改了一下mediapipe_aar将tflite文件加入到aar当中一起打包。


assest.png Opengl Android组件化
上一篇下一篇

猜你喜欢

热点阅读