android 二进制文件中 .so 文件的名称冲突
name conflicts of .so file in android binary
我正在将 cc_library
链接到 android_binary
并遇到命名问题。谁能告诉我怎么解决?
cc_library
:
cc_library(
name = "native_library",
srcs = glob(["libs/**/*.so"])
)
libs目录内容:
libs
├── armeabi
│ ├── libSound.so
│ ├── libSec.so
│ ├── libWatch.so
│ └── libTec.so
├── armeabi-v7a
│ ├── libSound.so
│ ├── libSec.so
│ └── libWatch.so
├── x86
│ ├── libSound.so
│ ├── libSec.so
│ ├── libWatch.so
│ └── libTec.so
|—— other jars
并且错误信息是这样的:
ERROR: /the/path/to/BUILD:10:1: in android_binary rule //:debug_apk: Each library in the transitive closure must have a unique basename to avoid name collisions when packaged into an apk, but two libraries have the basename 'libSound.so': libs/armeabi/libSound.so and libs/armeabi-v7a/libSound.so.
...
我可能是错的,但这是 apk 布局的限制,所以恐怕你不能在胖 apk 中包含那个命名的库。将库重命名为 libSound-armeabi.so 等是否适合您?
另一种方法利用了 android_binary 的 --fat_apk_cpu 标志并且不需要重命名您的库:
android_binary 将为 --fat_apk_cpu 指定的每个架构构建每个 cc_library 一次。 --fat_apk_cpu 的默认值只是 armeabi-v7a。这被称为 "Android split transition"。当它构建每个 cc_library 时,cc_library 会从 --fat_apk_cpu 中的列表中传递一个 --cpu 标志。我们可以定义读取这些标志的 config_setting 规则,并在 cc_library 中使用 select 语句,以便您的 cc_library 包含不同的 .so 文件,具体取决于它所使用的架构专为
例如:
# BUILD
CPUS = ["armeabi", "armeabi-v7a", "x86"]
[config_setting(name = cpu, values = {"cpu": cpu}) for cpu in CPUS]
cc_library(
name = "native_library",
srcs = select(
{":%s" % cpu : glob(["libs/%s/*.so" % cpu]) for cpu in CPUS}
),
)
android_binary(
name = "app",
srcs = glob(["*.java"]),
manifest = "AndroidManifest.xml",
deps = [":native_library"],
)
然后在命令行上,您可以指定要在最终 APK 中显示的架构。
$ bazel build --fat_apk_cpu=armeabi,armeabi-v7a,x86 //:app
$ zipinfo -1 bazel-bin/app.apk | grep \.so$
lib/x86/libWatch.so
lib/x86/libSound.so
lib/x86/libSec.so
lib/x86/libTec.so
lib/armeabi-v7a/libWatch.so
lib/armeabi-v7a/libSound.so
lib/armeabi-v7a/libSec.so
lib/armeabi-v7a/libTec.so
lib/armeabi/libWatch.so
lib/armeabi/libSound.so
lib/armeabi/libSec.so
lib/armeabi/libTec.so
$ bazel build --fat_apk_cpu=x86 //:app
$ zipinfo -1 bazel-bin/app.apk | grep \.so$
lib/x86/libWatch.so
lib/x86/libSound.so
lib/x86/libSec.so
lib/x86/libTec.so
仅指定一种架构来构建可以加快您的开发构建。例如,如果您在开发时使用 x86 模拟器,则不需要 armeabi 和 armeabi-v7a .so 文件。
我正在将 cc_library
链接到 android_binary
并遇到命名问题。谁能告诉我怎么解决?
cc_library
:
cc_library(
name = "native_library",
srcs = glob(["libs/**/*.so"])
)
libs目录内容:
libs
├── armeabi
│ ├── libSound.so
│ ├── libSec.so
│ ├── libWatch.so
│ └── libTec.so
├── armeabi-v7a
│ ├── libSound.so
│ ├── libSec.so
│ └── libWatch.so
├── x86
│ ├── libSound.so
│ ├── libSec.so
│ ├── libWatch.so
│ └── libTec.so
|—— other jars
并且错误信息是这样的:
ERROR: /the/path/to/BUILD:10:1: in android_binary rule //:debug_apk: Each library in the transitive closure must have a unique basename to avoid name collisions when packaged into an apk, but two libraries have the basename 'libSound.so': libs/armeabi/libSound.so and libs/armeabi-v7a/libSound.so.
...
我可能是错的,但这是 apk 布局的限制,所以恐怕你不能在胖 apk 中包含那个命名的库。将库重命名为 libSound-armeabi.so 等是否适合您?
另一种方法利用了 android_binary 的 --fat_apk_cpu 标志并且不需要重命名您的库:
android_binary 将为 --fat_apk_cpu 指定的每个架构构建每个 cc_library 一次。 --fat_apk_cpu 的默认值只是 armeabi-v7a。这被称为 "Android split transition"。当它构建每个 cc_library 时,cc_library 会从 --fat_apk_cpu 中的列表中传递一个 --cpu 标志。我们可以定义读取这些标志的 config_setting 规则,并在 cc_library 中使用 select 语句,以便您的 cc_library 包含不同的 .so 文件,具体取决于它所使用的架构专为
例如:
# BUILD
CPUS = ["armeabi", "armeabi-v7a", "x86"]
[config_setting(name = cpu, values = {"cpu": cpu}) for cpu in CPUS]
cc_library(
name = "native_library",
srcs = select(
{":%s" % cpu : glob(["libs/%s/*.so" % cpu]) for cpu in CPUS}
),
)
android_binary(
name = "app",
srcs = glob(["*.java"]),
manifest = "AndroidManifest.xml",
deps = [":native_library"],
)
然后在命令行上,您可以指定要在最终 APK 中显示的架构。
$ bazel build --fat_apk_cpu=armeabi,armeabi-v7a,x86 //:app
$ zipinfo -1 bazel-bin/app.apk | grep \.so$
lib/x86/libWatch.so
lib/x86/libSound.so
lib/x86/libSec.so
lib/x86/libTec.so
lib/armeabi-v7a/libWatch.so
lib/armeabi-v7a/libSound.so
lib/armeabi-v7a/libSec.so
lib/armeabi-v7a/libTec.so
lib/armeabi/libWatch.so
lib/armeabi/libSound.so
lib/armeabi/libSec.so
lib/armeabi/libTec.so
$ bazel build --fat_apk_cpu=x86 //:app
$ zipinfo -1 bazel-bin/app.apk | grep \.so$
lib/x86/libWatch.so
lib/x86/libSound.so
lib/x86/libSec.so
lib/x86/libTec.so
仅指定一种架构来构建可以加快您的开发构建。例如,如果您在开发时使用 x86 模拟器,则不需要 armeabi 和 armeabi-v7a .so 文件。