Hlavní navigace

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

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

Sdílet

Tento díl bude trochu více zaměřený na Python, věřím, že to nebude vadit. Kromě vytvoření binárky z Pythonu se ale podíváme i na problémy s nabodeníčky. Předem upozorňuji, že zvláště v tématu vytváření binárky je třeba brát tento článek jako určité nastínění postupu, není to podrobný návod. Přesto věřím, že bude k užitku.

Problémy s češtinou

Python a PyGame mají jednu velkou výhodu – umožňují používat pro práci s textem univerzální kódování Unicode. Díky němu nemusíme provádět žádné překódovací „harakiri“ v závislosti na operačním systému, a vyhneme se tak nestandardnímu kódování Windows-1250. I když – pár problémů se přece jen našlo. Takže hurá na ně.

Titulek okna

Pokud vytváříme program, který poběží v okně, měli bychom tomuto oknu nastavit nějaký titulek. Nevím proč, ale v tomto případě knihovna PyGame s kódováním Unicode nepočítá a je třeba zadat text v nativním kódování. Naštěstí Python umožňuje detekci jednotlivých platforem, takže řešení problému je nasnadě:

cap = u"Akční čeština"
# detekujeme Windows platformu
if "win" in sys.platform:
   cap = cap.encode("windows-1250")
else:
   if "LANG" in os.environ and
os.environ["LANG"].endswith("UTF-8"):
   cap = cap.encode("utf-8")
else:
   cap = cap.encode("iso8859-2")

pygame.display.set_caption(cap)

Tento fragment kódu nedělá nic jiného, než že řetězec na platformě Windows překóduje do Windows kódování, na Linuxu v závislosti na nastavené proměnné LANG nastaví titulek podle aktuálního kódování (většinou ISO-8859–2, Redhat a Fedora používá Unicode). Nutno podotknout, že některé window managery unicode v titulku nepodporují, ale myslím, že jejich zastoupení můžeme zanedbat.

Klávesnice

Asi největší problém s češtinou byl při pokusu ji napsat. Nevím, jestli byla na vině knihovna SDL, anebo PyGame, každopádně jak v Linuxu, tak i ve Windows se českých znaků nedočkáme. Což je u českého programu poměrně nemilé. Řešení existuje – stačí si napsat vlastní převod scan kódu klávesnice na příslušný znak kódovaný v unicode.

Knihovna SDL (a díky tomu i PyGame) obsahuje frontu událostí (od myši, časovače apod.), jednou z událostí může být i stisk klávesy. V ideálním případě (a podle dokumentace) obsahuje tato událost scankód klávesy, stav shiftů a ostatních přepínačů a konečně také znak v unicode kódování, který by měl odpovídat stisknuté klávese. Leč neodpovídá. Nezbývá tedy nic jiného, než si ho z dostupných informací (scankódu, stavu shiftů apod.) doplnit. Nebudu uvádět kompletní zdrojový kód do článku, kdo chce, může si ho stáhnout. Uznávám, že někomu nemusí toto řešení připadat příliš čisté, protože nerespektuje nastavení systému, na druhou stranu funguje i na počítači, který nemá nakonfigurovanou českou klávesnici.

Fonty

Zdánlivě maličkost, ovšem u multiplatformního programu problém – kde vzít fonty, které budou na všech operačních systémech? U her a multimediálních aplikací se asi nespokojíme se standardním systémovým fontem, protože nechceme, aby program vypadal na každé platformě jinak. Řešením je použít nějaké volně dostupné fonty a zařadit je přímo do aplikace.

Knihovna PyGame podporuje zobrazování TrueType fontů, proto jsem hledal nějaký použitelný TrueType font. Díky firmě BitStream bylo mé hledání úspěšné. Tato firma totiž uvolnila své fonty Verapod otevřenou licencí. Dostanete tak k volnému použití standardní řezy, které odpovídají klasice Arial, Times a Courier. S tím většina aplikací vystačí.

Původní fonty od Bitstreamu nepodporovaly češtinu, naštěstí se našli dobrovolníci, kteří dodělali podporu pro národní znaky a vznikly tak od Very odvozené fonty DejaVu.

Vytváříme binárku

Jak jsem podotkl v předchozím dílu, mým cílem bylo odstínit koncového uživatele od toho, že program pohání nějaký Python. Výstupem měly být spustitelné soubory, a to pro Windows i pro Linux.

Python je v tomto směru docela kamarádský. Jak licencí, která povoluje zahrnout Python do libovolného projektu a s tímto projektem ho i šířit, tak i co se vytváření binárky týče. Principiálně to je jednoduché – k malému programu v C se přilinkuje knihovna s Pythonem a dotyčný malý prográmek jen spustí náš pythonovský program. Ve skutečnosti je to ale trochu složitější – naštěstí existují jak pro Linux, tak i pro Windows hotové nástroje, které to vyřeší za nás.

Řešení pro Linux

Pro vytváření Linuxové binárky jsem použil utilitu cx_freeze, která zjednodušeně dělá asi toto:

  • nalezne, jaké používáme v našem pythonovském programu balíčky (pythonovské knihovny)
  • tyto balíčky zapakuje do ZIP souboru
  • překopíruje (některé) používané binární knihovny do adresáře, kde bude vytvořená binárka
  • připojí vytvořený ZIP soubor k binárce s Pythonem, která při svém spuštění nastartuje pythonovský program uložený v ZIP souboru.

Instalace cx_freeze je snadná – stačí rozbalit stažený balíček a spustit skripty:

  • python MakeFrozenBases.py
  • python FreezePython.py –no-copy-deps FreezePython.py

Získáme program FreezePython, který použijeme na vytváření binárky ze zdrojových souborů. A můžeme to hned vyzkoušet. Vytvoříme si libovolný pythonovský prográmek, např. pokus.py. Přenositelnou a spustitelnou binárku z něj vytvoříme zavoláním:

./FreezePython –target-dir=bin pokus.py

Po nalezení všech závislostí dojde k vytvoření binárky v adresáři bin pod jménem pokus. Pokud ji zkopírujeme spolu s obsahem adresáře na jiný počítač, měla by tam fungovat i bez instalace Pythonu.

Tolik teorie a přání programátora. Ve skutečnosti nás čeká několik záludností:

  • program ne vždy rozezná všechny dynamické knihovny, které jsou závislé na Pythonu a jeho balíčcích. Je proto nutné zjistit, na kterých knihovnách je náš program závislý, a tyto knihovny zkopírovat do adresáře s binárkou. V mém případě to byla knihovna SDL.
  • Nevím proč, ale ve standardní instalaci cx_freeze je výsledná binárka linkovaná s Pythonem dynamicky. Pokud vám to nevyhovuje, stačí upravit skript MakeFrozenBases.py, který binárku vytváří (podrobnosti jsou už nad rámec článku, ale rád případně poradím mailem).

Výslednou aplikaci jsem testoval asi na šesti distribucích, od stařičkého Redhat 9 přes novější Suse, Fedora Core 3 a Mandrake 10.1 a všude běhala bez problémů.

Řešení pro Windows bez Windows

Jak jsem předeslal v prvním dílu seriálu, mým cílem bylo vytvářet i binárku pro Windows na Linuxu. Není to ani tak kvůli tomu, že bych byl takový fanatický odpůrce Windows. Je to zkrátka pohodlné. Přijde mi snadnější spustit jeden skript na Linuxu a za dvě minuty mít instalační balíčky pro Linux i Windows než neustále přebootovávat, případně pracovat na dvou počítačích najednou.

Níže popsaný postup je experimentální a neručím za to, že nepřestane v budoucnu fungovat, případně že nebude někomu fungovat na jeho distribuci i teď. Wine se neustále vyvíjí a autoři negarantují, že když něco funguje teď, bude to fungovat i za týden :-). Jak tedy na to?

  1. Předně potřebujeme Wine – „emulátor“ Windows, který si můžete stáhnout jako balíček pro vaši oblíbenou distribuci z domovské stránky projektu. Doporučuji nejnovější verzi.
  2. O Wine je známo, že v něm funguje spousta věcí, jen je třeba vše správně nakonfigurovat. Musím přiznat, že se mi to nikdy příliš nedařilo. Až nedávno jsem objevil vynikající utilitu WineTools, která stáhne a nainstaluje do Wine potřebné knihovny a základní Windows software (např. fonty, podporu pro DCOM a podobně). Také vytvoří soubor s Windows registry, díky němuž začne fungovat spousta programů, které dříve končily pádem.
  3. Máme funkční Wine, nyní je třeba nainstalovat Python pro Windows. Stáhneme instalační balíček (já mám vyzkoušený Python 2.3) a nainstalujeme (pomocí Wine).
  4. Podobně jako na Linuxu cx_Freeze existuje na Windows utilita py2exe. Na domovské stránce nalezneme instalační balíček, který stáhneme a opět pomocí Wine nainstalujeme.
  5. Stejně můžeme nainstalovat a stáhnout další balíčky pro Python (např. PyGame)

Tak, a nyní máme funkční Windows verzi Pythonu na Linuxu. Můžete vyzkoušet, jestli funguje – pokud jste postupovali jako já, můžete ho spustit pomocí:

wine ~/.wine/drive_c/Python23/python.exe

po chvíli by se mělo objevit klasické uvítání a prompt Pythonu – Win32 verze:

Python 2.3.4 (#53, May 25 2004, 21:17:02)
[MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> _

Pokud Python funguje, můžeme přistoupit k vytváření EXE souboru. Py2exe je oproti cx_freeze vyzrálejší, nemusel jsem dělat žádné úpravy ani ručně vyhledávat chybějící knihovny. I použití je jednoduché, musíme jen vytvořit soubor setup.py, který vypadá zhruba takto:

from distutils.core import setup
import py2exe
setup(windows=["akcnicestina.py"], icon_file="akcnicestina.ico")

Popisovat všechna možná nastavení Py2Exe je nad rámec tohoto článku. Pro běžné použití postačí takto jednoduchý setup.py soubor, ve kterém se určuje, z jakého .py souboru budeme vytvářet EXE soubor a jaká bude tomuto výslednému EXE souboru přiřazena ikona.

Pak již jen stačí zavolat:

CS24_early

wine c:\\python23\\python.exe setup.py py2exe

A pokud vše proběhne tak, jak má, objeví se v adresáři dist výsledný EXE soubor spolu s potřebnými knihovnami.

A co bude příště?

Počítám, že příští díl bude i dílem posledním. Budeme se věnovat vytváření instalačních balíčků, a to jak pro Linux, tak i pro Windows. Samozřejmě vytváření Windows instalačního balíčku proběhne na Linuxu :-). A pokud by byly nějaké další náměty, rád se o nich zmíním, nebojte se zeptat.

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