• Linux aarch64交叉编译之 weston窗口管理程序


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

    1 weston的来龙去脉

    在介绍weston之前,我们不得不来说说wayland。因为weston本质上就是wayland的一种实现。而说到wayland,又不得不提一下X11,那么接下来我们从X11->wayland->weston这条路线系统地理解下weston。

    Wayland资料索引:

    我们基于黄金圈法则,搞懂why,也就是为啥要搞出一个wayland来?那我们首先就要了解历史,先来看看X11。

    1.1 X11,一个古老的图形系统

    这里X表示的是协议,是1984年起始于 MIT(麻省理工学院)。11表示的是协议的版本号(实际版本是11 release 7.6),是在 1987年9月提出的。该方案是由 X 基金会所领导。

    在wayland出来之前,Linux系统一直使用X11图形系统,这是一个古老的系统,到目前为止有近40年的历史,设计之初是因为个人PC性能低,所以构建了这样架构:

    • 所有渲染相关的计算都放在X Server端(本地的X显示程序,提供显示服务,它扮演了服务器的角色),而X Client端是既可以运行在本地端,也可以运行在网络端,代表客户端角色。 
    • X Server和XClient通信的手段就是X Protocol。所有的客户端接收到鼠标,键盘等等事件,都要通知Server,Server经过计算,通知驱动层进行绘制。

    1.2 wayland诞生缘由和原理,性能大幅度提升带来的变革

    Wayland的定位:替换Linux上的X11系统。

    Wayland协议诞生的缘由:

    • X11的框架在当时计算机性能较弱的环境下几乎是唯一可行的方式,但随着计算机性能的提升,“客户端”也有很强大的渲染能力。
    • 原本在X11图形系统中 X Server中做的事很多已被移到kernel或者单独的库中,因此X Server就显得比较累赘了。

    接下来谈谈Wayland本身,也就是what:

    @1 Wayland是啥?

    Wayland是一种表示显示系统server端与client端之间的通信协议。与X11相比只是原理不同而已。

    @2 Wayland原理是啥?

    Wayland的大概原理是:所有渲染都发生在client端,client端根据自己的业务逻辑构建相应的图形界面,计算需要渲染render的区域,然后在内存中开辟一段空间(可以是共享内存,也可以是显存,取决于实际硬件,注意,这里不是buffer的拷贝,而是把buffer的fd直接进行传递,效率高),将绘制好的图像放入buffer中,通知Wayland的Server(Compositor,表图像合成器),Compositor会监听所有client的请求,把所有Client绘制好的图片合成后发送到渲染器渲染并显示。

    这种设计相比X11大幅度减少了Client和Server的频繁交互和数据传递,所以效率大幅度提高。

    1.3 关键解读:Weston是啥?

    Weston是Wayland compositor的参考实现(就像OpenGL是一种标准,而mesa是OpenGL的一种实现一样)。其官网为http://wayland.freedesktop.org/

    最后附上weston的Github下载地址:GitHub - wayland-project/weston

    2 Linux 本地编译 & 交叉编译

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

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

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

    这里关于安装位置,可以通过--prefix=具体路径来设置。

    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

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

    1. [binaries]
    2. c = 'aarch64-linux-gnu-gcc'
    3. cpp = 'aarch64-linux-gnu-cpp'
    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'

    之后在weston目录下执行:

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

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

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

    也就是进入到sysroot对应的虚拟机/mnt/data/arm64中安装缺失的库。

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

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

    调整compositor中内容,主要是将环境变量WESTON_MODULE_MAP置空,进而在链接库的时候走默认路径,weston代码修改如下:

    1. diff --git a/weston/libweston/compositor.c b/weston/libweston/compositor.c
    2. index a594d67..bd942da 100644
    3. --- a/weston/libweston/compositor.c
    4. +++ b/weston/libweston/compositor.c
    5. @@ -7985,7 +7985,7 @@ weston_version(int *major, int *minor, int *micro)
    6. WL_EXPORT size_t
    7. weston_module_path_from_env(const char *name, char *path, size_t path_len)
    8. {
    9. - const char *mapping = getenv("WESTON_MODULE_MAP");
    10. + const char *mapping ="";// getenv("WESTON_MODULE_MAP");
    11. const char *end;
    12. const int name_len = strlen(name);

    接下来修改weston配置文件meson_options.txt,修改内容如下:

    1. diff --git a/weston/meson_options.txt b/weston/meson_options.txt
    2. index 32daa01..cb9c179 100644
    3. --- a/weston/meson_options.txt
    4. +++ b/weston/meson_options.txt
    5. @@ -85,6 +85,20 @@ option(
    6. description: 'Xwayland: path to installed Xwayland binary'
    7. )
    8. +option(
    9. + 'x-moduledir-path',
    10. + type: 'string',
    11. + value: 'default',
    12. + description: 'x define for different moduledir path'
    13. +)
    14. +
    15. +option(
    16. + 'x-libwestonmoduledir-path',
    17. + type: 'string',
    18. + value: 'default',
    19. + description: 'x define for different libweston moduledir path'
    20. +)
    21. +
    22. option(
    23. 'systemd',
    24. type: 'boolean',

    接下来修改weston的配置文件meson.build,将MODULEDIR 和LIBWESTON_MODULEDIR的默认加载路径重新设置,如下所示:

    1. diff --git a/weston/meson.build b/weston/meson.build
    2. index 63943f3..6ecf32c 100644
    3. --- a/weston/meson.build
    4. +++ b/weston/meson.build
    5. @@ -116,8 +116,11 @@ config_h.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/wayland
    6. config_h.set_quoted('BINDIR', dir_bin)
    7. config_h.set_quoted('DATADIR', dir_data)
    8. config_h.set_quoted('LIBEXECDIR', dir_libexec)
    9. -config_h.set_quoted('MODULEDIR', dir_module_weston)
    10. -config_h.set_quoted('LIBWESTON_MODULEDIR', dir_module_libweston)
    11. +
    12. +#config_h.set_quoted('MODULEDIR',dir_module_weston)
    13. +#config_h.set_quoted('LIBWESTON_MODULEDIR',dir_module_libweston)
    14. +config_h.set_quoted('MODULEDIR', get_option('x-moduledir-path'))
    15. +config_h.set_quoted('LIBWESTON_MODULEDIR', get_option('x-libwestonmoduledir-path'))
    16. config_h.set10('TEST_GL_RENDERER', get_option('test-gl-renderer'))

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

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

    之后编译出来的库和相关bin文件就可以在开发板上运行啦~。

    特殊说明:之前在解决该问题时优先考虑的是设置LD_LIBRARY_PATH变量,但是发现并不管用,这是为什么呢?因为weston人家自己搞了一套设置加载库路径的东东,那为啥要这么搞呢?如果看了代码我们会知道,weston是使用dlopen这种方式直接打开库的,并不是简单的加载,因此 LD_LIBRARY_PATH这种链接库的设置是无效的。

  • 相关阅读:
    【Docker】之安装 RabbitMQ
    LINUX中的vi/vim命令
    2020美亚团队赛复盘
    2022-08-11 第六小组 瞒春 学习笔记
    【Python】逻辑回归变量的显著性分析
    自然语言处理(八):预训练BERT
    leetcode - 串联所有单词的子串 - 最小覆盖子串 - x 的平方根
    Transformers北大源
    CKA认证,开启您的云原生之旅!
    Spring mvc实现文件上传
  • 原文地址:https://blog.csdn.net/vviccc/article/details/125363702