目前,我正在做一个通过巴泽尔支持巴泽尔的实验。我的代码可以找到这里。
在安装了Bazel和GCC9的Linux上,您可以通过以下方法测试Qt6 Bazel规则:
git clone https://github.com/Vertexwahn/rules_qt6
cd rules_qt6
bazel run --config=gcc9 //:Qt6HelloWorld # run Qt6HelloWorld binary当试图运行Qt6HelloWorld时,会报告此错误:
/home/user/.cache/bazel/_bazel_$USER/196a14423fc09522ef7bd657344d1cd0/execroot/Qt6Testbed/bazel- out/k8-fastbuild/bin/Qt6HelloWorld:
error while loading shared libraries: libQt6Network.so.6: cannot open shared object file: No such file or directory在Qt6.1.0中似乎有libQt6Network.so、libQt6Network.so.6和libQt6Network.so.6.1.0。如果我将这些文件复制到bazel-out/k8-fastbuild/bin ( Qt6HelloWorld二进制文件所在的地方),我仍然会得到这个错误。
对如何纠正这个错误有什么想法吗?关于如何扩展我的规则来复制那些所需的库库,Bazel很高兴,有什么想法吗?
发布于 2022-04-05 09:02:31
这是一个迟来的答复,但我只是偶然看到你的规则,试图做一些非常类似的事情。
这里的主要问题似乎是在您的规则中引用了libQt*.so,它是指向实际库的符号链接。Bazel正确地创建了一个指向runfiles目录(在_solib_k8下)的符号链接,并将从主二进制到_solib_k8下路径的相对路径放置到二进制文件的RUNPATH中。但是,二进制文件中的DT_NEEDED条目引用以.so.6结尾的文件(可能是因为这是库的SONAME )。这些在任何目录中都找不到,给出了上面的错误。以下是一些细节:
$ readelf -d [...]/execroot/Qt6Testbed/bazel-out/k8-fastbuild/bin/Qt6HelloWorld
0x0000000000000001 (NEEDED) Shared library: [libQt6Network.so.6]
0x0000000000000001 (NEEDED) Shared library: [libQt6Qml.so.6]
0x0000000000000001 (NEEDED) Shared library: [libQt6Core.so.6]
0x0000000000000001 (NEEDED) Shared library: [libQt6Gui.so.6]
0x0000000000000001 (NEEDED) Shared library: [libQt6Widgets.so.6]
[...]
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/_solib_k8/_U@qt_U6.1.0_Ulinux_Udesktop_Ugcc_U64_S_S_Cqt_Unetwork_Ulinux_Uimport___Ulib:$ORIGIN/_solib_k8/_U@qt_U6.1.0_Ulinux_Udesktop_Ugcc_U64_S_S_Cqt_Uqml_Ulinux_Uimport___Ulib:$ORIGIN/_solib_k8/_U@qt_U6.1.0_Ulinux_Udesktop_Ugcc_U64_S_S_Cqt_Ucore_Ulinux_Uimport___Ulib:$ORIGIN/_solib_k8/_U@qt_U6.1.0_Ulinux_Udesktop_Ugcc_U64_S_S_Cqt_Ugui_Ulinux_Uimport___Ulib:$ORIGIN/_solib_k8/_U@qt_U6.1.0_Ulinux_Udesktop_Ugcc_U64_S_S_Cqt_Uwidgets_Ulinux_Uimport___Uli]
[...]检查RUNPATH上第一个目录中的第一个RUNPATH,我们得到如下信息:
readelf -d [...]/execroot/Qt6Testbed/bazel-out/k8-fastbuild/bin/_solib_k8/_U@qt_U6.1.0_Ulinux_Udesktop_Ugcc_U64_S_S_Cqt_Unetwork_Ulinux_Uimport___Ulib/libQt6Network.so
Dynamic section at offset 0x206960 contains 36 entries:
Tag Type Name/Value
[...]
0x000000000000000e (SONAME) Library soname: [libQt6Network.so.6]
[...]显而易见的修正是使用libQt*.so.6作为cc_import目标,但是我们必须跳过interface_library参数,因为很明显,必须以.so结尾。但是,我不知道cc_import在cc_library上有什么好处,至少在Linux上是这样。因此,我建议使用cc_library,并简单地使用类似于libQt6Core.so*的glob。
一旦修复了这个问题,我们将面临下一个问题:至少有一个libicui18n.so.56库需要libQt*.so,但我们还没有提供它。事实证明,这是所有人都需要的,所以我们可以简单地扩大我们的全球范围。结果可能是这样的:
[
cc_library(
name = "qt_%s_linux_import" % name,
hdrs = [],
srcs = glob([
"lib/lib%s.so*" % library_name,
"lib/libicu*.so*",
]),
target_compatible_with = ["@platforms//os:linux"],
)
for name, include_folder, library_name, _ in QT_LIBRARIES
]最后一个问题是没有找到Qt平台插件。可以通过通过plugins提供整个data目录并设置QT_QPA_PLATFORM_PLUGIN_PATH来解决这个问题。我们可以将插件放入filegroup中的qt_6.1.0_linux_desktop_gcc_64.BUILD
filegroup(
name = "plugin_files",
srcs = glob(["plugins/**/*"]),
visibility = ["//visibility:public"],
)然后在cc_binary中把这个写成data
cc_binary(
name = "Qt6HelloWorld",
srcs = ["main.cpp"],
deps = [
":qt_core",
":qt_qml",
":qt_widgets",
],
env = select({
"@platforms//os:linux": {
"QT_QPA_PLATFORM_PLUGIN_PATH": "external/qt_6.1.0_linux_desktop_gcc_64/plugins",
},
"@platforms//os:windows": {
# TODO
},
}),
data = select({
"@platforms//os:linux": ["@qt_6.1.0_linux_desktop_gcc_64//:plugin_files"],
"@platforms//os:windows": [],
}),
)因为我已经把所有这些地方现在,我将创建一个公关为您的GitHub回购。
https://stackoverflow.com/questions/67671236
复制相似问题