【发布时间】:2021-03-06 06:11:45
【问题描述】:
我有一个基于 bazel 的 c++ 项目,它使用带有 proto_library 规则的 protos。
我的 .bazelrc 有一个 android 配置,它指定了一个 android 配置(在 example here 之后)
build:android_arm64 --cpu=arm64-v8a
build:android_arm64 --fat_apk_cpu=arm64-v8a
build:android_arm64 --crosstool_top=//external:android/crosstool
build:android_arm64 --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
protobuf BUILD 文件有一个使用相同 crosstool_top 值的 android 配置,它控制是否将 pthread 与 -lpthread 链接(因为 libpthread.so 在 android 上不存在)。所以应该启用android配置。
如果我使用 bazel build :my_project_cc_binary --config=android_arm64 构建,我会在 my_project_binary 的最后链接步骤中收到关于 ld: cannot find -lpthread 的错误。所以看起来用于protoc 主机二进制文件的链接选择的//conditions:default 配置正在添加到android 目标的链接选择中。
据我了解,我的 android cc_binary 应该与 libprotobuf 链接,它是 linkopts。它不应该与 protoc 的 linkopts 链接,即使它包含在依赖图中,因为主机需要构建并运行它来编译 protos。
我通过将 protobuf LINK_OPTS 中的 -lpthread 更改为 //conditions:default 的 -lnotareallibrary 来验证这一点,我收到了一个错误。我可以确认大多数规则都使用了 ndk 工具链二进制文件,因此我相信 crosstool_top 设置正确。
为什么主机规则中的链接选择会显示在我的 cc_binary 目标的链接选择中?需要构建主机工具的 android 目标不支持 cc_binary 吗?我也很好奇 android_binary 是否以某种方式解决了这个问题,但无法看到它是如何定义的。
# com_google_protobuf/BUILD
config_setting(
name = "android",
values = {
"crosstool_top": "//external:android/crosstool",
},
)
...
# Android and MSVC builds do not need to link in a separate pthread library.
LINK_OPTS = select({
":android": [],
":android-libcpp": [],
":android-gnu-libstdcpp": [],
":msvc": [
# Suppress linker warnings about files with no symbols defined.
"-ignore:4221",
],
"//conditions:default": [
"-lpthread",
"-lm",
],
})
...
cc_binary(
name = "protoc",
srcs = ["src/google/protobuf/compiler/main.cc"],
linkopts = LINK_OPTS,
visibility = ["//visibility:public"],
deps = [":protoc_lib"],
)
【问题讨论】:
标签: android protocol-buffers bazel