目录

xserver-xsdl实现了在Android环境下运行xserver显示linux图形桌面程序的功能

1. 准备源代码

最新代码在GitHub上,xserver-xsdl代码库,该代码库只有源码,最新代码在xsdl-1.20,不包含编译时的依赖包,基本编译不出来。

存在第三方打包的源代码XServer-XSDL-1.20.51-src.tar.xz,既包含源码,也包含依赖包在内的编译工程,做少量修改即可编译出app。

解压xz包,创建目录(mkdir -p xserver-xsdl),解药(tar Jxf XServer-XSDL-1.20.51-src.tar.xz -C xserver-xsdl)

XServer-XSDL-1.20.51解压后达到3G多的存储空间,主要因为其包含了编译不同CPU架构的依赖包编译环境和依赖包编译中间文件,为减少包的大小,可删除不用的CPU架构编译环境,只保留arm64-v8a编译环境,可用下面脚本删除相关文件:

1#!/bin/bash 2 3 4 5UNUSE_CPU_LIST="armeabi-v7a x86 x86_64" 6 7for CPU in ${UNUSE_CPU_LIST} ;do 8 find project -name "${CPU}" -exec rm -rf {} \; 2>/dev/null 9 find project -name "tmp-${CPU}" -exec rm -rf {} \; 2>/dev/null 10done

在构建git代码库时,可以忽略以下文件

1# .gitignore 2 3project/jni/application/xserver/libapplication-*.so 4project/jni/application/xserver/AndroidData/bin-map.zip 5project/jni/application/xserver/AndroidData/lib/ 6 7project/.gradle/ 8project/.knownPackages 9project/app/build.gradle 10project/app/build/ 11project/assets/ 12project/build-tools/ 13project/build/ 14project/emulator/ 15project/jni/Settings.mk 16project/jni/application/xserver/gfx-arm64-v8a.o 17project/jni/application/xserver/main-arm64-v8a.o 18project/jni/openssl/include/ 19project/jni/openssl/lib-arm64-v8a/ 20project/jni/openssl/lib-armeabi-v7a/ 21project/jni/openssl/lib-x86/ 22project/jni/openssl/lib-x86_64/ 23 24project/lib 25project/libs/ 26project/licenses 27project/local.properties 28project/obj/local/ 29project/patcher/ 30project/platform-tools/ 31project/platforms/ 32project/proguard-local.cfg 33project/res/drawable/banner.png 34project/res/raw/xsdl.raw 35project/res/values-es/ 36project/res/values-fr/ 37project/res/values-ru/ 38project/res/values-uk/ 39project/res/values-zh/ 40project/res/values/strings.xml 41project/tools/

注:

  • XServer-XSDL-1.20.51中包含依赖包源码编译生成的中间文件,如.libs,.deps,.o等,删除这些文件会导致编译失败,其编译工程可能存在一些文件有待解决

  • 使用xserver-xsdl最新代码代替XServer-XSDL-1.20.51中的相关部分,其编译依赖报错(xcb)等

2. 构建编译环境镜像

根据Dockerfile构建编译环境镜像:docker build -f xserver-xsdl.docker -t xserver-xsdl.image . 若镜像存在,可省略该步。

1#xserver-xsdl.docker 2 3FROM ubuntu:22.04 4 5RUN apt-get update 6RUN apt-get install -y apt-utils 7RUN apt-get install -y bison file wget 8RUN apt-get install -y make zip pkg-config curl autoconf automake autopoint libtool libtool-bin help2man texinfo intltool 9RUN apt-get install -y xfonts-utils xutils-dev libfontenc-dev libxkbfile-dev libxmuu-dev libxfont-dev 10RUN apt-get install -y libjpeg-dev libpng-dev libpixman-1-dev libssl-dev libpciaccess-dev 11 12RUN apt-get install -y openjdk-8-jdk zipalign apksigner 13 14# XServer-XSDL-1.20.51支持ndk22版本, 更新ndk版本时,需要修改对应的名称 15RUN mkdir -p /Android/Sdk/ndk/ && wget https://dl.google.com/android/repository/android-ndk-r22b-linux-x86_64.zip && unzip android-ndk-r22b-linux-x86_64.zip -d /Android/Sdk/ndk/ 16ENV NDK_PATH=/Android/Sdk/ndk/android-ndk-r22b 17# 设置环境变量,系统生效,NDK_PATH环境变量用来获取ndk版本 18RUN echo "NDK_PATH=$NDK_PATH\nPATH=\"$NDK_PATH:$PATH\"" >> /etc/bash.bashrc

注:

  • 当前xserver-xsdl版本支持ndk23编译

3. 启动编译环境

几个建议:

  • 将home目录映射至容器中,容器中的用户名即可与主机用户名相同,也可以统一为xsdl,只需确保用户名和用户组的id与主机一致

  • 源代码可放在用户的home目录下,Android的SDK也可以放在用户home目录下

  • 第一次进入容器后,添加用户。首先在主机上使用id命令找到用户名和用户组的id,然后在容器中指定id添加用户:

    • 假设主机上的用户组id为1000,则使用groupadd -g 1000 xsdl添加xsdl用户组

    • 假设主机上的用户名id为1000,则使用useradd -s /bin/bash -u 1000 -g xsdl xsdl

    • 使用su xsdl切换至xsdl用户

可创建一次性容器(docker run --rm -it -v $HOME:/home/xsdl -w /home/xsdl xserver-xsdl.docker /bin/bash),每次都执行以上步骤

也可生成一个命名容器(docker run -it -v $HOME:/home/xsdl -w /home/xsdl xserver-xsdl.docker --name user-defined-name-docker /bin/bash),执行一次以上步骤,下次使用docker start -i user-defined-name-docker进入容器,只需执行切换用户名即可

或者直接使用指定的uid和gid登录(docker run --rm -it  -u `id -u`:`id -g` -v $HOME:/home/xsdl -w /home/xsdl xserver-xsdl.docker  /bin/bash)则不需要上述操作.

4. 编译源代码

  1. 下载Android SDK,建议使用Android Studio下载,SDK的API级别为30(Android 11),参见SDK 平台。宿主机必须为x86_64环境

  2. 删除文件名包含非ASCII码的文件,编译环境不支持非ASCII文件名,运行一次即可,需要root权限,命令(rm -f project/jni/application/xserver/xserver/host-build/data/usr/lib/ssl/certs/NetLock_Arany_*.pem)

  3. 设置SDK根目录ANDROID_SDK环境变量,默认在$HOME/Android/Sdk

  4. 按照如下脚本执行,(需要跑多次,一次很难成功,原因未知)

1#!/bin/bash 2 3# 默认情况下,使用android-studio下载的sdk在此目录下 4ANDROID_SDK=$HOME/Android/Sdk 5 6if [ ! -L project/licenses ]; then 7 rm -f project/licenses 8 OLD_PWD=`pwd` 9 cd "${ANDROID_SDK}"/tools/bin/ 10 ./sdkmanager --update 11 ./sdkmanager --licenses 12 cd "${OLD_PWD}" 13 ln -s "${ANDROID_SDK}"/licenses project/ 14fi 15 16# 环境变量NDK_PATH,容器镜像中下载了ndk,并定义了NDK_PATH环境变量 17NDK_VERSION=`grep -w Pkg.Revision "$NDK_PATH/source.properties" | awk -F= '{print $2}' | awk '$1=$1'` 18# 替换ndk版本号 19sed -i 's/ndkVersion.*$/ndkVersion "'$NDK_VERSION'"/' project/app/build-template.gradle | grep ndk 20 21# 指定ndk.dir,否则报错 22if [ `grep -c ndk.dir changeAppSettings.sh` -eq 0 ]; then 23 sed -i '/proguard.config=proguard.cfg/a\echo "ndk.dir='$NDK_PATH'" >> project/local.properties' changeAppSettings.sh 24fi 25 26#只编译arm64-v8a 27AndroidAppSetting=project/jni/application/xserver/AndroidAppSettings.cfg 28sed -i "s/MultiABI.*$/MultiABI='arm64-v8a'/" $AndroidAppSetting 29 30./build.sh xserver

注:XServer-XSDL-1.20.51支持ndk22版本,其它版本编译会出现问题