Na čem aktuálně pracují vývojáři GNOME a KDE Plasma? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE Plasma.
Byla vydána nová verze 0.4.15 (𝕏) svobodného operačního systému ReactOS (Wikipedie), jehož cílem je kompletní binární kompatibilita s aplikacemi a ovladači pro Windows. Přehled novinek i s náhledy v oznámení o vydání.
Byl představen rpi-image-gen, tj. oficiální nástroj pro vytváření vlastních softwarových obrazů pro zařízení Raspberry Pi.
Byla vydána nová major verze 8.0, aktuálně 8.0.1, softwaru pro správu elektronických knih Calibre (Wikipedie). Přehled novinek v poznámkách k vydání. Vypíchnuta je lepší podpora Kobo KEPUB formátu nebo integrovaný lokálně běžící engine Piper pro převod textu na řeč používaný pro čtení nahlas (již od verze 7.18).
Společnost OpenAI rozšířila své API o nové audio modely. Nový model pro převod textu na řeč (text-to-speech model) lze bez přihlašování vyzkoušet na stránce OpenAI.fm.
Příspěvek Bezpečnost paměti pro webové fonty na blogu Chrome pro vývojáře rozebírá, proč se pro zpracování webových fontů v Chrome místo FreeType nově používá v Rustu napsaná Skrifa z Fontations.
V pátek 21. a v sobotu 22. března proběhnou Arduino Days 2025, tj. každoroční „narozeninová oslava“ platformy Arduino. Na programu je řada zajímavých přednášek. Sledovat je bude možné na YouTube. Zúčastnit se lze i lokálních akcí. V sobotu v Praze na Matfyzu.
Komunitná konferencia Bratislava OpenCamp, ktorá sa uskutoční už o tri týždne 5. 4. 2025 na FIIT STU pozná svoj program – návštevníkom ponúkne 3 paralelné behy prednášok a workshopov na rôzne témy týkajúce sa otvoreného softvéru či otvorených technológií.
Časopis MagPi od nakladatelství Raspberry Pi se s číslem 151 přejmenoval na Raspberry Pi Official Magazine. I pod novým názvem zůstává nadále ve formátu pdf zdarma ke čtení.
Japonská SoftBank Group kupuje firmu Ampere Computing za 6,5 miliardy dolarů. Ampere Computing vyrábí 32-128jádrové procesory Ampere Altra a 192jádrové procesory AmpereOne.
Až příliš praktická ukázka, jak pomocí Flatpaku připravit k distribuci netriviální aplikaci...
Distribuce vlastních aplikací pro Linux dostatečně bezúdržbovým způsobem, který by nevyžadoval aspoň občasnou kontrolu, zda se nezměnilo ABI nějaké knihovny je obecně trochu problematická. Tím hůře, pokud chce člověk cílit na více než pár vybraných distribucí. Dosud jsem to řešil masivně statickými buildy, které si maximum závislostí nesly se sebou v jedné olbřímí binárce. Přístup je to sice možný ale dost pracný už jen proto, že takto uhnětenou binárku je potřeba alespoň na pár cílových distribucích stejně otestovat. Dále je třeba počítat s některými omezeními statických sestavení; typicky třeba GUI aplikace linkované proti statickým Qt působí ve zbytku systému jako pěst na oko, protože nemohou použít systémové stylovací pluginy. Před pár dny jsem jen tak zkusil spustit binárku, co jsem zkompiloval zhruba před dvěma lety. Samozřejmě se to nepodařilo, i když jsem se setsakra snažil udržet množství závislostí na systémových knihovnách na minimu. Můj pokus zkrachoval na knihovnělibgfortran.so.4
, zatímco moje binárka počítala s verzí 3. Protože na ruční udržování balíčků pro různé distribuce nebo pravidelnou kontrolu, která ze závislostí se zase rozbila nemám kapacity, rozhodl jsem se pro další projekt použít odlišný způsob distribuce.
/var/lib/flatpak
(případně ~/.local/share/flatpak
) a běží sandboxované; nemohou tedy nabořit zbytek systému. Díky tomu se autor aplikace navíc nemusí bát, že by jeho balíček s něčím kolidoval.
Ač není základní dokumentace Flatpaku vůbec špatná, omezuje se pouze na triviální ukázku, která je pro sestavení jakékoliv reálné aplikace obtížně použitelná. Dodatečné informace je nutné vylovit „nasyrovo“ z dokumentace a - v nemálo případech - z flatpakových předpisů jiných projektů, ticketů na GitHubu a podobně. Protože ne všechny funkce Flatpaku se chovají úplně intuitivně, napadlo mne shrnout pár svých poznatků ze zhruba jednodenního klopýtání Flatpakovým polem do nějakého zápisku, určitě to budu ještě potřebovat...
Jako případová studie nám poslouží PeakMaster, nástroj pro provádění jistých fyzikálně-chemických simulací. Protože vývoj současné verze i výpočetního podvozku probíhal téměř výhradně na Linuxu (GUI z části na macOS), bylo by docela hloupé, kdyby předkompilovaná binárka existovala jen pro Windows. PeakMaster má v nynější podobně pár exotických závislostí, na kterých je možné ukázat různé možnosti, jak zaflatpakovat netriviální program.
Závislostní strom PeakMasteru vypadá v současné podobě nějak takto:
Eigen a MPFR C++ existují jen jako hlavičkové soubory a žádnou binární podobu nemají, balíčky s LEMNG a ECHMETCoreLibs byste určitě hledali marně a s GNU GMP a MPFR mohou nastat různé nečekané potíže, viz dále. Navíc MPFR nedávno vyšla ve verzi 4.0.0 s jiným ABI; některé distribuce už ji mají, jiné ne. Motivace pro použití Flatpaku je myslím zřejmá.
Zápisek, který si původně dával za cíl ukázat, na jaké praktické problémy je možné při přípravě Flatpakových balíčku narazit předvést pár možných řešení se nakonec zvrhl v de-facto návod, jak kompletně sestavit jistý software cílící na velmi specifickou skupinu uživatelů. Protože jsem bytostný nepřítel abstraktních („mějme aplikaci A závisející na knihovnách L1 až L6“) či umělých („ukážeme si to na aplikaci dummy závisející na knihovnách libfoo a libbar“) tutoriálů, použil jsem příklad z opravdové praxe, kdy jsem musel řešit opravdové problémy. Doufám, že postřehy, nápady a doporučení zde zmíněné jsou použitelné daleko šířeji než produkt, který na konci tohoto zápisku vznikne...
Všechno experimentování jsem prováděl na virtuálním stroji s Fedorou 27 nainstalovanou z netinstallu. Kromě Xfce, Vimu a Flatpaku jsem nemusel instalovat nic dalšího.
Na úplném začátku potřebujeme nainstalovat Flatpak a Flatpak builder. Na Fedoře postačí:
$ dnf install flatpak flatpak-builder
Flatpak během své činnosti vytváří značné množství pracovních souborů, které je určitě vhodné držet na jasně definovaném místě, už jen proto, že umí zabrat docela dost místa. Naším „kořenovým“ adresářem bude /home/flatpak/flatpak_PMNG
Jako první je nutné přidat repozitář, odkud si Flatpak stáhne potřebné runtimy a SDK. To provedeme takto:
$ flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
Dále potřebujeme nainstalovat příslušné SDK, oproti kterému budeme sestavovat naší aplikaci. Seznam SDKček, která jsou momentálně k dispozici v repozitáři flathub je třeba zde. Protože GUI PeakMasteru je napsané v Qt 5, nainstalujeme runtime a SDK pro KDE.
$ flatpak install flathub org.kde.Platform//5.9 org.kde.Sdk//5.9
Všimněte si, že za jménem balíčku je uvedené ještě číslo verze, resp. název větve. Kdybychom jej vynechali, vynadal by nám Flatpak s následující chybou:
error: Multiple branches available for org.kde.Platform, you must specify one of: org.kde.Platform//5.10, org.kde.Platform//5.9
Konzervativně jsem se držel větve 5.9, protože Qt 5.9 má na rozdíl od 5.10 slíbenou dlouhodobou podporu.
Teď máme vše, co potřebujeme pro sestavení zkušebního balíčku. Předpis - či chcete-li manifest, podle kterého Flatpak balíčky sestavuje má formu JSON souboru. Triviální manifest může vypadat třeba takto. My při zkušební jízdě sestavíme ECHMETCoreLibs, protože bez nich se nehneme dál.
Vytvoříme jednoduchý manifest, který stáhne zdrojáky Eigenu a ECHMETCoreLibs a pokusí se je sestavit. Budeme počítat s tím, že manifest dále rozšíříme až do tvaru, který dovede sestavit a zabalit celý PeakMaster. Soubor s manifestem pojmenujeme cz.cuni.natur.echmet.PeakMasterNG.json
a umístíme do adresáře ~/flatpak_PMNG
.
Hlavička manifestu bude vypadat takto:
"app-id": "cz.cuni.natur.echmet.PeakMasterNG", "runtime": "org.kde.Platform", "runtime-version": "5.9", "sdk": "org.kde.Sdk",
app-id
- Unikátní identifikátor balíčkuruntime
- ID runtimu, vůči kterému balíček sestavujemeruntime-version
- Verze runtimusdk
- ID SDKčka
Hlavička dále obsahuje pole modules
, ve kterém jsou uvedeny jednotlivé moduly (jak by určitě nikdo neuhodl) tvořící výsledný balíček. GNU GMP a MPFR jsou již obsaženy v org.kde.Platform, potřebujeme tedy zatím jen Eigen a ECHMETCoreLibs.
Prvek pole modules
zajišťující stažení a „sestavení“ Eigenu lze zapsat třeba následovně:
{ "name": "eigen", "buildsystem": "simple", "build-commands": [ "mkdir -p /app/Eigen", "cp -r Eigen /app/Eigen", "cp -r unsupported /app/Eigen" ], "sources": [ { "type": "archive", "url": "http://bitbucket.org/eigen/eigen/get/3.3.4.tar.bz2", "sha256": "dd254beb0bafc695d0f62ae1a222ff85b52dbaa3a16f76e781dce22d0d20a4a6" } ], "cleanup": [ "/Eigen" ] }
name
- Název modulu, v principu může být libovolný.buildsystem
- Typ nástroje, který balíček sestaví. V případě Eigenu potřebujeme pouze nakopírovat hlavičkové soubory na vhodné místo, použijeme tedy systém simple
.build-commands
- Seznam příkazů provádějících sestavení a instalaci modulusources
- Zdrojové kódy nutné pro sestavení modulu. Eigen je distribuován jako tar archiv, pole sources
bude tedy obsahovat jediný prvek. Jednotlivé položky mají následující význam:
type
- Způsob distribuce zdrojáku, zde archive
.url
- Odkaz na umístění, kde je archiv k dispozici.sha256
- SHA256 kontrolní součet. Je-li zdrojem vzdálené umístění, je nutné kontrolní součet uvést, jinak se balíček nesestaví.cleanup
- Seznam souborů či adresářů, které je možné po sestavení balíčku odstranit.
Jistě jste si všimli, že Eigen se kopíruje do adresáře /app
. Tento adresář je ve Flatpakovém sandboxu vždy přimountovaný a funguje jako de-facto kořenový adresář. Flatpakový sandbox standardně nedovoluje přístup ke skutečnému souborovému systému stroje - s tímto je nutné počítat a sestavovací skripty a aplikaci tomu přizpůsobit. Pozor na to, že Flatpak není s používáním prefixu /app
úplně konzistentní, někdy (většinou) je nutné jej uvést, jindy nikoliv.
Fajn, to bychom měli Eigen, můžeme směle pokročit k sestavení ECHMETCoreLibs. Definice modulu pro ECHMETCoreLibs se liší od té pro Eigen použitím jiného buildsystemu a způsobu, kterým se získá zdrojový kód. ECHMETCoreLibs jsou sestavovány CMakem. Jako buildsystem
tedy uvedeme cmake
a namísto build-commands
použijeme config-opts
. Typ zdroje bude nyní git
, url
bude obsahovat odkaz na příslušný repozitář. Navíc ještě přibude hodnota branch
identifikující gitovou větev, kterou chceme naklonovat. Celá definice vypadá takto:
{ "name": "CoreLibs", "buildsystem": "cmake", "config-opts": [ "-DCMAKE_BUILD_TYPE=Release", "-DEIGEN_INCLUDE_DIR=/app/Eigen", "-DCMAKE_INSTALL_PREFIX=/app", "-DCMAKE_CXX_FLAGS=-g" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/ECHMETCoreLibs.git", "branch": "master" } ], "cleanup": [ "/include" ] }Zkompletovaný manifest jest následující:
{ "app-id": "cz.cuni.natur.echmet.PeakMasterNG", "runtime": "org.kde.Platform", "runtime-version": "5.9", "sdk": "org.kde.Sdk", "modules": [ { "name": "eigen", "buildsystem": "simple", "build-commands": [ "mkdir -p /app/Eigen", "cp -r Eigen /app/Eigen", "cp -r unsupported /app/Eigen" ], "sources": [ { "type": "archive", "url": "http://bitbucket.org/eigen/eigen/get/3.3.4.tar.bz2", "sha256": "dd254beb0bafc695d0f62ae1a222ff85b52dbaa3a16f76e781dce22d0d20a4a6" } ], "cleanup": [ "/Eigen" ] }, { "name": "CoreLibs", "buildsystem": "cmake", "config-opts": [ "-DCMAKE_BUILD_TYPE=Release", "-DEIGEN_INCLUDE_DIR=/app/Eigen", "-DCMAKE_INSTALL_PREFIX=/app", "-DCMAKE_CXX_FLAGS=-g" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/ECHMETCoreLibs.git", "branch": "master" } ], "cleanup": [ "/include" ] } ] }
Zkušební manifest máme připravený, můžeme vyrazit. Build samotný spustíme příkazem:
$ flatpak-builder --repo=PMNG PMNG_pkg cz.cuni.natur.echmet.PeakMasterNG.json --force-clean
--repo=PMNG
- Název lokálního repozitáře udržujícího informace a sestaveném balíčku. Teoreticky není nutný ale balíček by pak nešel exportovat.PMNG_pkg
- Adresář se soubory tvořící Flatpakový balíček.cz.cuni.natur.echmet.PeakMasterNG.json
- Náš manifest.--force-clean
- Není-li adresář PMNG_pkg
prázdný, smaž jeho obsah.
Dopadlo-li všechno dobře, měli bychom v adresář flatpak_PMNG
najít dva nové podadresáře PMNG
a PMNG_pkg
. Nahlédneme-li do PMNG_pkg/files
, měli bychom tam nalézt vše, co vzniklo sestavovacím procesem uvedeným v manifestu. V našem případě půjde o adresář /lib
se čtyřmi knihovnami a příslušnými symlinky. V podadresáři debug
jsou tytéž knihovny ještě jednou, tentokrát všech včetně ladicích symbolů. flatpak_PMNG
by měl ještě obsahovat skrytý adresář .flatpak_builder
kde si builder uchovává cache a stažené zdrojáky.
Úspěšně jsme sestavili úplný základ, můžeme tedy v klidu pokračovat a přidat další z potřebných závislostí. Knihovna LEMNG se sestavuje skoro stejně jako ECHMETCoreLibs, definice modulu je následující:
{ "name": "LEMNG", "buildsystem": "cmake", "config-opts": [ "-DCMAKE_BUILD_TYPE=Release", "-DEIGEN_INCLUDE_DIR=/app/Eigen", "-DECHMET_CORE_LIBS_DIR=/app", "-DCMAKE_INSTALL_PREFIX=/app", "-DCMAKE_CXX_FLAGS=-g" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/LEMNG.git", "branch": "master" } ], "cleanup": [ "/include" ] }
Zde je asi vhodné zmínit, že Flatpak sestavuje moduly v tom pořadí, jak jsou uvedeny v poli modules
. Dále se předpokládá, že modul uvedený v seznamu níže závisí na modulech před ním. Jakákoliv změna v definici modulu způsobí rebuild všech modulů uvedených pod ním.
Až doposud šlo všechno celkem přímočaře. První výmol na cestě můžeme trefit v případě, kdy musíme sestavit nějaký software, jehož sestavovací proces není možné rozumně nakonfigurovat parametry předanými z příkazové řádky. To je případ třeba knihovny Qwt. Ta předpokládá, že ručně upravíme soubor qwtconfig.pri
. Způsobů, jak si poradit, je více. V rámci demonstrace několika možností začneme s variantou kanadského dřevorubce.
$ tar -xvf qwt-6.1.3.tar.bz2
qwt-6.1.3
upravíme soubor qwtconfig.pri
. Zde je potřeba nastavit proměnnou QWT_INSTALL_PREFIX
v sekci unix
takto:QWT_INSTALL_PREFIX = /app
$ tar -cjf qwt-6.1.3_configured.tar.bz2 qwt-6.1.3/
Do modulů v manifestu přidáme následující blok. Protože Flatpak - aspoň co jsem dokázal zjistit - nemá přímou podporu pro qmake, pomůžeme si ručně nastavením buildsystemu na simple
spuštěním buildu tak, jak bychom to udělali z klasické příkazové řádky.
{ "name": "qwt", "buildsystem": "simple", "build-commands": [ "qmake qwt.pro CONFIG+=release", "make -j4", "make install" ], "sources": [ { "type": "archive", "path": "/home/flatpak/flatpak_PMNG/qwt-6.1.3_configured.tar.bz2" } ], "cleanup": [ "/include", "/doc", "/features", "/plugins" ] }
Nalezneme-li v adresáři PMNG_pkg/files/lib
knihovnu libLEMNG.so
a adresář PMNG_pkg/files/qwt-6.1.3/lib
se zkompilovanými Qwt, můžeme si pogratulovat a pokračovat dále.
Teď už máme vše, co potřebujeme, abychom sestavili samotný PeakMaster. Stejně jako Qwt se parametry nutné pro sestavení řeší úpravou konfiguračního souboru, tentokrát PeakMasterNG.pri
. Protože budeme zdrojáky tahat z gitu, nemůžeme předchozí postup použít. Co s tím?
Nejdříve vytvoříme základní definici modulu, od které se odrazíme. Ta vypadá takto:
{ "name": "PeakMasterNG", "buildsystem": "simple", "build-commands": [ "qmake PeakMasterNG.pro CONFIG+=release CONFIG+=flatpak_build", "make -j4", "make install" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/PeakMasterNG.git", "branch": "master" } ] }Flatpak umožňuje pracovat i se zdroji ve formě patchů, čehož zde můžeme šikovně využít. Stačí nám stáhnout příslušný konfigurační soubor. Ten zkopírujeme a kopii upravíme tak, že jeho obsah bude tento:
# Path to location where the ECHMETCoreLibs are installed ECHMET_CORE_LIBS_DIR = "/app" # Path to location where the LEMNG library is insalled LEMNG_DIR = "/app" # Path to where the Qwt toolkit is installed QWT_DIR = "/app" include("$$QWT_DIR/features/qwt.prf") #Do not touch anything below this line! INCLUDEPATH += "$$ECHMET_CORE_LIBS_DIR/include/ECHMET/CoreLibs" INCLUDEPATH += "$$LEMNG_DIR/include/ECHMET/LEMNG" LIBS += -L"$$ECHMET_CORE_LIBS_DIR/lib" -lSysComp -lECHMETShared LIBS += -L"$$LEMNG_DIR/lib" -lLEMNG QMAKE_LFLAGS += -Wl,-rpath-link,"$$ECHMET_CORE_LIBS_DIR/lib"Pomocí
$ diff -u PeakMasterNG.pri PeakMasterNG_mod.pri > PMNG_config.patchvytvoříme konfigurační patch a umístíme jej do
/home/flatpak/flatpak_PMNG/
Do pole sources
modulu PeakMasterNG
přidáme další objekt s tímto obsahem:
{ "type": "patch", "path": "/home/flatpak/flatpak_PMNG/PMNG_config.patch", "strip-components": 0 }Výchozí hodnota
strip-components
je 1, což se nám v tomto případě příliš nehodí.
Spustili bychom teď build, PeakMaster by se měl bez problémů zkompilovat a PMNG_pkg/files/bin/
obsahovat soubor PeakMasterNG
. K tomu, abychom vytvořili skutečně použitelný balíček nám akle ještě malý kousek cesty zbývá. Hlavičku manifestu je třeba doplnit o následující blok:
"command": "PeakMasterNG", "finish-args": [ "--filesystem=host", "--socket=x11", "--socket=wayland", "--socket=pulseaudio", "--device=all", "--share=ipc" ],
command
překvapivě říká, jaký příkaz se při spuštění Flatpakového balíčku provést, my chceme spustit binárku PeakMasterNG
. Pole finish-args
umožňuje vypnout některá omezení sandboxu. --filesystem=host
povolí přístup k celému souborovému systému stroje, kde naše binárka běží. Parametry volby --socket
umožní přístup k XServeru, Wayland kompozitoru a PulseAudio serveru hosta. Další nezbytností je --share=ipc
, bez čehož by nefungovala sdílená paměť Xek a výkon naší aplikace by dost utrpěl. Chceme-li povolit přístup aspoň k 3D akceleračnímu hardware, musíme ještě uvést --device=dri
.
Výsledkem našeho pachtění se můžeme pokochat tak, že program spustíme. Nanečisto spustíme PeakMaster takto:
$ flatpak-builder --run PMNG_pkg/ cz.cuni.natur.echmet.PeakMasterNG.json PeakMasterNG
Pozor na to, že takhle spuštěná binárka se neřídí nastavením snadboxu z finish-args
ale parametry, které nastaví flatpak-builder
. Ty jsou ve výchozím stavu docela restriktivní a pořádně není přístupný ani souborový systém hosta. Na ověření, že máme sestavené všechny závislosti, knihovny nainstalované na správných místech apod. to ale stačí.
Balíček, jak jej máme teď by šel bez problémů zabalit, nainstalovat a spustit, měl by však pár nehezkých nedostatků. Kupříkladu chybějící .desktop
záznam by znemožnil jednoduché spuštění programu z nějaké nabídky aplikací. Zde má Flatpak pár specifik, o kterých je nutné vědět.
Protože Flatpakové balíčky jsou identifikovány pomocí app-id
, je nutné tomu přispůsobit i příslušný .desktop
soubor. Flatpak naštěstí umí tento proces dosti zjednodušit. Náš standardní .desktop
záznam vypadá takto:
[Desktop Entry] Type=Application Exec=PeakMasterNG Name=PeakMaster GenericName=Capillary Zone Electrophoresis simulator X-KDE-StartupNotify=true Terminal=false Categories=Science;Education Icon=PeakMasterNGDo hlavičky manifestu přidáme tento blok:
"rename-desktop-file": "PeakMasterNG.desktop"Samotný
.desktop
soubor je potřeba nakopírovat na správné místo. To lze zařídit přidáním následujícího řádku do build-commands
modulu PeakMasterNG
:
"install -D PeakMasterNG.desktop /app/share/applications/PeakMasterNG.desktop"Podobný trik použijeme i na ikonu aplikace. Hlavičku manifestu obohatíme o
"rename-icon": "PeakMasterNG"a
build-commands
o
"install -D res/PeakMaster_icon.png /app/share/icons/hicolor/32/apps/PeakMasterNG.png"
Tady je kruciální dát pamatovat na to, že v rename-icon
se uvádí název původního soubru s ikonou bez přípony a že ikonu je při vytváření balíčku nutné nakopírovat na správné místo. Kdybyste se někde spletli, dostanete od flatpak-builderu na konci sestavování balíčku varování. Proběhlo-li vše v pořádku, budou nyní v /home/flatpak/flatpak_PMNG/PMNG_pkg/
v podadresáři export
nakopírované soubory PeakMaster.desktop
a cz.cuni.natur.echmet.PeakMasterNG.png
I když jsem až dosud hovořil o sestavování balíčku, ve skutečnosti jsme zatím žádný opravdový balíček nevytvořili. Obsah adresáře PMNG_pkg
je jen jakýsi prefabrikát, který musíme dotáhnout do konečné podoby. Flatpak umožňuje přímý export do online repozitářů (třeba flathub), tuto možnost jsem ovšem nezkoušel. Předvedu možnost, jakým se vytvoří samostatný soubor, který si uživatel stáhne z webu a pomocí Flatpaku nainstaluje. Je to jednoduché:
$ flatpak build-bundle PMNG PeakMasterNG.flatpak cz.cuni.natur.echmet.PeakMasterNG
kde PMNG
je jméno repozitáře, které jsme předávali flatpak-builderu, PeakMasterNG.flatpak
jméno výsledného balíčku a cz.cuni.natur.echmet.PeakMasterNG
ID aplikace.
Čerstvě sestavený teď už skutečně balíček můžete nainstalovat:
$ flatpak install --bundle PeakMasterNG.flatpak
V aplikačním menu by měla přibýt ikona PeakMasteru. Instalátoru je možné přidat parametr--user
, který balíček nainstaluje do ~/.local/share/flatpak
.
Zajisté všichni znáte ten pocit, kdy vaši parádní a samozřejmě perfektně odladěnou aplikaci připravíte pro distribuci, všechno je hotové a připravené, už jste v podstatě jednou nohou ze dveří kanceláře ale stejně vám to nedá, tak tu distribuční verzi přece jen vyzkoušíte. Jen tak, pro ten pocit, že jste všechno prověřili s paranoidní nedůvěřivostí, přesvědčeni, že všechno musí být okay a ono to dopadne takhle:
Flatpakové aplikace je možné debugovat skoro stejně jako všechny jiné. Předpokládáme, že máme kromě runtimu pro danou aplikaci nainstalované i SDK (což na vývojovém stroji určitě máme). Pak lze provést:
$ flatpak run --devel --command=sh cz.cuni.natur.echmet.PeakMasterNGMísto aplikace samotné se spustí shell, odkud můžeme spustit třeba gdb:
$ gdb /app/bin/PeakMasterNGZ gdb se ale v tomto případě nedozvíme o moc více, v knihovně MPFR prostě selhal nějaký assert...
Protože tušíme, že jde o problém kdesi v synchronizaci vláken, sáhneme po nástroji helgrind
, který je k dispozici také:
$ valgrind --tool=helgrind /app/bin/PeakMasterNGvýstup, obsahující například toto je více než výmluvný:
==5== Possible data race during write of size 8 at 0x6F75010 by thread #10 ==5== Locks held: none ==5== at 0x6D36268: mpfr_set_d (in /usr/lib/libmpfr.so.4.1.4) ==5== by 0x6F9A727: ??? (in /app/lib/libCAES.so.0.2) ==5== by 0x6F89D55: calculateFirstConcentrationDerivatives_prepared (in /app/lib/libCAES.so.0.2) ==5== by 0x53B7342: ??? (in /app/lib/libLEMNG.so.0.3) ==5== by 0x53BF318: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (in /app/lib/libLEMNG.so.0.3) ==5== by 0x382020EE78: ??? (in /usr/lib/libpthread-2.24.so) ==5== by 0x53B68C9: ??? (in /app/lib/libLEMNG.so.0.3) ==5== by 0x3820AB7F6E: ??? (in /usr/lib/libstdc++.so.6.0.22) ==5== by 0x3820207443: ??? (in /usr/lib/libpthread-2.24.so) ==5== by 0x381FAE827E: clone (in /usr/lib/libc-2.24.so) ==5== ==5== This conflicts with a previous read of size 8 by thread #9 ==5== Locks held: none ==5== at 0x6D2C984: mpfr_mul (in /usr/lib/libmpfr.so.4.1.4) ==5== by 0x6F8CF41: ??? (in /app/lib/libCAES.so.0.2) ==5== by 0x6F8DE16: ??? (in /app/lib/libCAES.so.0.2) ==5== by 0x6F8BB74: ??? (in /app/lib/libCAES.so.0.2) ==5== by 0x6F89DB7: calculateFirstConcentrationDerivatives_prepared (in /app/lib/libCAES.so.0.2) ==5== by 0x53B7342: ??? (in /app/lib/libLEMNG.so.0.3) ==5== by 0x53BF318: std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (in /app/lib/libLEMNG.so.0.3) ==5== by 0x382020EE78: ??? (in /usr/lib/libpthread-2.24.so) ==5== Address 0x6f75010 is 0 bytes inside data symbol "__gmpfr_emin"Knihovna MPFR by měla být thread-safe, pokud to daná platforma a použitý překladač umožňují. Jako thread-unsafe se MPFR přeloží pouze tehdy, nedovolí-li to použité prostředí nebo je to ručně zakázáno v konfiguraci. Výstup helgrindu napovídá, že MPFR dodáváná v runtime org.kde.Platform thread-safe nejspíš není. Způsobů, jak to ověřit se nabízí několik. Můžeme například přidat vlastní build knihovny MPFR jako další modul. To uděláme tak, že úplně na začátek pole
modules
vložíme
{ "name": "mpfr", "buildsystem": "autotools", "config-opts": [ "--enable-thread-safe", "--disable-static" ], "sources": [ { "type": "archive", "url": "http://www.mpfr.org/mpfr-current/mpfr-4.0.1.tar.xz", "sha256": "67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e" } ], "cleanup": [ "/include", "/share" ] }
Význam jednotlivých položek už je předpokládám jasný. Projdeme-li výstup helgrindu teď, zjistíme, že žádné synchronizační problémy v našem kódu už nehlásí a program nepadá! (Pozor na to, že helgrind dodávaný s Flatpakovými SDK je trochu problémový a občas spadne sám o sobě.) Jednou ze zvláštností, na kterou jsem při testování Flatpaku narazil bylo, že některé knihovny jsou očividně přeložené i s asserty. Pokud jste zapomněli v kódu nějakou hloupou chybu, můžete o nějaký takový assert zakopnout.
Protože jde o první projekt, který hodlám pro Linux distribuovat pomocí Flatpaku, těžko můžu na závěr nabídnout nějaké dlouhodobější zkušenosti nebo doporučení. Můžu říct pouze tolik, že mi celý proces přišel docela elegantní. Vzhledem k tomu, jak flexibilní musí flatpak-builder být se to o moc jednodušeji udělat nejspíš nedá. Jak moc se mi Flatpak osvědčí v praxi ukáže až čas...
Úplný finální manifest:{ "app-id": "cz.cuni.natur.echmet.PeakMasterNG", "runtime": "org.kde.Platform", "runtime-version": "5.9", "sdk": "org.kde.Sdk", "command": "PeakMasterNG", "finish-args": [ "--filesystem=host", "--socket=x11", "--socket=wayland", "--socket=pulseaudio", "--device=all", "--share=ipc" ], "rename-desktop-file": "PeakMasterNG.desktop", "rename-icon": "PeakMasterNG", "modules": [ { "name": "mpfr", "buildsystem": "autotools", "config-opts": [ "--enable-thread-safe", "--disable-static" ], "sources": [ { "type": "archive", "url": "http://www.mpfr.org/mpfr-current/mpfr-4.0.1.tar.xz", "sha256": "67874a60826303ee2fb6affc6dc0ddd3e749e9bfcb4c8655e3953d0458a6e16e" } ], "cleanup": [ "/include", "/share" ] }, { "name": "eigen", "buildsystem": "simple", "build-commands": [ "mkdir -p /app/Eigen", "cp -r Eigen /app/Eigen", "cp -r unsupported /app/Eigen" ], "sources": [ { "type": "archive", "url": "http://bitbucket.org/eigen/eigen/get/3.3.4.tar.bz2", "sha256": "dd254beb0bafc695d0f62ae1a222ff85b52dbaa3a16f76e781dce22d0d20a4a6" } ], "cleanup": [ "/Eigen" ] }, { "name": "CoreLibs", "buildsystem": "cmake", "config-opts": [ "-DCMAKE_BUILD_TYPE=Release", "-DEIGEN_INCLUDE_DIR=/app/Eigen", "-DCMAKE_INSTALL_PREFIX=/app", "-DCMAKE_CXX_FLAGS=-g" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/ECHMETCoreLibs.git", "branch": "master" } ], "cleanup": [ "/include" ] }, { "name": "LEMNG", "buildsystem": "cmake", "config-opts": [ "-DCMAKE_BUILD_TYPE=Release", "-DEIGEN_INCLUDE_DIR=/app/Eigen", "-DECHMET_CORE_LIBS_DIR=/app", "-DCMAKE_INSTALL_PREFIX=/app", "-DCMAKE_CXX_FLAGS=-g" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/LEMNG.git", "branch": "master" } ], "cleanup": [ "/include" ] }, { "name": "qwt", "buildsystem": "simple", "build-commands": [ "qmake qwt.pro CONFIG+=release", "make -j4", "make install" ], "sources": [ { "type": "archive", "path": "/home/flatpak/flatpak_PMNG/qwt-6.1.3_configured.tar.bz2" } ], "cleanup": [ "/include", "/doc", "/features", "/plugins" ] }, { "name": "PeakMasterNG", "buildsystem": "simple", "build-commands": [ "qmake PeakMasterNG.pro CONFIG+=release CONFIG+=flatpak_build", "make -j4", "make install", "install -D PeakMasterNG.desktop /app/share/applications/PeakMasterNG.desktop", "install -D res/PeakMaster_icon.png /app/share/icons/hicolor/32/apps/PeakMasterNG.png" ], "sources": [ { "type": "git", "url": "https://github.com/echmet/PeakMasterNG.git", "branch": "master" }, { "type": "patch", "path": "/home/flatpak/flatpak_PMNG/PMNG_config.patch", "strip-components": 0 } ] } ] }
Tiskni
Sdílej:
flatpak run --nofilesystem=home MyApp
) nebo trvale (flatpak override --nofilesystem=home MyApp
). Práva v manifestu jsou jen default, který si může uživatel upravit dle potřeby.
Kernel ABI != userspace ABIVe smyslu, ze "stable" distra neslibuji stabilni kernel ABI ale jen userspace ABI? Tohle je priklad, na ktery jsem narazil zrovna vcera, kdy slib stabilniho ABI nic neznamena. Pripady, kdy se neco podobneho povedlo klukum z flatpaku si budes muset najit sam (maji bugzillu pro runtimes?).
--device=dri
(doufám, že nekecám).
Pokud se ma aplikace spoustet po startu/ovladat pres init skripty, jak je toto vyreseno?Není vyřešeno. Pro takové aplikace není Flatpak určen.
/var/lib/flatpak
. To je daleko lepší situace než typické dilema AURisty, kdy WeirdAppA chce knihovnu libLegacyB která teď začala kolidovat s libNewVersionB, na které jako na potvoru závisí dalších patnáct balíčků a dokud to někdo nějak nevyřeší, nemohu instalovat aktualizace.
Pochopil jsem, že se ti koncept flatpaku nelíbí, okay, jak bys to tedy řešil ty?Dodrzovat ABI kompatibilitu. Pokud by mi abclinuxu nevracelo "413 Request Entity Too Large", tak bych vlozil jako prilohu build vimu, ktery pouziva dynamicke linkovani a bude fungovat na vsech normalnich distribucich od rhel5 po Ubuntu 17.10 - to znamena na vetsim mnozstvim distribuci nez flatpak. Navic diky tomu ze ma dynamicky linkovane libtinfo se i lepe integruje do systemu. Je mi jasne, ze to takto nefunguje pro gtk aplikace, protoze gnome "vyvojari" (narozdil od core knihoven) na to totalne kaslou. Sam mam takovou prihodu, kdy jsem resil velice neprijemny bug s gsettings v ubuntu. Resetovalo se nastaveni klavesovych zkratek po restartu. Tento bug tam vydrzel pres dva roky a minimalne jeden ubuntu maintainer o nem vedel, nastavil si workaround a neresil; po dvou letech me to nastvalo tak, ze jsem stravil tri dny v gdb a fixnul to za ne, ale ocenuji, ze pak aspon patch bez kecu prijali (na zaklade predchozich zkusenosti jsem patch ani nezkousel dostat do upstreamu gnome - to by proste vyhnilo v bugzille). Je mi jasne, ze naucit vyvojare s takovymto pristupem nerozbijet ABI je mimo realitu. Na druhou stranu, jine opravdove reseni neexistuje. Flatpak apod. jsou takove workaroundy, kde se povazuje za uspech, ze se aplikace povede spustit.
Ne, minimálně pro Flathub to je vyřešené tak, že do něj lze přidávat témata jako rozšíření runtimu.Jo to je presne ten "hack", ktery myslim, tzn. integrace nulova. Takze se nic nezmenilo, diky za info.
Neco jako treba:
# for LINE in $(rpm -qR httpd);do rpm -q --whatprovides $LINE; done | sort | uniq | grep -v "no package provides" apr-1.2.7-11.el5_6.5 apr-util-1.2.7-11.el5_5.2 bash-3.2-32.el5 chkconfig-1.3.30.2-2.el5 coreutils-5.97-34.0.1.el5_8.1 db4-4.3.29-10.el5_5.2 expat-1.95.8-11.el5_8 file-4.17-28 findutils-4.2.27-6.el5 gawk-3.1.5-16.el5 glibc-2.5-107 httpd-2.2.3-76.0.1.el5_9 initscripts-8.45.42-1.0.3.el5_8.1 libselinux-1.33.4-5.7.el5 mailcap-2.1.23-1.fc6 mktemp-1.5-24.el5 openldap-2.3.43-25.el5_8.1 openssl-0.9.8e-26.el5_9.1 pcre-6.6-6.el5_6.1 shadow-utils-4.0.17-21.el5 zlib-1.2.3-7.el5
Jsem si nevsiml ze by si to tahlo vsechny zavislosti sebou. A httpd je takova obvykla unixova aplikace pokud se nepletu. Instalace pres rpm/deb mi proste prijde k systemu cistejsi a obecne vzato i bezpecnejsi.
Co se klonování z gitu týče, jde uvést branch, tag i konkrétní commit, který se má použít.Aspoň, že tak.
Flatpak se IMHO nesnaží být "lepší balíčkovacím systémem" jako spíš rozumně kompromisní alternativou k nativním balíčkům. Jsem zvědavý, zda a kam se možnosti Flatpaku posunou.Obávám se, že nativní balíky budou postupně mizet. Tady je totiž problém v tom, že vytvořit správně balík třeba pro Debian není vůbec jednoduché a dostat ho do oficiálních repozitářů jakbysmet. Vývojáři ani uživatelé nechtějí čekat. Dnes se proto lze často setkat s „oficiálními“ upstream repozitáři (ať už provozovaných na vlastním serveru, nebo třeba jako PPA). To na první pohled vypadá jako dobré řešení, dokud není třeba řešit závislosti napříč těmito repozitáři. Balík foo z jednoho repozitáře může záviset na balíku bar z jiného repozitáře, který uživatel nemá přidaný. Konflikt pak musí vyřešit ručně on sám (v tomto případě nalezením a přidáním repozitáře, který obsahuje patřičný balík). V dlouhodobém horizontu se také můžou objevovat problémy se zanikajícími repozitáři. Nabízí se myšlenka, jestli by závislost neměla být specifikována jen jménem balíku, ale ještě zdrojem. To ovšem neřeší ty případné zanikající repozitáře. Nakonec by tedy asi bylo nejlepší něco jako IPFS, kdy balík bude specifikován jménem, verzí (viz dále) a nějakým podpisem – klasický checksum nelze použít, protože každá verze bude mít jiný. Co se týká verzí, bylo by ideální pevně odlišit verzi API od verze softwaru, nebo striktně dodržovat konvence. V praxi nevím, jaký konsenzus v případě schéma <major>.<minor>.<patch> panuje ohledně situací, kdy v rámci (security) bugfixu je nutné rozbít zpětnou kompatibilitu. Inkrementuje se jen patch a mávne se nad tím rukou s tím, že „správně napsané programy by to rozbít nemělo“? Takže by existoval jen jediný decentralizovaný repozitář (provozovaný např. na IPFS). Závislost by byla určená jménem balíku, podpisem, co nejméně restriktivní verzí (např. 1.2.*, pokud je garantováno, že API je stejné; alternativně lze také zavést další kvalifikátory, např. že patch musí být větší nebo roven nějaké hodnotě apod.) a dále referenční verzí, se kterou byl daný program původně testován. Pokud by v systémech existovalo cachování balíků (nebo způsob jak je rekonstruovat z instalovaných souborů a minimálních dat držených v cachi package manageru), šlo by za předpokladu, že by systémy byly do IPFS běžně zapojeny zajistit, že dokud lidé budou libovolný balík dané verze používat, bude k dispozici i ostatním. Referenční verze má spíše dokumentační význam: Pokud po upgradu nějaké knihovny přestane program fungovat, uživatel tuší, na jakou verzi by měl zkusit downgradovat (i třeba za cenu, že bude riskovat bezpečnostní zranitelnost – to už je jeho volba). Balíčkovací systém by s tímto případně mohl i automatizovaně pomoci. Prerekvizitou samozřejmě je, že balíčkovací systém bude umět držet více verzí stejně pojmenovaného balíku. Ostatně, v systému, který naznačuji, by název měl rovněž spíše dokumentační význam než cokoliv jiného. Závazný je spíše nějaký ten podpis. IPFS zmiňuji jen jako příklad, možná se na toto použití ani nehodí. Podstatná je ta myšlenka jednoho decentralizovaného depozitáře, ne konkrétní technické provedení.
215 text files. 215 unique files. 6 files ignored. github.com/AlDanial/cloc v 1.70 T=0.70 s (301.2 files/s, 26595.5 lines/s) ----------------------------------------------------------------------------------- Language files blank comment code ----------------------------------------------------------------------------------- C++ 88 2307 134 8636 C/C++ Header 100 1103 70 3633 Qt 20 0 0 2313 Prolog 1 22 0 270 Markdown 1 18 0 55 Windows Resource File 1 19 23 28 ----------------------------------------------------------------------------------- SUM: 211 3469 227 14935 -----------------------------------------------------------------------------------Takže kvůli cca 9k řádkům v C++ (dodám že to je počet který by Gentoo emerglo jedním příkazem snad dřív než by se ten Flatpak nainstaloval) bude sebou aplikace tahat co? Qwt, QT5, LEMNG, … GNUGMP? Pokrok prostě nezastavíš. Ještě by mě zajímalo kolik má kB vlastní binárka toho PeakMasteru a kolik vlastní balíček ve Flatpaku. Jako pro nějaké velké aplikace typu LibreOffice, GIMP (i když i ten mám přeložený svůj v několika verzích a přitom naprosto bez problémů) budiž, ale tohle kvůli nějakému grafickému bindingu na pár knihoven který by se hodil spíš do nějakého AppStoru?