Reputation: 11
I'm using the bazel functions android_library() and android_binary() to build an APK. My android_library has a dependency to a native lib built with cc_library(). The native lib gets packed into the APK but I would like to pack an additional native lib into the APK.
I have tried to add the additional lib as a dependency to android_library() to no avail. It gets built but does not get packed into the APK.
In the build.gradle
that I used before I started migrating to bazel this was achieved by using the "sourceSets" section:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId = 'com.my.runtime'
minSdkVersion 14
targetSdkVersion 26
versionCode = 1
versionName = '1.0'
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'
}
}
}
splits {
abi {
reset()
enable true
universalApk false // If true, also generate a universal APK
include "arm64-v8a"
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
sourceSets {
main {
// let gradle pack the additional shared library into apk
jniLibs.srcDirs = ['../additional_lib']
}
}
externalNativeBuild {
cmake {
version '3.15.5'
path 'src/main/jni/CMakeLists.txt'
}
}
}
dependencies {
implementation 'com.android.support:appcompat-v7:26.0.0'
}
How could I achieve this by using the bazel functions?
Upvotes: 1
Views: 557
Reputation: 5016
The way to do this is with a cc_import
: https://docs.bazel.build/versions/master/be/c-cpp.html#cc_import
Then have your android_binary
depend on that cc_import
.
If you have a .so
for each architecture you want to support, then you can import them all using cc_import
, select()
, and config_setting
. For example, if you have a directory called libs
with this structure:
$ tree libs
libs
├── arm64-v8a
│ └── libsomething.so
├── armeabi-v7a
│ └── libsomething.so
├── x86
│ └── libsomething.so
└── x86_64
└── libsomething.so
Then you can create a BUILD file in libs
like this:
config_setting(
name = "x86",
values = {
"cpu": "x86",
}
)
config_setting(
name = "x86_64",
values = {
"cpu": "x86_64",
}
)
config_setting(
name = "armeabi-v7a",
values = {
"cpu": "armeabi-v7a",
}
)
config_setting(
name = "arm64-v8a",
values = {
"cpu": "arm64-v8a",
}
)
cc_import(
name = "lib",
shared_library = select({
":x86": "x86/libsomething.so",
":x86_64": "x86_64/libsomething.so",
":armeabi-v7a": "armeabi-v7a/libsomething.so",
":arm64-v8a": "arm64-v8a/libsomething.so",
}),
visibility = ["//visibility:public"],
)
Then have your android_binary
depend on lib
. Then when you build with --fat_apk_cpu
, each .so
will be packaged for its respective architecture, e.g.:
bazel build java/com/app --fat_apk_cpu=x86,x86_64,armeabi-v7a,arm64-v8a
$ unzip -l bazel-bin/java/com/app/app.apk
Archive: bazel-bin/java/com/app/app.apk
Length Date Time Name
--------- ---------- ----- ----
9 2010-01-01 00:00 nativedeps
274288 2010-01-01 00:00 lib/arm64-v8a/libapp.so
18770760 2010-01-01 00:00 lib/arm64-v8a/libsomething.so
189796 2010-01-01 00:00 lib/armeabi-v7a/libapp.so
10076740 2010-01-01 00:00 lib/armeabi-v7a/libsomething.so
239312 2010-01-01 00:00 lib/x86/libapp.so
38612828 2010-01-01 00:00 lib/x86/libsomething.so
247784 2010-01-01 00:00 lib/x86_64/libapp.so
53690632 2010-01-01 00:00 lib/x86_64/libsomething.so
2760 2010-01-01 00:00 classes.dex
1832 2010-01-01 00:00 AndroidManifest.xml
728 2010-01-01 00:00 res/layout/main_layout.xml
768 2010-01-01 00:00 resources.arsc
1374 2010-01-01 00:00 META-INF/CERT.SF
1211 2010-01-01 00:00 META-INF/CERT.RSA
1270 2010-01-01 00:00 META-INF/MANIFEST.MF
--------- -------
122112092 16 files
Upvotes: 2