尝试使用 bazel 创建依赖于 ITK 库的 C++ 二进制文件时出现链接错误(未定义的引用)

问题描述 投票:0回答:1

所以我正在开发一个项目,我有以下简化的结构

./
┗━ utils
  ┗━ BUILD
┗━ tool1
  ┗━ BUILD
┗━ itk.BUILD
┗━ WORKSPACE

本质上我正在尝试构建一个二进制文件

tool1
,它依赖于一个库
utils
,而库又依赖于
itk

这里是

utils/BUILD
文件的内容(简化):

cc_library(
    name = "utils",
    srcs = glob(
        [
            "utils/*.cpp",
            "include/**",
        ],
    ),
    hdrs = glob([
        "include/*.h",
    ]),
    copts = [
        "-DITK_USE_SYSTEM_ZLIB",
    ],
    includes = ["./include"]
    linkopts = ["-ldl", "-lz", "-lm", "-lgomp", "-lpthread", "-lcrypto", "-lrt"],
    visibility = ["//visibility:public"],
    deps = [
        "@itk//:itk_libs",
    ],
)

tool1/BUILD

cc_binary(
    name = "tool1",
    srcs = ["tool1.cpp"],
    deps = [
        "//:utils",
    ],
)

ITK 已在

third_party/itk
中预编译,它作为本地存储库包含在
WORKSPACE
文件中:

new_local_repository(
    name = "itk",
    path = "third_party/itk",
    build_file = "itk.BUILD",
)

itk.BUILD
只是创建了一个集体库:

cc_library(
    name = "itk_libs",
    srcs = glob(["lib/**/*.a"]),
    hdrs = glob([
        "include/ITK-4.13/**/*.h",
        "include/ITK-4.13/*.h",
        "include/ITK-4.13/**/*.hxx",
        "include/ITK-4.13/*.hxx",
        "include/ITK-4.13/**/*.txx",
        "include/ITK-4.13/*.txx",
    ]),
    strip_include_prefix = "include/ITK-4.13",
    visibility = ["//visibility:public"],
)

使用 bazel 构建实用程序时

bazel build //:utils
它成功了,但是,当运行
bazel build //tool1
时,我收到一堆链接错误,如下所示:

external/itk/lib/libitkvnl_algo-4.13.a(vnl_cholesky.cxx.o): In function `vnl_cholesky::vnl_cholesky(vnl_matrix<double> const&, vnl_cholesky::Operation)':
vnl_cholesky.cxx:(.text+0x99): undefined reference to `v3p_netlib_dpofa_'

我已经无计可施了,几个星期以来我一直在为此苦苦挣扎。

我不明白的是,

//:utils
编译成功,链接错误仅在构建
//tool1
时出现。

我尝试更改命令行中库的顺序并手动运行它,结果相同。 我尝试将itk直接添加为tool1的依赖,即将

@itk//:itk_libs
添加到
deps
中的
tool1/BUILD
,结果相同

我一定错过了一些东西,如果有人能指出我正确的方向,我将不胜感激。我几乎可以肯定问题出在我不知道的 ITK 上,而不一定是 bazel 上。

编辑: 我从其他依赖项中收到了一堆其他错误,这些错误现已解决,奇怪的是,剩下的唯一错误都与 libitkvnl_algo-4.13.a 相关。

c++ bazel itk bazel-rules bazel-cpp
1个回答
0
投票

如果存档

libitkvnl_algo.a
依赖于
libv3p_netlib.a
中定义的符号,则(在 Linux 上)用于创建二进制文件的链接行上的库的顺序很重要:
libv3p_netlib.a
必须出现在
libitkvnl_algo.a
之后。如果您只使用
glob
,您不一定会获得可用的订单;您可能必须在
srcs
中明确列出库。或者,您可以为每个
cc_library
文件构造一个
.a
并使用
deps
来反映正确的依赖关系图;然后 bazel 会自动给你正确的链接线排序。

© www.soinside.com 2019 - 2024. All rights reserved.