4.1.1 构建XServer-xsdl编译环境和代码库
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编译环境,可用下面脚本删除相关文件:
#!/bin/bash
UNUSE_CPU_LIST="armeabi-v7a x86 x86_64"
for CPU in ${UNUSE_CPU_LIST} ;do
find project -name "${CPU}" -exec rm -rf {} \; 2>/dev/null
find project -name "tmp-${CPU}" -exec rm -rf {} \; 2>/dev/null
done
在构建git代码库时,可以忽略以下文件
# .gitignore
project/jni/application/xserver/libapplication-*.so
project/jni/application/xserver/AndroidData/bin-map.zip
project/jni/application/xserver/AndroidData/lib/
project/.gradle/
project/.knownPackages
project/app/build.gradle
project/app/build/
project/assets/
project/build-tools/
project/build/
project/emulator/
project/jni/Settings.mk
project/jni/application/xserver/gfx-arm64-v8a.o
project/jni/application/xserver/main-arm64-v8a.o
project/jni/openssl/include/
project/jni/openssl/lib-arm64-v8a/
project/jni/openssl/lib-armeabi-v7a/
project/jni/openssl/lib-x86/
project/jni/openssl/lib-x86_64/
project/lib
project/libs/
project/licenses
project/local.properties
project/obj/local/
project/patcher/
project/platform-tools/
project/platforms/
project/proguard-local.cfg
project/res/drawable/banner.png
project/res/raw/xsdl.raw
project/res/values-es/
project/res/values-fr/
project/res/values-ru/
project/res/values-uk/
project/res/values-zh/
project/res/values/strings.xml
project/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 . 若镜像存在,可省略该步。
#xserver-xsdl.docker
FROM ubuntu:22.04
RUN apt-get update
RUN apt-get install -y apt-utils
RUN apt-get install -y bison file wget
RUN apt-get install -y make zip pkg-config curl autoconf automake autopoint libtool libtool-bin help2man texinfo intltool
RUN apt-get install -y xfonts-utils xutils-dev libfontenc-dev libxkbfile-dev libxmuu-dev libxfont-dev
RUN apt-get install -y libjpeg-dev libpng-dev libpixman-1-dev libssl-dev libpciaccess-dev
RUN apt-get install -y openjdk-8-jdk zipalign apksigner
# XServer-XSDL-1.20.51支持ndk22版本, 更新ndk版本时,需要修改对应的名称
RUN 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/
ENV NDK_PATH=/Android/Sdk/ndk/android-ndk-r22b
# 设置环境变量,系统生效,NDK_PATH环境变量用来获取ndk版本
RUN 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. 编译源代码
下载Android SDK,建议使用Android Studio下载,SDK的API级别为30(Android 11),参见SDK 平台。宿主机必须为x86_64环境
删除文件名包含非ASCII码的文件,编译环境不支持非ASCII文件名,运行一次即可,需要root权限,命令(rm -f project/jni/application/xserver/xserver/host-build/data/usr/lib/ssl/certs/NetLock_Arany_*.pem)
设置SDK根目录ANDROID_SDK环境变量,默认在$HOME/Android/Sdk
按照如下脚本执行,(需要跑多次,一次很难成功,原因未知)
#!/bin/bash
# 默认情况下,使用android-studio下载的sdk在此目录下
ANDROID_SDK=$HOME/Android/Sdk
if [ ! -L project/licenses ]; then
rm -f project/licenses
OLD_PWD=`pwd`
cd "${ANDROID_SDK}"/tools/bin/
./sdkmanager --update
./sdkmanager --licenses
cd "${OLD_PWD}"
ln -s "${ANDROID_SDK}"/licenses project/
fi
# 环境变量NDK_PATH,容器镜像中下载了ndk,并定义了NDK_PATH环境变量
NDK_VERSION=`grep -w Pkg.Revision "$NDK_PATH/source.properties" | awk -F= '{print $2}' | awk '$1=$1'`
# 替换ndk版本号
sed -i 's/ndkVersion.*$/ndkVersion "'$NDK_VERSION'"/' project/app/build-template.gradle | grep ndk
# 指定ndk.dir,否则报错
if [ `grep -c ndk.dir changeAppSettings.sh` -eq 0 ]; then
sed -i '/proguard.config=proguard.cfg/a\echo "ndk.dir='$NDK_PATH'" >> project/local.properties' changeAppSettings.sh
fi
#只编译arm64-v8a
AndroidAppSetting=project/jni/application/xserver/AndroidAppSettings.cfg
sed -i "s/MultiABI.*$/MultiABI='arm64-v8a'/" $AndroidAppSetting
./build.sh xserver
注:XServer-XSDL-1.20.51支持ndk22版本,其它版本编译会出现问题