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压缩后执行总是出现段错误,所以直接放弃了。



  • 老铁,写的可以啊


Log in to reply
 

走马观花

最近的回复

  • Z

    我按照楼主说的,除了windeployqt以外,还需要Qt\labs\folderlistmodel,QtQuick\Layouts,QtQuick\VirtualKeyboard,QtQuick.2,platforminputcontexts这么几个目录,另外Qt5Qml.dll, Qt5Quick.dll也要加进来,还是不行,楼主可以发个完整的文件夹给我吗,release模式的,debug模式没问题

    read more
  • 1.jpg

    简介

    USD全称是“Universal Scene Description”,它主要着力的是电影、游戏复杂制作的流程的规范化。这回我们主要来研究USD在Maya中有关渲染部分究竟是如何实现的。

    USD通过附属的子项目Hydra来实现在其工具“UsdView”以及Maya中渲染方面的实现。Hydra是一款经过多年锤炼的渲染引擎(据说自从2012年就开始研发),Hydra与Maya中有关渲染的结合得益于Maya支持第三方渲染框架通过它提出的“Viewport (1.0、2.0)”方式支持。

    初探

    我们打开USD项目,会发现它有很多子项目。其中包含了imaging和usd子项目。这里我们主要关注的是imaging项目。由单词意思可知,其主要关注的是产出图片的,也就是有关渲染的。
    ca7ce8ff-7e7d-4ec3-9246-fbee48109c7b-image.png

    有关Hydra是三个子项目。包含了hdSt、hdStream以及hdx。我们主要关注的是hdSt。因为这个项目是和OpenGL渲染密切相关的。由于OpenGL是做渲染的大家通用知识,因而它是我们关注的主要子项目。

    调试

    调试.jpg
    我们调试这部分代码,截了此图。我们在图中至少发现几个问题:

    Maya底层是用OpenSceneGraph(OSG)管理场景的。我们可以看到Maya 2018的文件夹里有很多OSG开头的动态链接库,这么说具体视口渲染的部分都是建立在OSG上的。Maya的Viewport 2.0也是建立在OSG上的。在可见的将来它们不会替换掉OSG。

    USD的Hydra和Maya结合的类叫做UsdMayaGLBatchRenderer。由名字可知,它仅工作在OpenGL下,换句话说,如果Maya使用的是DirectX11进行渲染的,那么它将会失效。
    d7063ec4-242e-40bd-bf05-5103c38fedf1-image.png

    libhd项目只是一个前端库,后端通过libhdx以及libhdSt来实现。尤其是libhdSt,它主要是和OpenGL打交道的。它十分复杂。主要基于的是OpenGL 3.3+,也就是包含了各种着色器以及高级栅格化技术,并且整合了网格细分库:OpenSubdiv。

    后续

    由于我们的研究方向是思考一个方式来让让Hydra支持过程化纹理,因此我们还需要继续对此进行研究。

    read more
  • 最近我开始在Maya工作啦。Maya是一款优秀的三维软件,可以处理布景、建模、纹理、装备、渲染等操作。而且它可以支持C++和Python的开发。文档也是非常多的(参考这里)。

    我们最近的工作呢,是想要利用Maya的资源,尤其是图片资源,来制作新的界面。由于Maya是基于Qt开发的,因此要获取图片资源,除了Maya文件夹里D:\Develop\Autodesk\Maya2018\icons文件之外,还需要从资源文件中获取到。而资源文件一般是编译成C++代码放在程序的某个位置了,所以我们一般是看不到的。我们就开始想,既然Maya能够成功地读取并且显示,我们通过Maya的插件开发,不也能够获取并且显示到需要的图标吗?由于Qt的经验,我开始研究通过写Maya插件来获取到Maya资源文件的方法。

    新打开Maya软件,点击右下角的脚本图标,我们开始输入脚本:
    ad141613-63a5-4a93-9b79-3d6ca44da782-image.png

    2、我们通过Qt for Python来从Maya中获取到图标信息。由于Maya是构建在Qt 5.6.1上的,当时还不叫Qt for Python,而是PySide2。当然用法也是差不多的。更重要的是Qt 5.6.1已经支持QML了,可以支持QML的基本绘图方法。所以我们打算结合Qt for Python和QML来实现相关的功能。其实这样一组合就和Maya没有什么关系了。剩下的都是Qt的技术。
    我们的脚本是这样的:

    from PySide2.QtQuick import QQuickView from PySide2.QtCore import QDir, QFileInfo, QUrl def getMayaResourceFileList( nameFilter ): dir = QDir( ":/" ) return dir.entryList( nameFilter ) view = QQuickView( ) view.setResizeMode( QQuickView.SizeViewToRootObject ) mainUrl = QUrl.fromLocalFile( "C:/Users/huawei/Documents/ImageGridView.qml" ) view.setSource( mainUrl ) view.show( ) rootItem = view.rootObject( ) if rootItem != None: rootItem.setProperty( "prefix", "qrc:/" ) rootItem.setProperty( "model", getMayaResourceFileList( '*.png' ) )

    其中C:/Users/huawei/Documents/ImageGridView.qml是我本地的路径,可以改为任意的路径甚至是http路径呢。

    我们还得完成ImageGridView.qml文件内容,其实也非常简单,大概是这样的: import QtQuick 2.6 GridView { id: root width: 320 height: 480 cellWidth: 80 cellHeight: 80 delegate: Image { width: 80 height: 80 source: root.prefix + modelData Text { anchors { left: parent.left right: parent.right bottom: parent.bottom } text: modelData wrapMode: Text.Wrap } } model: 40 property string prefix }

    22ae8472-0bb3-4342-ae72-e1cb54bd87a7-image.png

    4、这些文件准备就位了!我们打开一下Maya软件,看看结果~
    f430332d-c824-47d3-8d1c-b17b3c53bc97-image.png
    它是一个可滑动的界面,每行显示4列,然后下面是文字的内容,展示了图标的名称。我们可以借此工具拿到我们感兴趣的图标的路径,然后应用到我们制作的界面上。其实,如果你觉得图片好,也可以通过QImage以及QPixmap给转存出去自己用。

    如果你觉得文章很棒,记得点赞哦。

    read more

关注我们

微博
QQ群











召唤伊斯特瓦尔