在 Ubuntu 24.04 上构建玲珑应用
Qt based 应用玲珑化编译构建
在完成前面运行演示之后,我们即将开始展示 Qt based 应用玲珑化编译构建 的效果,这里的完整解释是以Qt5运行库为核心运行库的应用及其源码。我们这里选取 LibreCAD
.
对于一般图形化应用而言,一套良好的体验应当还包括desktop文件以及图标文件,这样以保证普通用户可以通过启动器启动应用。
* 直接通过玲珑编译源码前,你应该先在相同环境的宿主机中成功编译一次以确保可行性并保存相关构建规则
材料要求
因此,本次案例中将会用到以下文件:
- 需要编译安装到玲珑容器的应用
LibreCAD
源码 - 案例应用的图标文件
- 案例应用的 desktop文件
知识点预习
在对源码进行编译工作前,我们需要知道以下知识点:
- 玲珑构建工程在进行编译、运行任务时,实际路径将会被定向为
容器目录
而不是宿主机目录. - 在玲珑生态中,目前由
org.deepin.Runtime
负责提供大部分运行库如boost
等,包含了include头文件
与动态运行库
.在容器中映射目录为/runtime/include
,/runtime/lib
等,内容均在/runtime
中 - 在玲珑生态中,目前由
org.deepin.foundation
负责提供基本运行环境
,包含了include头文件
与动态运行库
.在容器中映射目录为/usr/include
,/usr/lib
等,路径与宿主机规则保持一致
根据上面的信息,我们知道玲珑构建工程在执行构建、运行任务时,include头文件与lib动态运行库会分布在两个目录 /runtime
/usr
中,这个知识点对于后续的编译操作至关重要.
准备工作
由于玲珑构建工具内对于tar归档压缩包解压功能仍存在,以及方便后续根据编译情况动态修改源码。因此我这里建议在项目build之前提前将源码解压到项目内并准备好其他的材料
为了节省时间,我这里已经将上述文件准备完毕、源码也一并解压完成,给大家展示几个重要目录的结构
构建目录结构:
ziggy@ziggy-Standard-PC:~/linglong-build$ tree -L 2
.
├── linglong.yaml
├── org.librecad.www-2.2.0.8-src.tar.bz2
├── src
│ └── org.librecad.www-2.2.0.8-src
├── template_app
│ ├── applications
│ └── icons
└── template_app.tar.bz2
图标、desktop文件资源目录结构(template_app):
template_app/
├── applications
│ └── org.librecad.www.desktop
└── icons
└── hicolor
├── 128x128
│ ├── apps
└── librecad.png
在整个过程中,我们需要重点关注两个需要改动的文件:
desktop文件。
Exec字段必须匹配玲珑项目构建后的路径、应用id、执行命令一致,执行命令与下文提及的yaml配置文件中的”command”值保持一致。
案例yaml配置文件中的**”command”**值:
command:
- /opt/apps/org.librecad.www/files/bin/start.sh
Icon字段考虑到目前在不同发行版上存在兼容性差异,因此这里建议直接填写绝对路径否则有可能不显示图标
可供参考的目录路径:
## desktop应用启动文件Exec
Exec=/opt/apps/$id/$version/files/bin/start.sh
## 应用Icon目录
Icon=/var/lib/linglong/layers/main/$id/$version/x86_64/binary/entries/share/icons/hicolor
需要注意的两个点:
- 一般情况下hicolor目录下存放了不同尺寸的图标文件,建议在选择合适的尺寸后在desktop应用启动文件的Icon字段中填入具体图标文件的路径
- 此处的**id∗∗代指玲珑应用的id,∗∗version**代指玲珑应用的已安装版本号,需要填写具体的实际值
[Desktop Entry]
Name=LibreCAD
Comment=A professional CAD System.
Exec=/opt/apps/org.librecad.www/files/bin/start.sh %U
Icon=/var/lib/linglong/layers/main/org.librecad.www/2.2.0.8/x86_64/binary/
files/share/icons/hicolor/128x128/apps/librecad.png
Type=Application
Categories=Graphics;Engineering;
MimeType=image/vnd.dxf;
Terminal=false
StartupNotify=true
编译工程评估 & 运用
在开始制定合适的编译规则(build)以及配置文件linglong.yaml前,我们需要根据源码工程结构来判断我们应该使用什么类型的构建规则.
对于核心运行库为Qt的应用来说,常用的编译配置生成工具是 cmake
、qmake
.
我们进入解压之后的应用源码目录,可以看到源码根目录内只包含了Qt工程的 .pro
文件而并不存在 CMakeLists.txt
或 Makefile
等其他构建配置文件,因此我们可以迅速得出结论,编译该工程时流程应该为:qmake生成配置文件 ==> make编译 ==> make install
由于qmake指定PREFIX变量对本工程不生效,因此在编译二进制之后我们需要在build规则中手动写入操作以确保所有相关文件可以写入玲珑容器的 $PREFIX
中
yaml配置文件。
我们现在看到玲珑构建配置文件 linglong.yaml
,由于我们本次编译需要用到include头文件以及部分第三方库,因此在默认的base设置外,我们需要在yaml中添加 org.deepin.Runtime
作为 runtime项目
使用.
在build阶段的构建规则,参考我们前面总结的编译顺序,可以在规则中依次设置不同的操作: 进入源码目录 ==> 依次执行编译 ==> 安装操作 ==> 生成启动脚本
在构建规则修改完成后,我们执行一边构建操作看看是否可以正常完成编译操作.
可以看到,当我们执行 ll-builder build -v
后,最后的报错提示为 Project ERROR: Boost installation not found.
,意思是无法找到系统中的 boost
库.但当我们进入前文提到的两个目录 /usr/lib
/runtime/lib
/usr/include
/runtime/include
中搜索 boost
相关库时,却可以找到相关的头文件以及动态运行库.
ziggy@ziggy-Standard-PC:/project$ ls /usr/include/ |grep boost
ziggy@ziggy-Standard-PC:/project$ ls /runtime/include/ |grep boost
boost
ziggy@ziggy-Standard-PC:/project$ ls /usr/lib/x86_64-linux-gnu/ |grep boost
libboost_regex.so.1.74.0
但考虑到上游源码并非完全适配玲珑结构,有可能编译配置文件仅考虑到了宿主机本地编译的场景或者其他符合目录规范的场景,若某库出现在了不是传统的路径中则有可能无法识别到.
此时我们依次进入源码各级子目录,可以看到 boost
库相关的一个配置文件 boost.pri
,我们打开文件,使用编译的报错来搜索,发现报错提示信息是由该文件判断并输出.
往细节分析,我们看到该报错原因是无法找到既定目录下 boost
库的头文件,根据上下文源码关系,我们看到一个变量 BOOST_DIR
暂时判断该变量定义了 boost
库的目录.
可以看到,该变量中搜索路径有 /usr
/usr/local
,这更加印证了我们的猜测,根据该结构规律以及 boost
的头文件目录在玲珑容器中是 /runtime/include
,我们这里将 /runtime
添加到搜索路径中使得编译程序可以读取 boost
头文件所在目录.
Origin:
BOOST_DIR = $$findBoostDirIn( /usr /usr/local /usr/pkg /opt/local )
Fixed:
BOOST_DIR = $$findBoostDirIn( /usr /usr/local /usr/pkg /opt/local /runtime )
模板linglong.yaml变量解释:
需替换变量 | 解释 |
---|---|
LL_APPID | 玲珑应用id |
LL_NAME | 玲珑应用名 |
LL_VERSION | 玲珑应用版本 |
临时测试
修改完源码后,我们重新编译构建一次查看效果.
最终测试通过编译,我们可以退出容器来根据我们的操作记录来修改构建规则,并重置构建目录来通过 ll-builder build
按构建规则执行任务.
在构建完成后,我们在项目目录执行调试看看是否正常运行
ziggy@ziggy-Standard-PC:~/linglong-build$ ll-builder run
发表回复