Hlavní navigace

Vyvíjíme multiplatformní programy na Linuxu (1)

10. 3. 2005
Doba čtení: 7 minut

Sdílet

V tomto malém seriálu se vás budu snažit obeznámit s radostmi a strastmi vývoje multiplatformní aplikace, která je primárně vyvíjena na Linuxu. Určitě se mi nepodaří napsat naprosto obecný článek, který postihne celou problematiku. Nabídnout ale mohu zkušenosti z praktického projektu, který je již dokončen a docela dobře funguje.

V tomto malém seriálu se vás budu snažit obeznámit s radostmi a strastmi vývoje multiplatformní aplikace, která je primárně vyvíjena na Linuxu. Určitě se mi nepodaří napsat naprosto obecný článek, který postihne celou problematiku. To asi ani není možné, protože přístupů a možností, jak vyvíjet aplikaci, je nespočet. Nabídnout ale mohu zkušenosti z praktického projektu, který je již dokončen a docela dobře funguje.

Než se rozepíši o konkrétních problémech, je třeba napsat, co jsem si od projektu sliboval a jaké byly finální požadavky:

  • jedná se o hru (výukovou). Tj. v programu musí být animace, hudba, zvuky.
  • program chci vyvíjet na Linuxu
  • bude-li to možné, chci vytvářet binární soubor i instalační balíček pro Windows na Linuxu
  • program musí fungovat na všech běžných distribucích, může být instalován i bez práv roota
  • ovládání programu i instalaci musí zvládnout běžní uživatelé, a to jak na Linuxu, tak i na Windows. Uživatele nezajímá, co jsem použil za technologie, musí to prostě fungovat. Nechci ho otravovat s nějakými závislostmi balíčků a různými verzemi knihoven.
  • nejedná se o opensource projekt. I na ten chléb je potřeba nějak vydělat… Z toho plyne, že se k uživateli dostane jen binárka.

Možná budu některými čtenáři ukamenován, ale myslím si, že v Linuxu mají své místo kromě opensource programů i programy šířené jako shareware anebo dokonce pod komerční licencí. Já jsem například velmi vděčný za linuxovou verzi Lingea Lexiconu a mrzí mě, že není více podobných českých firem, které by nabídly např. linuxovou verzi účetnictví, různých grafických prohlížečů a třeba i různých shareware blbůstek, kterých je pro konkurenční OS bezpočet. Proto je hlavním cílem článku ukázat, že multiplatformní aplikaci, která není opensource, udělat jde.

Vhodný programovací jazyk a knihovny

V dnešní době to má programátor podstatně jednodušší než před takovými 5 lety. Dříve by asi nebyla jiná volba než C/C++, ovšem díky stále rychlejším počítačům jsem si nyní mohl dovolit použít vyšší jazyk. Volba padla na Python, a to z následujících důvodů:

  • Python velmi dobře pracuje s unicode řetězci. Unicode podporuje jak v Linuxu, tak i ve Windows, tj. v programu pak nemusíme (až na některé výjimky) řešit problém s kódováním.
  • Python řeší docela dost platformně závislých problémů za vás. Dobrým příkladem je práce s adresáři a cestami. Při použití standardní pythonovské knihovny os.path se o správný formát zápisu cesty nemusíme vůbec starat.
  • Python je velmi dobře podporován na Linuxu, Apple i Windows. Pro všechny tyto platformy existují i knihovny, které řeší právě speciality dané platformy (např. volání Windows API).
  • Na všech platformách jde vytvořit binární soubor, do kterého se začlení jak Python, tak i samotný program zkompilovaný do bytecode. Uživatel tedy vůbec nemusí tušit, že má na svém počítači nějaký Python. Výsledná binárka je v závislosti na platformě menší než 3 MB, což je ve srovnání např. s Javou velmi příjemná velikost.
  • V Pythonu se velmi dobře programuje, díky pluginu do Eclipse máme k dispozici komfortní editor, debugger a podobné nástroje. O Pythonu zde ale psali povolanější, takže nezbývá než odkázat na seriál Létající cirkus.
  • Běh programů v Pythonu je poměrně rychlý, lze použít i just in time compiler Psyco. Rychlost rozhodně dostačuje pro běžné aplikace i jednodušší hry.

Samotný Python neřeší grafiku, hudbu a další potřebné věci k vývoji hry. S tím nám pomůže PyGame, která je nadstavbou oblíbené a hojně používané knihovny SDL. Zvládá výborně práci s grafikou, s hudbou v různých formátech i s periferiemi a je primárně vytvářena jako multiplatformní. Existuje verze pro Linux, Apple, Windows a další operační systémy.

Nechci, aby vznikl dojem, že se Python a dále popsané postupy hodí jen na vývoj hry. Zájemce o klasické aplikace odkážu na projekt wxPython, který je nadstavbou nad multiplatformní Gui knihovnou wxWidgets. Pomocí ní můžete vytvářet klasické okénkové aplikace, které používají nativní Gui prvky dané platformy. Konkrétní postupy popsané v dalších dílech bude možné ve většině případů použít i na tento typ aplikací. U řešení některých problémů budu uvádět příklady v Pythonu, věřím, že je Python natolik pochopitelný, že přepsání do jiného jazyka by nemělo činit problémy. Pokud se budu někde odkazovat na název aplikace, budu používat anonymní MyApp.

Domovský a aplikační adresář

Většina aplikací potřebuje pro svůj bezproblémový běh dva druhy úložišť, kam může zapisovat uživatelská nastavení a další aplikační data. Jednak to jsou data unikátní pro uživatele (např. nastavení menu, oblíbené barvy apod.), jednak globální nastavení společné pro všechny uživatele. U her to může být například soubor s tabulkou s nejvyšším skóre. Požadavky na jednotlivá úložiště jsou asi zřejmá, do uživatelského adresáře smí zapisovat (i z něj číst) jen dotyčný uživatel, ve společném mohou číst i zapisovat všichni.

Řešení na Linuxu

Získat domovský adresář je na Linuxu opravdu snadné. Oblíbená tilda funguje i v Pythonu, takže adresář, do kterého si můžeme zapisovat konfiguraci, lze získat třeba takto:

homeConfig = os.path.join(os.path.abspath(os.path.expanduser("~")),".myApp")

aplikačním adresářem to už tak jednoduché není. Díky požadavku zápisu všech uživatelů musíme správně nastavit práva k adresáři i GUID bit programu. Ale pěkně popořádku.

Podle Linux Games Install And Directory Guide je vhodné místo pro společná data v adresáři /var/games/myApp. Do tohoto adresáře ovšem musí mít aplikace právo čtení i zápisu. Ve většině distribucí existuje skupina games, která slouží právě k tomuto účelu. Dotyčnému adresáři ve var/games/ nastavíme práva zápisu pro skupinu a vlastníka skupinu games:

chown games:games /var/games/myApp
chmod g+rw /var/games/ucimehrou/myApp

Následně musíme binárnímu souboru, kterým program spouštíme, nastavit jako vlastníka tuto skupinu games a nastavit sticky bit pro skupinu.

chown games:games myapp.bin
chmod g+s myapp.bin

Díky tomu bude mít spuštěný program právo zápisu do konfiguračního adresáře, nebude tam ale mít přístup běžný uživatel, tj. nebude moci např. smazat skóre. Což je přesně to, co chceme. Samozřejmě tyto příkazy nespouští uživatel, ale spouští se automaticky při instalaci.

Řešení na Windows

Ve Windows existuje ekvivalent linuxové proměnné HOME. Spoléhat na to ale bohužel nemůžeme, protože tuto proměnnou ve starých „DOSových“ Windows 95/98/Me nenalezneme. Musíme si tedy pomoci voláním Win32 API. Nutno podotknout, že nezískáme klasický Home, ale adresář, který se v českých Windows nazývá „Aplikační data“ a slouží přesně k tomu, k čemu ho potřebujeme – k uložení konfiguračních dat aplikace.

from win32com.shell import shellcon, shell
home = os.path.join(shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0),"myapp")

Důležitý je právě druhý parametr funkce SHGetFolderPath, který určuje, o jaký adresář máme zájem. Můžeme tak získat i další adresáře, např. úložiště fontů, programů a podobně.

Proto pro získání společného adresáře použijeme stejnou funkci, jen s jinou konstantou:

path = os.path.join(shell.SHGetFolderPath(0, shellcon.CSIDL_COMMON_APPDATA, 0, 0),"myApp")

o nastavení práv zápisu se stará instalační program, podrobněji se k tomu vrátím v dílu o vytváření instalačních balíčků. Nejsem natolik zběhlý ve Windows, takže jsem nepřišel na to, jestli jdou podobně jako v Linuxu nastavit práva, která závisí na spuštěné aplikaci a ne na přihlášeném uživateli. Otázka do pléna – jde to nějak? V tomto směru se mi nepodařilo nic bližšího vyzkoumat, a proto jsem jednoduše nastavil tomuto adresáři práva Read a Write pro Everybody.

Zrady a zákysy

Při řešení této problematiky vedly v zákysech Windows, i když nevím, jestli za to přímo mohly. Některé knihovny (libxml2) měly problém s diakritikou v názvu adresáře, proto načítání z aplikačních dat s přehledem fungovalo na anglických Windows (kde se adresář jmenuje Application Data), na českých však nikoliv. Samotný Python to zvládal bez problémů, proto pozor na některé knihovny.

CS24_early

Na co se můžete těšit příště?

Rád bych nastínil problematiku, kterou se budou zabývat další díly:

  • vytváříme windowsovou binárku a instalační balíček na Linuxu
  • vytváříme instalační balíček pro Linux tak, aby fungoval pokud možno na většině distribucí
  • další nechutné zrady Windows a Linuxu
  • nabodeníčka, a jak to přeci jen nebylo bez problémů

Je možné, že seznam není konečný. Rád ho také přizpůsobím vašemu zájmu. Můžu se například rozepsat o vytváření pythonovských binárek na Linuxu (pomocí cx_freeze) i Windows (py2exe), ale nevím, jestli to není téma pro příliš úzký okruh čtenářů. Proto nešetřete otázkami a připomínkami v diskusi.

Byl pro vás článek přínosný?