• Linux aarch64交叉编译之 mesa图形库


    对于mesa的交叉编译。该文章的目标是编译一套aarch64 Linux Debian嵌入式版本上可以运行的版本库,接下来就开始趟坑。老套路,先把linux桌面版搞好,然后 移植到嵌入式Linux Debian 板子上。

    1 mesa简介

    Mesa 3D是一个在MIT许可证下开放源代码的三维计算机图形库,以开源形式实现了OpenGL的应用程序接口。OpenGL的高效实现一般依赖于显示设备厂商提供的硬件,而Mesa 3D是一个纯基于软件的图形应用程序接口。由于许可证的原因,它只声称是一个“类似”于OpenGL的应用程序接口。

    简而言之,mesa就是一套OpenGL标准的实现库,接口都是一样的。

    附上mesa的github项目下载地址:GitHub - projectmesa/mesa: Mesa

    2 Linux 本地编译 & 交叉编译

    2.1 Linux(ubuntu20.04)上mesa的编译

    mesa是使用meson进行编译的,根据README.md的提示,编译关键步骤如下:

    1. $meson build
    2. $ninja -C build
    3. $ninja -C build install

    这里关于安装位置,可以通过--prefix=具体路径来设置。mesa编译后生成的是就是我们常见的OpenGL 的那种库,如下所示:

    1. ├── dri
    2. │   ├── armada-drm_dri.so
    3. │   ├── asahi_dri.so
    4. │   ├── etnaviv_dri.so
    5. │   ├── exynos_dri.so
    6. │   ├── hx8357d_dri.so
    7. │   ├── i830_dri.so
    8. │   ├── i915_dri.so
    9. │   ├── i965_dri.so
    10. │   ├── ili9225_dri.so
    11. │   ├── ili9341_dri.so
    12. │   ├── imx-dcss_dri.so
    13. │   ├── imx-drm_dri.so
    14. │   ├── ingenic-drm_dri.so
    15. │   ├── kgsl_dri.so
    16. │   ├── kms_swrast_dri.so
    17. │   ├── lima_dri.so
    18. │   ├── mcde_dri.so
    19. │   ├── mediatek_dri.so
    20. │   ├── meson_dri.so
    21. │   ├── mi0283qt_dri.so
    22. │   ├── msm_dri.so
    23. │   ├── mxsfb-drm_dri.so
    24. │   ├── nouveau_vieux_dri.so
    25. │   ├── panfrost_dri.so
    26. │   ├── pl111_dri.so
    27. │   ├── r200_dri.so
    28. │   ├── r300_dri.so
    29. │   ├── r600_dri.so
    30. │   ├── r600_drv_video.so
    31. │   ├── radeon_dri.so
    32. │   ├── repaper_dri.so
    33. │   ├── rockchip_dri.so
    34. │   ├── st7586_dri.so
    35. │   ├── st7735r_dri.so
    36. │   ├── stm_dri.so
    37. │   ├── sun4i-drm_dri.so
    38. │   ├── swrast_dri.so
    39. │   ├── v3d_dri.so
    40. │   ├── vc4_dri.so
    41. │   ├── virtio_gpu_dri.so
    42. │   └── zink_dri.so
    43. ├── libEGL.so -> libEGL.so.1
    44. ├── libEGL.so.1 -> libEGL.so.1.0.0
    45. ├── libEGL.so.1.0.0
    46. ├── libgbm.so -> libgbm.so.1
    47. ├── libgbm.so.1 -> libgbm.so.1.0.0
    48. ├── libgbm.so.1.0.0
    49. ├── libglapi.so -> libglapi.so.0
    50. ├── libglapi.so.0 -> libglapi.so.0.0.0
    51. ├── libglapi.so.0.0.0
    52. ├── libGLESv1_CM.so -> libGLESv1_CM.so.1
    53. ├── libGLESv1_CM.so.1 -> libGLESv1_CM.so.1.1.0
    54. ├── libGLESv1_CM.so.1.1.0
    55. ├── libGLESv2.so -> libGLESv2.so.2
    56. ├── libGLESv2.so.2 -> libGLESv2.so.2.0.0
    57. ├── libGLESv2.so.2.0.0
    58. ├── libGL.so -> libGL.so.1
    59. ├── libGL.so.1 -> libGL.so.1.2.0
    60. ├── libGL.so.1.2.0
    61. ├── libxatracker.so -> libxatracker.so.2
    62. ├── libxatracker.so.2 -> libxatracker.so.2.5.0
    63. ├── libxatracker.so.2.5.0
    64. └── pkgconfig

    说明:这里dri目录下的内容是和平台相关的(比如i915是intel的,lima和panfrost是mali的,只是支持的代数不一样而已。当然,如果该GPU比较新 比如G610这种的,mesa如果不支持会使用swrast驱动来使用CPU模拟绘制 同时 性能会大幅度下降)。如果涉及嵌入式Linux的移植,一般这种dri驱动 留一个即可。

    2.2 aarch64交叉编译与移植

    2.2.1 交叉编译

    构建一个sysroot路径需要用到的aarch64虚拟机,方式如下:

    1. #创建一个虚拟fs文件系统
    2. $sudo qemu-debootstrap --arch arm64 bullseye /mnt/data/arm64 http://deb.debian.org/debian/
    3. #进入到文件系统
    4. $sudo chroot /mnt/data/arm64/
    5. #退出文件系统
    6. $exit

    在mesa目录下构建一个arm64文件,内容如下:

    1. [binaries]
    2. c = 'aarch64-linux-gnu-gcc'
    3. cpp = 'aarch64-linux-gnu-g++'
    4. ar = 'aarch64-linux-gnu-gcc-ar'
    5. strip = 'aarch64-linux-gnu-strip'
    6. pkgconfig = 'aarch64-linux-gnu-pkg-config'
    7. ld = 'aarch64-linux-gnu-ld'
    8. pcap-config = ''
    9. cmake = 'cmake'
    10. [properties]
    11. skip_sanity_check = true
    12. sys_root = '/mnt/data/arm64'
    13. # Generate binaries that are portable across all Armv8 machines
    14. platform = 'generic'
    15. pkg_config_libdir ='/mnt/data/arm64/usr/lib/aarch64-linux-gnu/pkgconfig:/mnt/data/arm64/usr/share/pkgconfig'
    16. [built-in options]
    17. c_args = ['--sysroot', '/mnt/data/arm64']
    18. c_link_args = ['-Wl,-rpath', '/mnt/data/arm64/usr/lib/aarch64-linux-gnu/', '-Wl,--as-needed']
    19. [host_machine]
    20. system = 'linux'
    21. cpu_family = 'aarch64'
    22. cpu = 'armv8-a'
    23. endian = 'little'

    之后在mesa目录下执行:

    1. $meson build --cross-file arm64.txt
    2. $ninja -C build
    3. $ninja -C build install

    注意:这个时候编译有可能出现各种缺库的问题,和之前编译weston时一样,我们需要执行:

    1. $sudo chroot /mnt/data/arm64/
    2. $apt search [缺的库 关键字检索]
    3. $apt-file search [缺少的头文件之类的关键字检索]
    4. $apt install [相关的库]

    2.2.2 解决移植中的库链接问题

    通过前面的操作,编译成功后可以将mesa其移动到debian开发板上(注意:开发版的库 需要和 虚拟机运行时缺少的库作同步)。但是这时候发现会有很多链接的错误,找不到库,我们这样调整

    mesa在链接库的时候走search_paths变量,因此我们的思路就是调整search_paths变量,mesa的配置文件meson_options.txt,修改内容如下:

    1. diff --git a/meson_options.txt b/meson_options.txt
    2. index 33471f0..95c47bb 100644
    3. --- a/meson_options.txt
    4. +++ b/meson_options.txt
    5. @@ -467,3 +467,10 @@ option(
    6. value : true,
    7. description : 'use msse2 flag for mingw x86. Default: true',
    8. )
    9. +option(
    10. + 'x-default-drv-dir',
    11. + type: 'string',
    12. + value: 'default',
    13. + description: 'x define for different moduledir path'
    14. +)

    接下来修改weston配置文件meson.build,将dri-search-path替换成x-default-drv-dir,如下所示:

    1. diff --git a/meson.build b/meson.build
    2. index 0c3d0c7..4d8b589 100644
    3. --- a/meson.build
    4. +++ b/meson.build
    5. @@ -83,7 +83,8 @@ dri_drivers_path = get_option('dri-drivers-path')
    6. if dri_drivers_path == ''
    7. dri_drivers_path = join_paths(get_option('prefix'), get_option('libdir'), 'dri')
    8. endif
    9. -dri_search_path = get_option('dri-search-path')
    10. +#dri_search_path = get_option('dri-search-path')
    11. +dri_search_path = get_option('x-default-drv-dir')
    12. if dri_search_path == ''
    13. dri_search_path = dri_drivers_path
    14. endif

    修改好代码后,这次我们重新编译,执行meson时候多了一个宏的设置,详细如下:

    1. $meson build --prefix=[交叉编译输出路径] \
    2. -Dx-default-drv-dir=[开发板 库路径] \
    3. --cross-file arm64.txt
    4. $ninja -C build
    5. $ninja -C build install

    之后编译出来的库文件放到开发板对应位置就可以使用啦~。当然这里dri的库 需要根据开发板实际情况调整(比如 RK3399的板子,GPU是T860,拷贝panfrost_dri.so即可,其他的可以不用拷贝)。

  • 相关阅读:
    Redis实战——短信登录
    Dart笔记:stream_channel 包用法
    【杂记-浅谈端口号和协议号】
    从小白到大咖:软件测试工作半年心得分享!总结我掉的4个坑…
    SpringBoot 配置进阶
    2023华为OD统一考试(B卷)题库清单(按算法分类),如果你时间紧迫,就按这个刷
    明明拍毕业照
    Golang 程序启动原理详解
    Python 教程之运算符(12)a += b 并不总是等价于 a = a + b
    java8 新特性5 方法引用
  • 原文地址:https://blog.csdn.net/vviccc/article/details/126104486