首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linux上Qt6的Bazel :如何复制所需的库?

Linux上Qt6的Bazel :如何复制所需的库?
EN

Stack Overflow用户
提问于 2021-05-24 11:24:03
回答 1查看 187关注 0票数 0

目前,我正在做一个通过巴泽尔支持巴泽尔的实验。我的代码可以找到这里

在安装了Bazel和GCC9的Linux上,您可以通过以下方法测试Qt6 Bazel规则:

代码语言:javascript
复制
git clone https://github.com/Vertexwahn/rules_qt6
cd rules_qt6
bazel run --config=gcc9 //:Qt6HelloWorld # run Qt6HelloWorld binary

当试图运行Qt6HelloWorld时,会报告此错误:

代码语言:javascript
复制
/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.solibQt6Network.so.6libQt6Network.so.6.1.0。如果我将这些文件复制到bazel-out/k8-fastbuild/bin ( Qt6HelloWorld二进制文件所在的地方),我仍然会得到这个错误。

对如何纠正这个错误有什么想法吗?关于如何扩展我的规则来复制那些所需的库库,Bazel很高兴,有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-05 09:02:31

这是一个迟来的答复,但我只是偶然看到你的规则,试图做一些非常类似的事情。

这里的主要问题似乎是在您的规则中引用了libQt*.so,它是指向实际库的符号链接。Bazel正确地创建了一个指向runfiles目录(在_solib_k8下)的符号链接,并将从主二进制到_solib_k8下路径的相对路径放置到二进制文件的RUNPATH中。但是,二进制文件中的DT_NEEDED条目引用以.so.6结尾的文件(可能是因为这是库的SONAME )。这些在任何目录中都找不到,给出了上面的错误。以下是一些细节:

代码语言:javascript
复制
$ 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,我们得到如下信息:

代码语言:javascript
复制
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_importcc_library上有什么好处,至少在Linux上是这样。因此,我建议使用cc_library,并简单地使用类似于libQt6Core.so*glob

一旦修复了这个问题,我们将面临下一个问题:至少有一个libicui18n.so.56库需要libQt*.so,但我们还没有提供它。事实证明,这是所有人都需要的,所以我们可以简单地扩大我们的全球范围。结果可能是这样的:

代码语言:javascript
复制
[
    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

代码语言:javascript
复制
filegroup(
    name = "plugin_files",
    srcs = glob(["plugins/**/*"]),
    visibility = ["//visibility:public"],
)

然后在cc_binary中把这个写成data

代码语言:javascript
复制
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回购。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67671236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档