【问题标题】:Bazel host (x86 linux) linkopts propogating to target (android)Bazel 主机(x86 linux)linkopts 传播到目标(android)
【发布时间】: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


    【解决方案1】:

    我已经解决了这个问题。这里的问题不是关于使用 protoc/protobuf 的主机链接选择,而是关于无条件使用 -lpthread 的另一个库 (gflags)。添加 protobuf 使用的相同 android 配置和 select 语句解决了这个问题 (PR)。关于使用不存在的-lnotareallibrary 的红鲱鱼是 protoc 的链接器错误,而不是我的目标可执行文件。

    为了便于描述调试过程,我在自动生成的bazel-myreponame/external 目录的BUILD 文件和.bzl 文件中搜索-lpthread。 (一开始只想搜索BUILD文件,漏掉了这个库)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 2021-08-13
      相关资源
      最近更新 更多