flatpak——Hello World



  • 哈哈,最近论坛新鲜事好多呀!我也来凑凑热闹。
    原文参考: https://blog.csdn.net/qq_32768743/article/details/80024622

    前言

    deepin自从宣布全力支持flatpak后,我研究flatpak很久了,一直没有什么进展。最近重新学了不少东西,整理一下,写下这篇文章。我的环境是Deepin 15.5。学习flatpak,官网和官网文档肯定是第一手资料。印象中flatpak的官网都改版了几次了。如果使用ubuntu,安装官方文档的指引,完成Building Your First Flatpak肯定是毫无压力的。可是,deepin毕竟是带有中国特色的linux发行版,总会有些不可思议的存在的。首先来尝试一下,各种花式Hello World。在正式开始之前,需要做一些准备工作,安装一些依赖。

    sudo apt install flatpak flatpak-builder deepin-fprt-com.deepin.platform-15.5 deepin-fprt-com.deepin.sdk-15.5
    

    这些依赖并不小,需要一段时间。为了方便后面使用,先添加一个仓库

    flatpak --user remote-add --no-gpg-verify --if-not-exists tutorial-repo tutorial-repo
    

    下面所有的操作都是在/home/pikachu/flatpak文件夹下进行的。

    Shell版

    这个版本的Hello World就是执行一个shell脚本,使用echo命令输出一行Hello World。代码很简单,脚本如下

    hello.sh

    #!/bin/bash
    echo "Hello World"
    

    把这个文件命名为hello.sh,给予执行权限,偷个懒,命令就是chmod 777 hello.sh。接着还有一个json文件,内容如下

    cn.net.pikachu.Hello.json

    {
        "app-id":"cn.net.pikachu.Hello",
        "runtime":"com.deepin.Platform",
        "runtime-version":"15.5.2",
        "sdk":"com.deepin.Sdk",
        "command":"hello.sh",
        "modules":[
            {
                "name":"hello",
                "buildsystem":"simple",
                "build-commands":[
                    "install -D hello.sh /app/bin/hello.sh"
                ],
                "sources":[
                    {
                        "type":"file",
                        "path":"hello.sh"
                    }
                ]
            }
        ]
    }
    

    把这个文件命名为cn.net.pikachu.Hello.json,姑且先不管各个项是什么含义,继续进行构建。于是,在同一个文件夹下,有cn.net.pikachu.Hello.jsonhello.sh两个文件。执行构建命令

    flatpak-builder --repo=tutorial-repo hello cn.net.pikachu.Hello.json
    

    这里写图片描述
    接着,安装,运行

    flatpak --user install tutorial-repo cn.net.pikachu.Hello
    flatpak run cn.net.pikachu.Hello
    

    这里写图片描述
    最后,可以打一个包,当别人使用时,就可以非常简单的安装了。

    flatpak build-bundle tutorial-repo hello.flatpak cn.net.pikachu.Hello
    

    这里写图片描述
    再次安装时,可以简单的使用flatpak install hello.flatpak就OK。

    小结

    Hello World只是开胃小菜,真正的好戏还在后面。
    有一个地方,我一直很疑惑。注意到modules.sources.path的值是一个字符串,如果我有多个文件,该怎么在json文件中写呢?试过把path的值改为数组,报错了。

    C++ 版

    c++版就是使用cmake作为构建工具,输出一个简单的Hello World.

    CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    
    project(hello_cmake)
    add_executable(${PROJECT_NAME} "main.cpp")
    set(CMAKE_INSTALL_PREFIX /usr)
    install(TARGETS hello_cmake DESTINATION bin)
    

    这里需要注意的是,写了一个set(CMAKE_INSTALL_PREFIX /usr),在flatpak构建时,要求把可执行文件放在/app/bin,所以可以看到后面用sed做了替换。

    cn.net.pikachu.cmake.Hello.json

    {
        "app-id":"cn.net.pikachu.cmake.Hello",
        "runtime":"com.deepin.Platform",
        "runtime-version":"15.5.2",
        "sdk":"com.deepin.Sdk",
        "command":"hello_cmake",
        "finish-args":[
        "--share=ipc",
        "--socket=x11",
        "--socket=pulseaudio",
        "--share=network",
        "--device=dri",
        "--filesystem=home"
        ],
        "modules":[
            {
                "name":"hello",
                "no-autogen":true,
                "sources":[
                    {
                        "type":"git",
                        "url":"file:///home/pikachu/flatpak/hello_cmake",
                        "branch":"master"
                    },
                    {
                        "type":"script",
                        "commands":[
                            "sed -i 's|/usr|/app|g' CMakeLists.txt",
                            "cmake ."
                        ],
                        "dest-filename":"configure"
                    }
                ]
            }
        ]
    }
    

    小结

    多个文件,我一直不知道该怎么弄。后来在Deepin论坛上,看到有人做的一个图形化打包界面,了解后发现是依赖Git工作的。这里,我也是依赖Git完成的。

    Qt 版

    Qt版的Hello World,就是显示一个简单的对话框,在对话框中间显示Hello World。最后,稍微接触一下Deepin开发的dxcb插件。

    一梭子命令

    有了前面的经验,再一次构建就非常快了。

    flatpak-builder --repo=tutorial-repo hello cn.net.pikachu.qt.Hello.json --force-clean 
    flatpak --user install tutorial-repo cn.net.pikachu.qt.Hello
    flatpak run cn.net.pikachu.qt.Hello
    
    

    cn.net.pikachu.qt.Hello.json

    {
        "app-id":"cn.net.pikachu.qt.Hello",
        "runtime":"com.deepin.Platform",
        "runtime-version":"15.5.2",
        "sdk":"com.deepin.Sdk",
        "command":"hello",
        "finish-args":[
            "--socket=x11",
            "--device=dri"
        ],
        "modules":[
            {
                "name":"hello",
                "no-autogen":true,
                "sources":[
                    {
                        "type":"git",
                        "url":"file:///home/pikachu/flatpak/hello_qt",
                        "branch":"master"
                    },
                    {
                        "type":"script",
                        "commands":[
                            "sed -i 's|/usr|/app|g' deepin-voice-recorder.pro",
                            "qmake PREFIX=/app"
                        ],
                        "dest-filename":"configure"
                    }
                ]
            }
        ]
    }
    

    代码: https://download.csdn.net/download/qq_32768743/10363976
    其实代码不重要,随便搭建一个GUI界面就行了。重点在于怎么用flatpak的manfest文件。
    这里写图片描述
    这里写图片描述
    需要注意的是,Deepin的Runtime是自带Qt的,看到About Qt中,Qt的版本居然是5.9。在自己的机器上,Deepin仓库里Qt的版本是5.6.1。在flatpak中,也是可以使用Deepin的dxcb插件的。
    主要有两点,一是使用DApplication::loadDXcbPlugin();;二是把QApplication换成DApplication。修改代码如下

    #include "dialog.h"
    #include <QApplication>
    #include <DApplication>
    #include <DLog>
    #include <QtCore>
    DWIDGET_USE_NAMESPACE
    DCORE_USE_NAMESPACE
    int main(int argc, char *argv[])
    {
        DLogManager::registerConsoleAppender();
        auto flag = DApplication::loadDXcbPlugin();
        qDebug()<<"load dxcb plugin"<<flag;
        DApplication a(argc, argv);
        a.setTheme("light");
        Dialog w;
        w.show();
    
        return a.exec();
    }
    
    

    这里写图片描述

    小结

    Qt GUI程序设计是使用flatpak的大头,现在deepin已经把很多应用迁移到flatpak上去了,我也计划把我的一个小工具用flatpak打包。

    谈一谈自己的一点想法

    从3个Hello World的构建来看,前面的信息都差不多,最主要的一个地方就是modules怎么去写,我相信,这也就是flatpak解决linux原有的版本问题的一种方式。当依赖变得复杂的时候,该怎么办?这将是下一次需要考虑的问题。在Hello World的例子中,暂且不管。但不管怎么样,首先是要对已有的命令,工具熟悉。新的工具总是或兼容、或依赖、或改进已有的工具的。无论是deb打包也好,flatpak打包也好,首先要做的是把软件开发好,把依赖梳理好,然后再根据相应的规则打包,对外发布。

    就目前的情况,也看不出flatpak什么奇特的地方。反而很晕,为什么弄这么复杂呢?还有很多新的概念。就目前关于flatpak的信息,也非常少。



  • 还有延迟加载,好棒



  • Flatpak是一种Linux的打包方案吗?同时我也看到了Linux有AppImage等解决方案,当然这些解决方案可能有这样或者那样的问题,我们也是根据自己项目的应用情况,选择性地使用这些方案吧。
    此外linuxdeployqt这个是AppImage团队做出的一个独立运行的软件,它的作用和windeployqt类似,是打包Linux应用程序到AppImage的。



  • 是的
    red hat的flatpak和ubuntu的snap是两个现在比较火的打包方式
    AppImage由于自身存在一些问题,没有大公司支持



  • @jiangcaiyang linux下有Qt GUI程序有什么比较好的发布方法吗?



  • 关注一波



  • @大黄老鼠 我觉得也没有太多的打包方法,虽然AppImage我尝试过,但是有一个问题,就是沙箱机制也许不是我想要的。有些应用需要保存配置文件的,如果被AppImage封装,配置文件就无法读取了,又是重新一个实例。这非常让人沮丧。比如说用AppImage打包的软件“Krita”就是如此。我目前采用的方法就是静态编译所有的库,成为一个standalone文件,这样就可以了。

    另:本来也想用upx进行压缩的,可惜upx压缩后执行总是出现段错误,所以直接放弃了。



  • 老铁,写的可以啊


 

走马观花

最近的回复

关注我们

微博
QQ群











召唤伊斯特瓦尔