对于weston的交叉编译。该文章的目标是编译一套aarch64 Linux Debian嵌入式版本上可以运行的版本库以及相关程序,接下来就开始趟坑。老套路,先把linux桌面版搞好,然后 移植到嵌入式Linux Debian 板子上。
在介绍weston之前,我们不得不来说说wayland。因为weston本质上就是wayland的一种实现。而说到wayland,又不得不提一下X11,那么接下来我们从X11->wayland->weston这条路线系统地理解下weston。
Wayland资料索引:
我们基于黄金圈法则,搞懂why,也就是为啥要搞出一个wayland来?那我们首先就要了解历史,先来看看X11。
这里X表示的是协议,是1984年起始于 MIT(麻省理工学院)。11表示的是协议的版本号(实际版本是11 release 7.6),是在 1987年9月提出的。该方案是由 X 基金会所领导。
在wayland出来之前,Linux系统一直使用X11图形系统,这是一个古老的系统,到目前为止有近40年的历史,设计之初是因为个人PC性能低,所以构建了这样架构:
Wayland的定位:替换Linux上的X11系统。
Wayland协议诞生的缘由:
接下来谈谈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的频繁交互和数据传递,所以效率大幅度提高。
Weston是Wayland compositor的参考实现(就像OpenGL是一种标准,而mesa是OpenGL的一种实现一样)。其官网为http://wayland.freedesktop.org/
最后附上weston的Github下载地址:GitHub - wayland-project/weston
weston是使用meson进行编译的,根据README.md的提示,编译关键步骤如下:
$meson build
$ninja -C build
$ninja -C build install
这里关于安装位置,可以通过--prefix=具体路径来设置。
因为是用aarch64交叉编译,需要提前配置环境,安装如下软件:
sudo apt install binutils-aarch64-linux-gnu-dbg binutils-aarch64-linux-gnu cpp-aarch64-linux-gnu \
g++-10-aarch64-linux-gnu g++-9-aarch64-linux-gnu g++-aarch64-linux-gnu g++ \
gcc-10-aarch64-linux-gnu-base gcc-9-aarch64-linux-gnu-base gcc-aarch64-linux-gnu \
pkg-config-aarch64-linux-gnu qemu-efi-aarch64 gcc arch-test
构建一个sysroot路径需要用到的aarch64虚拟机,方式如下:
#创建一个虚拟fs文件系统
$sudo qemu-debootstrap --arch arm64 bullseye /mnt/data/arm64 http://deb.debian.org/debian/
#进入到文件系统
$sudo chroot /mnt/data/arm64/
#退出文件系统
$exit
在weston目录下构建一个arm64文件,内容如下:
[binaries]
c = 'aarch64-linux-gnu-gcc'
cpp = 'aarch64-linux-gnu-cpp'
ar = 'aarch64-linux-gnu-gcc-ar'
strip = 'aarch64-linux-gnu-strip'
pkgconfig = 'aarch64-linux-gnu-pkg-config'
ld = 'aarch64-linux-gnu-ld'
pcap-config = ''
cmake = 'cmake'
[properties]
skip_sanity_check = true
sys_root = '/mnt/data/arm64'
# Generate binaries that are portable across all Armv8 machines
platform = 'generic'
pkg_config_libdir ='/mnt/data/arm64/usr/lib/aarch64-linux-gnu/pkgconfig:/mnt/data/arm64//usr/share/pkgconfig'
[built-in options]
c_args = ['--sysroot', '/mnt/data/arm64']
c_link_args = ['-Wl,-rpath', '/mnt/data/arm64/usr/lib/aarch64-linux-gnu/', '-Wl,--as-needed']
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'
之后在weston目录下执行:
$meson build --cross-file arm64.txt
$ninja -C build
$ninja -C build install
注意:这个时候编译有可能出现各种缺库的问题,我们需要执行
$sudo chroot /mnt/data/arm64/
$apt search [缺的库 关键字检索]
$apt-file search [缺少的头文件之类的关键字检索]
$apt install [相关的库]
也就是进入到sysroot对应的虚拟机/mnt/data/arm64中安装缺失的库。
通过前面的操作,编译成功后可以将weston其移动到debian开发板上(注意:开发版的库 需要和 虚拟机运行时缺少的库作同步)。但是这时候发现会有很多链接的错误,找不到库,我们这样调整
调整compositor中内容,主要是将环境变量WESTON_MODULE_MAP置空,进而在链接库的时候走默认路径,weston代码修改如下:
diff --git a/weston/libweston/compositor.c b/weston/libweston/compositor.c
index a594d67..bd942da 100644
--- a/weston/libweston/compositor.c
+++ b/weston/libweston/compositor.c
@@ -7985,7 +7985,7 @@ weston_version(int *major, int *minor, int *micro)
WL_EXPORT size_t
weston_module_path_from_env(const char *name, char *path, size_t path_len)
{
- const char *mapping = getenv("WESTON_MODULE_MAP");
+ const char *mapping ="";// getenv("WESTON_MODULE_MAP");
const char *end;
const int name_len = strlen(name);
接下来修改weston配置文件meson_options.txt,修改内容如下:
diff --git a/weston/meson_options.txt b/weston/meson_options.txt
index 32daa01..cb9c179 100644
--- a/weston/meson_options.txt
+++ b/weston/meson_options.txt
@@ -85,6 +85,20 @@ option(
description: 'Xwayland: path to installed Xwayland binary'
)
+option(
+ 'x-moduledir-path',
+ type: 'string',
+ value: 'default',
+ description: 'x define for different moduledir path'
+)
+
+option(
+ 'x-libwestonmoduledir-path',
+ type: 'string',
+ value: 'default',
+ description: 'x define for different libweston moduledir path'
+)
+
option(
'systemd',
type: 'boolean',
接下来修改weston的配置文件meson.build,将MODULEDIR 和LIBWESTON_MODULEDIR的默认加载路径重新设置,如下所示:
diff --git a/weston/meson.build b/weston/meson.build
index 63943f3..6ecf32c 100644
--- a/weston/meson.build
+++ b/weston/meson.build
@@ -116,8 +116,11 @@ config_h.set_quoted('PACKAGE_BUGREPORT', 'https://gitlab.freedesktop.org/wayland
config_h.set_quoted('BINDIR', dir_bin)
config_h.set_quoted('DATADIR', dir_data)
config_h.set_quoted('LIBEXECDIR', dir_libexec)
-config_h.set_quoted('MODULEDIR', dir_module_weston)
-config_h.set_quoted('LIBWESTON_MODULEDIR', dir_module_libweston)
+
+#config_h.set_quoted('MODULEDIR',dir_module_weston)
+#config_h.set_quoted('LIBWESTON_MODULEDIR',dir_module_libweston)
+config_h.set_quoted('MODULEDIR', get_option('x-moduledir-path'))
+config_h.set_quoted('LIBWESTON_MODULEDIR', get_option('x-libwestonmoduledir-path'))
config_h.set10('TEST_GL_RENDERER', get_option('test-gl-renderer'))
修改好代码后,这次我们重新编译,执行meson时候多了两个宏的设置,详细如下:
$meson build --prefix=[交叉编译输出路径] \
-Dx-moduledir-path=[开发板 库路径] \
-Dx-libwestonmoduledir-path=[开发板 库路径] \
--cross-file arm64.txt
$ninja -C build
$ninja -C build install
之后编译出来的库和相关bin文件就可以在开发板上运行啦~。
特殊说明:之前在解决该问题时优先考虑的是设置LD_LIBRARY_PATH变量,但是发现并不管用,这是为什么呢?因为weston人家自己搞了一套设置加载库路径的东东,那为啥要这么搞呢?如果看了代码我们会知道,weston是使用dlopen这种方式直接打开库的,并不是简单的加载,因此 LD_LIBRARY_PATH这种链接库的设置是无效的。