所以我正在开发一个项目,我有以下简化的结构
./
┗━ 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 相关。
如果存档
libitkvnl_algo.a
依赖于 libv3p_netlib.a
中定义的符号,则(在 Linux 上)用于创建二进制文件的链接行上的库的顺序很重要:libv3p_netlib.a
必须出现在 libitkvnl_algo.a
之后。如果您只使用 glob
,您不一定会获得可用的订单;您可能必须在 srcs
中明确列出库。或者,您可以为每个 cc_library
文件构造一个 .a
并使用 deps
来反映正确的依赖关系图;然后 bazel 会自动给你正确的链接线排序。