PageSourceSearch

https://docs.flathub.org/assets/js/bc909ca1.3001b082.js

js flathub.org collected 2026-09-24 08:38:07 UTC 13,780 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkflathub_docs_docusaurus=globalThis.webpackChunkflathub_docs_docusaurus||[]).push([[5659],{8678(e,n,t){t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"for-users/rebuilding","title":"Rebuilding a Flatpak from published sources","description":"flathub-repro-checker","source":"@site/docs/01-for-users/10-rebuilding.md","sourceDirName":"01-for-users","slug":"/for-users/rebuilding","permalink":"/docs/for-users/rebuilding","draft":false,"unlisted":false,"editUrl":"https://github.com/flathub/documentation/tree/main/docs/01-for-users/10-rebuilding.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{},"sidebar":"mainSidebar","previous":{"title":"Modifying default permissions","permalink":"/docs/for-users/permissions"},"next":{"title":"Slow connection to Flathub","permalink":"/docs/for-users/slow-connection"}}');var s=t(4848),i=t(8453);const r={},o="Rebuilding a Flatpak from published sources",l={},c=[{value:"Notes",id:"notes",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"rebuilding-a-flatpak-from-published-sources",children:"Rebuilding a Flatpak from published sources"})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"https://github.com/flathub-infra/flathub-repro-checker",children:"flathub-repro-checker"}),"\nchecker can be used to check reproducibility of apps published on\nFlathub."]})}),"\n",(0,s.jsxs)(n.p,{children:["Most of the time, if you want to rebuild a Flaptak from Flathub, you can\ngo to the ",(0,s.jsx)(n.a,{href:"https://github.com/flathub",children:"Flathub organization on GitHub"}),",\nfind the repository for the application that you want to rebuild, clone\nit and then follow the ",(0,s.jsx)(n.a,{href:"https://docs.flatpak.org/en/latest/first-build.html",children:"Building your first Flatpak"}),"\nsteps from the Flatpak documentation. But let's say that you want to\nrebuild a specific version of the Flatpak exactly as it was published\non Flathub, for example, to verify that the build is reproducible."]}),"\n",(0,s.jsxs)(n.p,{children:["In this guide, we will describe the process of doing that. This is\nequivalent to downloading an ",(0,s.jsx)(n.code,{children:"SRPM"})," and rebuilding the RPM from it, but\nfor Flatpaks."]}),"\n",(0,s.jsxs)(n.p,{children:["Let's pick a small Flatpak as an example:\n",(0,s.jsx)(n.a,{href:"https://github.com/flathub/org.kde.minuet",children:(0,s.jsx)(n.code,{children:"org.kde.minuet"})})]}),"\n",(0,s.jsx)(n.p,{children:"Let's first install the latest version from Flathub:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak --user install flathub org.kde.minuet\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We can now find the git commit that was used to build this Flatpak by\nlooking at the ",(0,s.jsx)(n.code,{children:"Subject"})," field in the output of the ",(0,s.jsx)(n.code,{children:"flatpak info"}),"\ncommand:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak info --user org.kde.minuet//stable\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Minuet - Music Education Software\n\n          ID: org.kde.minuet\n         Ref: app/org.kde.minuet/x86_64/stable\n        Arch: x86_64\n      Branch: stable\n     Version: 0.4.0.25042\n     License: GPL-2.0+\n      Origin: flathub\n  Collection: org.flathub.Stable\nInstallation: user\n   Installed: 33,8\xa0MB\n     Runtime: org.kde.Platform/x86_64/6.9\n         Sdk: org.kde.Sdk/x86_64/6.9\n\n      Commit: 1263d36e453073b96beaa15112c4dc8587679a2137da7441aabed305c4a6bc84\n      Parent: 412c1376ef4d002ade6e6c7fb45494a0e7a3f09e2c03d07ebc604bb3f5a17511\n     Subject: Merge pull request #102 from PunkPangolin/patch-1 (b403e3f69e11)\n        Date: 2025-07-01 13:59:17 +0000\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Here it is the commit ",(0,s.jsx)(n.a,{href:"https://github.com/flathub/org.kde.minuet/commit/b403e3f69e11",children:"b403e3f69e11"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"But that does not tell us the exact version and commits of the\nruntime and the SDK that were used to build it. Moreover, the sources\nused to build it may al
1so no longer be accessible from the remote\nservers."}),"\n",(0,s.jsx)(n.p,{children:"So, to fully reproduce the build without relying on external parties, we\nneed to get the processed manifest from the Flatpak and fetch the\nsources from Flathub."}),"\n",(0,s.jsx)(n.p,{children:"The processed manifest is stored in the Flatpak itself:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak run --user --command=/bin/cat org.kde.minuet /app/manifest.json\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n  "id" : "org.kde.minuet",\n  "runtime" : "org.kde.Platform",\n  "runtime-version" : "6.9",\n  "runtime-commit" : "f930fae18cfc829f51db18b9324905a3bebee0ec7e9d4d62afbb17f696fb20d0",\n  "sdk" : "org.kde.Sdk",\n  "sdk-commit" : "3170c974605b5af73a78bef2ae022df9b8dd7496569928a3766f0706c6c6515d",\n  "command" : "minuet",\n  "modules" : [\n    {\n      "name" : "fluidsynth",\n      "buildsystem" : "cmake-ninja",\n      "sources" : [\n        {\n          "url" : "https://github.com/FluidSynth/fluidsynth/archive/refs/tags/v2.4.6.tar.gz",\n          "sha256" : "a6be90fd4842b9e7246500597180af5cf213c11bfa3998a3236dd8ff47961ea8",\n          "x-checker-data" : {\n            "type" : "anitya",\n            "project-id" : 10437,\n            "stable-only" : true,\n            "url-template" : "https://github.com/FluidSynth/fluidsynth/archive/refs/tags/v$version.tar.gz"\n          },\n          "type" : "archive"\n        }\n      ]\n    },\n    {\n      "name" : "minuet",\n      "buildsystem" : "cmake-ninja",\n      "config-opts" : [\n        "-DBUILD_WITH_QT6=ON"\n      ],\n      "sources" : [\n        {\n          "url" : "https://download.kde.org/stable/release-service/25.04.2/src/minuet-25.04.2.tar.xz",\n          "sha256" : "6d01871df0f666fbfc9c84bad6c7146955690e6a37b46738e98058f8a5bfb514",\n          "x-checker-data" : {\n            "type" : "anitya",\n            "project-id" : 8763,\n            "stable-only" : true,\n            "url-template" : "https://download.kde.org/stable/release-service/$version/src/minuet-$version.tar.xz"\n          },\n          "type" : "archive"\n        },\n        {\n          "path" : "mr-37.patch",\n          "type" : "patch"\n        }\n      ]\n    }\n  ],\n  "cleanup" : [\n    "/lib64/pkgconfig",\n    "/include",\n    "/share/man"\n  ],\n  "finish-args" : [\n    "--device=dri",\n    "--share=ipc",\n    "--socket=fallback-x11",\n    "--socket=pulseaudio",\n    "--socket=wayland"\n  ],\n  "rename-icon" : "minuet",\n  "source-date-epoch" : 1321009871\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Notice that this manifest includes the exact commit of the runtime and\nSDk it was built against."}),"\n",(0,s.jsx)(n.p,{children:"Let's store this manifest in a new folder:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"mkdir org.kde.minuet\ncd org.kde.minuet\nflatpak run --user --command=/bin/cat --filesystem=$(pwd) org.kde.minuet /app/manifest.json >manifest.json\n"})}),"\n",(0,s.jsx)(n.p,{children:"Now we install the sources extension of the app from Flathub to obtain\nthe sources referenced in this manifest:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak install --user flathub org.kde.minuet.Sources//stable\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"flatpak info --user org.kde.minuet.Sources\n\n          ID: org.kde.minuet.Sources\n         Ref: runtime/org.kde.minuet.Sources/x86_64/stable\n        Arch: x86_64\n      Branch: stable\n      Origin: flathub\n  Collection: org.flathub.Stable\nInstallation: user\n   Installed: 29,5\xa0MB\n\n      Commit: fdafb56a6e907f87a359c8a048471fc1747291bdcbe0e952ad2d0cf3d66fc0dc\n      Parent: b8d569cd9611b64193264db7bd811e9dd322143fe4f2e438355a8be8dbab291c\n     Subject: Merge pull request #102 from PunkPangolin/patch-1 (b403e3f69e11)\n        Date: 2025-07-01 13:59:16 +0000\n"})}),"\n",(0,s.jsx)(n.p,{children:"The sources extension can now be found in the Flatpak runtime folder:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-console",children:"$ tree ~/.local/share/flatpak/runtime/org.kde.minuet.Sources/x86_64/stable/fdafb56a6e907f87a359c8a048471fc1747291bdcbe0e952ad2d0cf3d66fc0dc/files\n.\n\u251c\u2500\u2500 downloads\n\u2502\xa0\xa0 \u251c\u2500\u2500 6d01871df0f666fbfc9c84bad6c7146955690e6a37b46738e98058f8a5bfb514\n\u2502\xa0\xa0 \u2502\xa0\xa0 \u2514\u2500\u2500 minuet-25.04.2.tar.xz\n\u2502\xa0\xa0 \u2514\u2500\u2500 a6be90fd4842b9e7246500597180af5cf213c11bfa3998a3236dd8ff47961ea8\n\u2502\xa0\xa0     \u2514\u2500\u2500 v2.4.6.tar.gz\n\u2514\u2500\u2500 manifest\n    \u251c\u2500\u2500 mr-37.patch\n    \u2514\u2500\u2500 org.kde.minuet.json\n"})}),"\n",(0,s.jsxs)(n.p,{children:["We first create a ",(0,s.jsx)(n.code,{children:".flatpak-builder"})," folder which should lie alongside\nthe manifest in the same directory. Then we copy the sources\n(",(0,s.jsx)(n.code,{children:"archive"}),", ",(0,s.jsx)(n.code,{children:"git"})," etc.) and place them inside the ",(0,s.jsx)(n.code,{children:".flatpak-builder"}),"\nfolder:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"mkdir -p .flatpak-builder\ncp -a ~/.local/share/flatpak/runtime/org.kde.minuet.Sources/x86_64/stable/fdafb56a6e907f87a359c8a048471fc1747291bdcbe0e952ad2d0cf3d66fc0dc/files/downloads .flatpak-builder\n"})}
1),"\n",(0,s.jsx)(n.p,{children:"The patch file needs to be placed alongside the manifest:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cp ~/.local/share/flatpak/runtime/org.kde.minuet.Sources/x86_64/stable/fdafb56a6e907f87a359c8a048471fc1747291bdcbe0e952ad2d0cf3d66fc0dc/files/manifest/*.patch .\n"})}),"\n",(0,s.jsx)(n.p,{children:"Before we start building the Flatpak with those, we have to make sure\nthat we are using the right commit for the runtime and SDK."}),"\n",(0,s.jsx)(n.p,{children:"We first install the runtime and the SDK:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak --user install flathub org.kde.{Platform,Sdk}//6.9\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then we update them to the commit obtained from the manifest above:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak --user update \\\n      --commit=f930fae18cfc829f51db18b9324905a3bebee0ec7e9d4d62afbb17f696fb20d0 \\\n      org.kde.Platform//6.9\nflatpak --user update \\\n      --commit=3170c974605b5af73a78bef2ae022df9b8dd7496569928a3766f0706c6c6515d \\\n      org.kde.Sdk//6.9\n"})}),"\n",(0,s.jsx)(n.p,{children:"Now we can rebuild the Flatpak using:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"flatpak run org.flatpak.Builder --user --disable-download --repo=repo --force-clean --disable-rofiles-fuse builddir manifest.json\n"})}),"\n",(0,s.jsx)(n.p,{children:"This process can be reproduced for any Flatpak on Flathub and any\nversion of the Flatpak as long as the sources extension is available\nand older versions haven't been pruned."}),"\n",(0,s.jsx)(n.h3,{id:"notes",children:"Notes"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Flathub may periodically prune older versions to keep the Flatpak\nrepository size in check. The last three commits of an app should\nbe available."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["If the manifest has ",(0,s.jsx)(n.code,{children:"git"})," sources, flatpak-builder may try to fetch\nthem from the git remote. If the remote repository is no longer\navailable, the manifest can be edited to replace the ",(0,s.jsx)(n.code,{children:"url"})," of ",(0,s.jsx)(n.code,{children:"git"}),"\nsources with ",(0,s.jsx)(n.code,{children:"file://"})," or ",(0,s.jsx)(n.code,{children:"dir"})," counterparts pointing to the git repo\nobtained from the sources extension."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Flatpak Builder does not pin extensions to an exact commit in the\ngenerated manifest. This can be worked around by inspecting the\nextension repository's git history and copying the corresponding\nbuild recipe from that point into the application manifest."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Flathub uploads the sources extension only from ",(0,s.jsx)(n.code,{children:"x86_64"})," build\npipelines. If a manifest has architecture specific binary sources,\nthe sources of only one architecture will be available. This is not an\nissue for applications that are entirely built from source tarballs or\ngit repos."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453(e,n,t){t.d(n,{R:()=>r,x:()=>o});var a=t(6540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.