Emacs pro mírně pokročilé (3): Kompilace a debuggování programů v Emacsu

24. 4. 2001
Doba čtení: 6 minut

Sdílet

Koloběh práce při programování je velmi stereotypní. Editace, kompilování, ladění, hledání a odstraňování chyb, a tak stále dokola. Dá se říci, že podobný koloběh zažívá i typograf při elektronickém sázení dokumentu. Jednou z výhod prostředí editoru Emacs je možnost spouštění a komunikace s externími programy. Při programování či při tvorbě dokumentů pomocí rozličných formátovacích programů se tato možnost komunikace velmi hodí.

Při psaní kódu v editoru Emacs není důvod tento editor opouštět ve chvíli, kdy chceme kompilovat program například v jazyce C či zpracovávat vstupní text například pro TeX. Podívejme se nejprve, jak kompilovat programy. V Emacsu lze spouštět kompilátory jako podřízené procesy, jejichž výstup se bude zobrazovat v bufferu Emacsu. Emacs zároveň dokáže zpracovat případný chybový výstup a odkázat na řádky kódu, kde se chyba při kompilaci vyskytla. Funkce compile (která není standardně namapována na žádnou klávesovou zkratku a zavoláme ji tedy například pomocí M-x) spustí kompilaci, kde chybová hlášení zapisuje do bufferu compilation. Funkce vyžaduje jako parametr příkaz ke spuštění kompilace (zadaný v minibufferu) a při prvním spuštění nabízí standardně make -k. Adresář, ve kterém je uložen soubor v aktuálním bufferu, je použit jako výchozí. Standardní příkaz je definovaný v proměnné compile-command; pokud je tedy pro některý soubor vhodný jiný kompilační příkaz, lze tuto proměnnou lokálně předefinovat tak, jak jsme viděli v minulé části seriálu (pomocí konstrukce -*- mode: MODENAME; VAR: VALUE; ... -*-), nebo ji ručně zadat v minibufferu.

Spuštění kompilace zobrazí buffer compilation v novém okně, které však není aktivní. Stavový řádek (mode line) nás zároveň informuje o průběhu a stavu kompilace; zobrazuje slovo „run“, když proces ještě nebyl ukončen a „exit“ po skončení procesu, kdy zároveň zobrazí výstupový kód procesu. Toto okno nemusí zůstat otevřené a kompilace bude probíhat i po uzavření tohoto okna. Emacs nás o probíhající kompilaci informuje zobrazením slova „Compilation“. Pokud bychom chtěli kompilaci předčasně ukončit, lze k tomu použít funkci kill-compilation. Nastavení proměnné compilation-scroll-output na hodnotu různou od nil způsobí, že informace zobrazovaná v okně compilation bude rolovat tak, jak bude Emacs dostávat výstup z probíhajícího procesu kompilace.

A nyní k tomu nejzajímavějšímu, co nám Emacs při kompilaci nabízí – zpracování (typicky) chybového výstupu, tedy bufferu compilation. K tomuto účelu je určen tzv. compilation mode, jehož hlavním účelem je vhodným způsobem zobrazit řádek s chybou. Příkaz next-error, který je standardně namapován na klávesovou zkratku C-x ` (obrácený apostrof; pokročilým uživatelům snad netřeba připomínat, že tuto klávesovou kombinaci lze předefinovat, stejně tak jako definovat klávesové zkratky pro předchozí příkazy). Tento příkaz se hodí pro sekvenční zpracování chyb tak, jak byly vypsány kompilátorem, a lze jej použít ve všech bufferech (s výjimkou bufferu compilation, zde lze buď klávesou <RET>, nebo kliknutím prostředního tlačítka myši zobrazit přímo konkrétní chybu).

Pokud je řádek s chybou obsažen v některém z bufferů, přepne Emacs do tohoto bufferu a posune kursor přímo na daný řádek. Pokud soubor, kde byla nalezena chyba, není otevřený, pokusí se ho editor otevřít. Další práce v módu kompilace je usnadněna příkazy pro nové (míněno od začátku) zpracovávání výsledku kompilace ( C-u C-x); klávesami <SPC> a <DEL>, kterými lze posouvat text v bufferu compilation o celé obrazovky vpřed či vzad; pohyb po jednotlivých chybových výpisech je umožněn pomocí kláves M-n pro následující chybu a M-p pro předchozí. Lze se také posouvat pomocí M-{ na chybový výpis v předchozím souboru či M-} v následujícím souboru. Podobně jako v případě kompilace lze (spolu)pracovat s programem grep. Zadáním M-x grep nám Emacs standardně nabídne příkaz grep -n -e . Podrobnosti si lze přečíst v manuálu, poznamenejme pouze, že zpracování výstupu, který se pro změnu zobrazí v bufferu *grep* je velmi podobné zpravování výstupu kompilace. Navíc existuje i vedlejší (minor) mód compilation-minor-mode, který lze použít ke zpracování obsahu libovolného bufferu.

Kompilace ovšem není jediná a už vůbec ne hlavní nástraha, která na programátora číhá. Tou hlavní je obvykle ladění a odstraňování chyb, pro které se v češtině ustálil výraz debuggování. Ani ten nejlepší programátor se tomuto úkonu nevyhne. Emacs nám i v tomto případě nabízí pomoc, a dá se říci pomoc velmi silnou. Přichází s celou knihovnou GUD (Grand Unified Debugger), která poskytuje rozhraní k mnoha debuggerům. Doporučit lze GDB, ale je možné používat například i DBX, SDB nebo XDB. Tato knihovna poskytuje rovněž rozhraní k debuggovacímu módu Perlu, debuggeru Pythonu PDB, a konečně i JDB – Java debuggeru. Podrobněji si rozebereme pouze práci s GNU GDB debbuggerem.

Příkazem M-x gdb spustíme v Emacsu gdb jako podřízený proces. Tento příkaz vytvoří buffer pro komunikaci s gdb (vstup a výstup) a zvolí ho jako aktuální, pokud takový buffer již existuje, pouze do něho přepne. Analogické jsou i příkazy pro ostatní debuggery. Každý z nich (tedy i gdb) vyžaduje jeden argument, kterým je příkaz pro zavolání debuggeru. V nejjednodušším případě lze zadat pouze jméno spustitelného souboru, který chceme debuggovat, ale lze zde také předat řádkové parametry debuggeru. Emacs může v daný moment spustit pouze jediný debuggovací proces.

Když tedy spustíme debugger, vytvoří se buffer, který se nazývá GUD buffer. Během debuggování zobrazuje Emacs zdrojové soubory v bufferech sám, pokud je nalezne v příslušných cestách. Šipka v jednom z těchto bufferů (‚ =>‘) označuje právě prováděný řádek. Tato šipka není součástí textu, soubor lze tedy běžným způsobem editovat (ovšem pokud se rozhodneme smazat či přidat řádky, musíme být připraveni na to, že debuggovací informace o číslech řádků nebude odpovídat realitě a pozice této šipečky nebude odpovídat; v tomto případě je vždy lepší program překompilovat a spustit znovu).

Zmiňovaný GUD buffer používá variantu tzv. Shell módu. GUD mode navíc poskytuje příkazy pro práci s breakpointy, krokování programu a další. Tyto příkazy jsou dostupné jak uvnitř GUD bufferu, tak i globálně mimo tento buffer, ovšem v obou případech s jinými klávesovými zkratkami. Nastavování breakpointů (český překlad „místo přerušení běhu programu“ je příliš dlouhý a málo přehledný) budeme nejčastěji používat přímo na konkrétním místě v kódu programu. Globálně je pro práci s breakpointy (pro nastavení i mazání) definována klávesová kombinace C-x <SPC>, která nastaví/odstraní breakpoint na řádku, kde se nachází kurzor. Všechny ostatní klávesové zkratky lze rozlišit pomocí předpon: C-c pro příkazy uvnitř GUD bufferu, C-x C-a pro příkazy použitelné globálně, tedy vně GUD bufferu (ale také uvnitř GUD bufferu).

bitcoin školení listopad 24

Příkazů a následně i klávesových zkratek je k dispozici celá řada a záleží na nátuře, kolik si jich kdo osvojí. Nutno podotknout, že uvnitř GUD bufferu lze s debuggerem pracovat stejným způsobem, jakým se s ním pracuje vně Emacsu, tedy pomocí zadávání příkazů. Přesto se pokročilý uživatel později uchýlí k alespoň základním zkratkám, jako například krokování, jehož zkratky odpovídají mnemotechnicky příkazům debuggeru (např.: C-c C-s uvnitř GUD bufferu pro provedení jednoho řádku, apod.). Podrobnosti lze jako vždy nastudovat v manuálu. Práci s rozhraním knihovny lze poměrně široce upravit vlastním nárokům. Jako návnada pro stále ještě nerozhodnuté a pro ty, kteří zároveň pracují s Emacsem v grafickém prostředí, od verze 21 je k dispozici tzv. GUD tooltip facility. Posuneme-li kursor myši nad proměnnou, zobrazí Emacs její obsah v tzv. balónové nápovědě (tooltipu).

V příštím dílu stále ještě zůstaneme u komunikace Emacsu s okolím, podíváme se, jak pracovat se softwarem pro správu verzí, zejména s CVS, a jak si poradit v případě konfliktů mezi verzemi.