在为 Raspberry Pi 4 (arm64) 构建 Qt 5.15.2 时,无法 link 对抗交叉编译的 opengl_es2

Cannot link against cross-compiled opengl_es2 when building Qt 5.15.2 for Raspberry Pi 4 (arm64)

我正在尝试为 arm64 Pi4 编译 Qt 5.15.2。 配置阶段失败

ERROR: Feature 'opengles2' was enabled, but the pre-condition '(config.win32 && !features.opengl-dynamic) || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)' failed.

ERROR: Feature 'eglfs' was enabled, but the pre-condition '!config.android && !config.darwin && !config.win32 && !config.wasm && features.egl' failed.

ERROR: The OpenGL functionality tests failed!

阅读构建输出后,我看到了 OpenGL 测试如何失败:

+ cd /build/pi4/parts/qtbase/build/config.tests/opengl_es2 && PKG_CONFIG_SYSROOT_DIR=/ PKG_CONFIG_LIBDIR=/build/pi4/stage/usr/lib/pkgconfig:/build/pi4/stage/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig /build/pi4/parts/qtbase/build/bin/qmake "CONFIG -= qt debug_and_release app_bundle lib_bundle" "CONFIG += shared warn_off console single_arch" 'QMAKE_LIBDIR += /build/pi4/stage/usr/lib/aarch64-linux-gnu' -early "CONFIG += cross_compile" 'QMAKE_USE += opengl_es2' 'QMAKE_LIBS_OPENGL_ES2 = -L//build/pi4/stage/usr/lib -lGLESv2' 'QMAKE_INCDIR_OPENGL_ES2 = //build/pi4/stage/usr/include' /build/pi4/parts/qtbase/build/config.tests/opengl_es2
+ cd /build/pi4/parts/qtbase/build/config.tests/opengl_es2 && MAKEFLAGS= /usr/bin/make
> /usr/bin/aarch64-linux-gnu-g++ -c -march=armv8-a -mtune=cortex-a72 -O2 -w -fPIC  -I. -I/build/pi4/stage/usr/include -I/build/pi4/parts/qtbase/build/mkspecs/devices/linux-rasp-pi4-v3d-g++ -o main.o main.cpp
> /usr/bin/aarch64-linux-gnu-g++ -Wl,-O1 -o opengl_es2 main.o   -L/build/pi4/stage/usr/lib/aarch64-linux-gnu -L//build/pi4/stage/usr/lib -lGLESv2   
> /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: warning: libglapi.so.0, needed by //build/pi4/stage/usr/lib/libGLESv2.so, not found (try using -rpath or -rpath-link)
> /usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: //build/pi4/stage/usr/lib/libGLESv2.so: undefined reference to `_glapi_tls_Dispatch'
> collect2: error: ld returned 1 exit status
> make: *** [Makefile:69: opengl_es2] Error 1

但是 libglapi.so.0 正好在 -L//build/pi4/stage/usr/lib 中。

我手动执行了测试步骤,但失败并出现同样的错误:

root@10cb734e2e05:~/pi4/parts/qtbase/build/config.tests/opengl_es2# /usr/bin/aarch64-linux-gnu-g++ -Wl,-O1 -o opengl_es2 main.o   -L/build/pi4/stage/usr/lib/aarch64-linux-gnu -L//build/pi4/stage/usr/lib -lGLESv2
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: warning: libglapi.so.0, needed by //build/pi4/stage/usr/lib/libGLESv2.so, not found (try using -rpath or -rpath-link)
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld: //build/pi4/stage/usr/lib/libGLESv2.so: undefined reference to `_glapi_tls_Dispatch'
collect2: error: ld returned 1 exit status

但是如果我指定相同的路径/build/pi4/stage/usr/lib-rpath,编译成功:

root@10cb734e2e05:~/pi4/parts/qtbase/build/config.tests/opengl_es2# /usr/bin/aarch64-linux-gnu-g++ -Wl,-O1,-rpath=/build/pi4/stage/usr/lib -o opengl_es2 main.o   -L/build/pi4/stage/usr/lib/aarch64-linux-gnu -L//build/pi4/stage/usr/lib -lGLESv2

所以我的问题是 - 为什么链接器找不到与 -L 参数相同的库,但如果我使用 -rpath 却可以找到?

根本原因是链接器找不到依赖项的依赖项。 LD_LIBRARY_PATHL 在这种情况下不起作用。你应该使用 -rpath-link.

您可以在我最后提到的 post 中阅读更多详细信息。

编译Qt时,您可以为您需要的库传递额外的参数。 就我而言,我必须添加以下代码才能使其正常工作:

QMAKE_LIBS_OPENGL_ES2+="-Wl,-rpath,${SNAPCRAFT_STAGE}/usr/lib/" \
QMAKE_LIBS_EGL+="-Wl,-rpath,${SNAPCRAFT_STAGE}/usr/lib/" \

我的解决方案基于此post:Why does ld need -rpath-link when linking an executable against a so that needs another so?

和这篇文章:Why does ld need -rpath-link when linking an executable against a so that needs another so?