源码构建的qdoc依赖libclang动态链接,Qt安装包版为何无此依赖?
我在Ubuntu 24.04.2 LTS上源码构建了Qt qttools 6.8.2,此前已在/home/trung/qt6构建qtbase、qtdeclarative,在/home/trung/.apps/llvm构建LLVM。根据Qt文档,qdoc需要Clang,因此用以下命令构建qttools:
cmake .. -DLLVM_INSTALL_DIR=/home/trung/.apps/llvm -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/home/trung/qt6 -G Ninja ninja -j 4 ninja install
之后检查生成的qdoc可执行文件的链接库:
cd /home/trung/qt6/bin ldd ./qdoc
输出如下:
linux-vdso.so.1 (0x00007e48aaab6000) libQt6Qml.so.6 => /home/trung/qt6/bin/./../lib/libQt6Qml.so.6 (0x00007e48aa400000) libQt6Core.so.6 => /home/trung/qt6/bin/./../lib/libQt6Core.so.6 (0x00007e48a9c00000) libclang.so.19.1 => /home/trung/.apps/llvm/lib/libclang.so.19.1 (0x00007e48a1600000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007e48aaa81000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007e48a1200000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007e48aa317000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007e48aaa51000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007e48a0e00000) /lib64/ld-linux-x86-64.so.2 (0x00007e48aaab8000) libQt6Network.so.6 => /home/trung/qt6/bin/./../lib/libQt6Network.so.6 (0x00007e48a0a00000) libicui18n.so.74 => /lib/x86_64-linux-gnu/libicui18n.so.74 (0x00007e48a0600000) libicuuc.so.74 => /lib/x86_64-linux-gnu/libicuuc.so.74 (0x00007e48a0200000) libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007e48a14b7000) libpcre2-16.so.0 => /lib/x86_64-linux-gnu/libpcre2-16.so.0 (0x00007e48aa28b000) libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007e48a1146000) libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007e48aa27d000) libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007e489fc00000) libicudata.so.74 => /lib/x86_64-linux-gnu/libicudata.so.74 (0x00007e489de00000) libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007e48a10ac000) libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007e48a9bdd000)
如输出第4行所示,qdoc链接了clang。
但使用Qt安装器下载的预编译可执行文件,用ldd检查显示:
ldd ./qdoc
输出如下:
linux-vdso.so.1 (0x00007606bf331000) libQt6Qml.so.6 => /home/trung/.apps/qt6/6.8.2/gcc_64/bin/./../lib/libQt6Qml.so.6 (0x00007606bec00000) libQt6Network.so.6 => /home/trung/.apps/qt6/6.8.2/gcc_64/bin/./../lib/libQt6Network.so.6 (0x00007606be800000) libQt6Core.so.6 => /home/trung/.apps/qt6/6.8.2/gcc_64/bin/./../lib/libQt6Core.so.6 (0x00007606be000000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007606bf313000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007606bf30e000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007606bf307000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007606bdc00000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007606beb17000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007606bf2d9000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007606bd800000) /lib64/ld-linux-x86-64.so.2 (0x00007606bf333000) libzstd.so.1 => /lib/x86_64-linux-gnu/libzstd.so.1 (0x00007606bea5d000) libgssapi_krb5.so.2 => /lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007606bf283000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007606bf267000) libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007606bf254000) libicui18n.so.73 => /home/trung/.apps/qt6/6.8.2/gcc_64/bin/./../lib/libicui18n.so.73 (0x00007606bd400000) libicuuc.so.73 => /home/trung/.apps/qt6/6.8.2/gcc_64/bin/./../lib/libicuuc.so.73 (0x00007606bd000000) libicudata.so.73 => /home/trung/.apps/qt6/6.8.2/gcc_64/bin/./../lib/libicudata.so.73 (0x00007606bb000000) libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007606bdeb7000) libgthread-2.0.so.0 => /lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007606bea58000) libkrb5.so.3 => /lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007606be737000) libk5crypto.so.3 => /lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007606bea2a000) libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007606bea24000) libkrb5support.so.0 => /lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007606bea17000) libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007606bdb66000) libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007606be730000)
上述ldd输出中无clang链接,请问原因是什么?预编译版qdoc是否未使用clang?
原因分析
静态链接Clang库:Qt官方预编译版本可能将Clang相关库静态链接到qdoc中,而非动态链接。静态链接会把库代码直接嵌入可执行文件,因此ldd无法检测到动态依赖。你可以用
nm或objdump工具检查预编译qdoc是否包含Clang符号,比如执行objdump -t ./qdoc | grep clang,如果能找到相关符号,说明是静态链接了Clang。内部集成简化版Clang:Qt官方可能为qdoc定制了简化版的Clang组件,将其作为内部模块构建,无需依赖外部动态库,因此不会出现在ldd输出中。
构建配置差异:你自己编译时显式指定了
-DLLVM_INSTALL_DIR,强制qdoc动态链接外部LLVM/Clang库;而官方构建可能使用了内部专属配置,比如启用了QT_BUILD_INTERNAL选项,或直接使用Qt内部集成的Clang资源,避免外部依赖。
结论
预编译版qdoc并非未使用Clang,而是通过静态链接或内部集成的方式引入了Clang功能,因此动态依赖列表中看不到libclang。
内容的提问来源于stack exchange,提问作者Nguyen Thanh Trung

