记一次debug

来源:互联网 发布:华东师范大学知乎 编辑:程序博客网 时间:2024/06/06 14:14

问题描述

移植Qt5.5.1到 hisiv400嵌入式开发板,之前的工作包括:
1. 搭建嵌入式开发环境(boot, kernel, fs && 交叉编译环境)
2. 获取Qt5.5.1源码
3. 配置mkspecs文件
4. 设置configure参数

移植Qt到嵌入式平台,最大的问题,就是platform plugin问题,即告诉Qt调用嵌入式平台支持的方式渲染窗口,因为板卡自身不带窗口。

我的情况:EGL && mali

后两步的细节移步这里。

接着执行:

./configure -v ...make -j5make install

把相关文件部署到板子上,配置板子的环境变量

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/duino/lib:/mnt/duino/qt5/libexport QTDIR=/mnt/duino/qt5export QT_QPA_FONTDIR=/mnt/duino/qt5/lib/fontsexport QT_QPA_PLATFORM_PLUGIN_PATH=/mnt/duino/qt5/pluginsexport QT_QPA_PLATFORM=eglfsexport QT_QPA_EGLFS_FB=/dev/fb0export QT_QPA_EGLFS_WIDTH=1280export QT_QPA_EGLFS_HEIGHT=720export QT_QPA_EGLFS_DEPTH=32export QT_QPA_EGLFS_DEBUG="yes"export QT_QPA_EGLFS_INTEGRATION=eglfs_mali

运行Qt demo(qtbase/examples/widgets/widgets/analogclock

./analogclock

配置了QT_QPA_PLATFORM变量,可以省略”-platform eglfs”。

...Failed to load libGLESv2Aborted.

就这样不动声色地,毫无征兆地,不知不觉地,出错了。

定位问题

加载库文件失败,这个问题说明它找到了库,只是没有成功加载。说明问题出在程序里面。

Qt依赖三个与窗口渲染有关的外部库libEGL.so, libGLESv2.so, libmali.so

库文件是在程序运行时加载的,那么,这条错误语句,肯定可以在Qt源码里面找到。

cd .../qtbase/srcfind . | xargs grep "Failed to load libGLESv2" -r

果然找到了,它出现在qtbase/src/gui/opengl/qopenglfunctions.cpp文件中,QOpenGLES3Helper的构造函数里面。

继续往里面寻找,找到这个函数:

bool QOpenGLES3Helper::init(){#ifndef Q_OS_IOS# ifdef Q_OS_WIN#  ifndef QT_DEBUG    m_gl.setFileName(QStringLiteral("libGLESv2"));#  else    m_gl.setFileName(QStringLiteral("libGLESv2d"));#  endif# else#  ifdef Q_OS_ANDROID    m_gl.setFileName(QStringLiteral("GLESv2"));#  else    m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2);#  endif# endif // Q_OS_WIN    return m_gl.load();#else    return true;#endif // Q_OS_IOS}

由于Qt跨平台,所以源码里面有各种预编译命令,习惯就好。

在这个函数上面,看到一段话:

// Functions part of the OpenGL ES 3.0+ standard need special handling. These,// just like the 2.0 functions, are not guaranteed to be resolvable via// eglGetProcAddress or similar. Calling them directly is, unlike the 2.0// functions, not feasible because one may build the binaries on a GLES3-capable// system and then deploy on a GLES2-only system that does not have these// symbols. Until ES3 gets universally available, they have to be dlsym'ed.

大概是说OpenGL ES 3.0 和 2.0的兼容性方面的问题。

我一直特别纳闷,为啥我使用的是libGLESv2,会出现QOpenGLES3Helper。我怀疑是不是开始配置的时候,告诉了Qt适配高版本的OpenGL ES, 而实际的低于这个版本,所以导致导入失败。

解决问题

尝试1

在configure的时候,禁止适配高版本的OpenGL ES3。撸起袖子改代码。

打开configure文件,找到下面这段,注释掉。

# If OpenGL ES 2.0 is enabled, check for 3.0 and higher. This is used to allow# compile-time differentiation and including the version specific (but backwards# compatible) ES headers (for example, GLES3/gl31.h). Other than that, there is# no difference in the configuration, even the library is the same.#if [ "$CFG_OPENGL" = "es2" ]; then#    if compileTestWithPkgConfig glesv2 unix/opengles3 "OpenGL ES 3.0" ""; then#        # Add a define for ES3, in addition to ES and ES2.#        QCONFIG_FLAGS="$QCONFIG_FLAGS QT_OPENGL_ES_3"#    fi#    if compileTestWithPkgConfig glesv2 unix/opengles31 "OpenGL ES 3.1" ""; then#        # Add a define for ES31.#        QCONFIG_FLAGS="$QCONFIG_FLAGS QT_OPENGL_ES_3_1"#    fi#fi

之后再./configure && make && make install,运行程序,错误依旧。

尝试2

问题还是在代码里面,QOpenGLES3Helper::init()里的load()失败了,原因可能是版本的问题。把这个函数里的这句话:

m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 2);

换成下面几种形式试一试:

m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 1);m_gl.setFileNameAndVersion(QStringLiteral("GLESv2"), 0);m_gl.setFileName(QStringLiteral("GLESv2"));

第三种设置的方式成功了!!!!!!

当看到连接嵌入式板卡的显示器,显示Qt应用程序的那一刻,突然感觉,整个世界都美好了,简直太棒了!!! 如果拍照方便的话,我肯定贴一张显示器的图片了~毕竟移植Qt这件事情,干了有3个星期,今天终于算是有了一个进步。

0 0
原创粉丝点击