Page 1

E N C Y K LO P E D I E

ZO N E R

P R E S S

Programmer to ProgrammerTM

Linux

Profesionálně ®

programování aplikací Jon Masters, Richard Blum

www.zonerpress.cz


Linux PROFESIONÁLNĚ programování aplikací

Jon Masters a Richard Blum


Professional Linux Programming Jon Masters, Richard Blum Published by Wiley Publishing, Inc., 10475 Crosspoint Boulevard, Indianapolis, IN 46256, www.wiley.com. Copyright © 2007 by Wiley Publishing, Inc., Indianapolis, Indiana. © Translation: ZONER software, s.r.o., 2008. All Rights Reserved. This translation published under license with the original publisher John Wiley & Sons, Inc. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Wiley Publishing, Inc. Všechna práva vyhrazena. Tento překlad je vydán na základě licenční smlouvy s John Wiley & Sons, Inc. Žádná část této publikace nesmí být reprodukována nebo předávána žádnou formou nebo způsobem, elektronicky ani mechanicky, včetně fotokopií, natáčení ani žádnými jinými systémy pro ukládání bez výslovného svolení Wiley Publishing, Inc.

Linux PROFESIONÁLNĚ – programování aplikací Autoři: Jon Masters a Richard Blum Copyright © ZONER software, s.r.o. Vydání první v roce 2008. Všechna práva vyhrazena. Zoner Press Katalogové číslo: ZR713 ZONER software, s.r.o. Nové sady 18, 602 00 Brno Překlad: Vilém Gutfreund, Pavel Macík, Jana Staurovská, Jan Kuklínek Odpovědný redaktor: Miroslav Kučera Šéfredaktor: Ing. Pavel Kristián DTP: Miroslav Kučera Trademarks: Wiley, the Wiley logo, Wrox, the Wrox logo, Programmer to Programmer, and related trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries, and may not be used without written permission. All other trademarks are the property of their respective owners. Wiley Publishing, Inc., is not associated with any product or vendor mentioned in this book. The Wrox Brand trade dress is a trademark of John Wiley & Sons, Inc. in the United States and/or other countries. Used by permission. Ochranné známky: Wiley, logo Wiley, Wrox, logu Wroxu a souvisejicí obchodní známky jsou ochrannými známkami nebo registrovanými ochrannými známkami vydavatelství John Wiley & Sons, Inc, nebo jejich poboček, ve Spojených státech a/ nebo ostatních zemích a nemohou být používány bez písemného oprávnění. Všechny ostatní ochranné známky jsou majetkem jejich vlastníků. Wiley Publishing, Inc. není propojen s jakýmkoliv produktem nebo výrobcem zmíněným v této knize. Obchodní značka Wrox je ochrannou známkou John Wiley & Sons, Inc. ve Spojených státech a/nebo ostatních zemích. Veškeré dotazy týkající se distribuce směřujte na: Zoner Press ZONER software, s.r.o. Nové sady 18, 602 00 Brno tel.: 532 190 883, fax: 543 257 245 e-mail: knihy@zoner.cz http://www.zonerpress.cz

ISBN 978-80-86815-71-8


Pro Karin, kterou tolik miluji – Jon Masters Mé ženě Barbaře – Richard Blum


4

O autorech Jon Masters je pětadvacetiletý autor a expert na linuxové jádro a zabudované systémy. Narodil se ve Velké Británii, ale v současné době žije v USA, kde pracuje pro firmu Red Hat. Do historie Velké Britániie se zapsal jako jeden z nejmladších univerzitních studentů, které tato země pamatuje – bylo mu pouhých 13 let. V době, kdy se jeho vrstevníci blížili k závěru svého prvního vysokoškolského studia, měl už za sebou dvě vysoké školy a přes stovku publikací v širokém spektru technických časopisů, sborníků a knih. Pracoval pro několik nadnárodních technologických společností. Intenzivně se věnoval oblastem zabudovaných systémů, podnikového nasazení Linuxu a vědecké přístrojové techniky a pomáhal s návrhem všeho možného – od set-top boxů až po novou generace zařízení pro nukleární magnetickou rezonanci. Když náhodou nepracuje pro firmu Red Hat na produktu Enterprise Linux, rád si dá čaj na Boston Common nebo si přečte sebrané spisy Thomase Paina a dalších velkých amerických revolucionářů minulosti. Sní o době, když svět neovládaly elektrony, ale dřevěné plachetnice. Hraje na housle a příležitostně zpívá v pěveckých sborech, za což již obdržel několik cen. Rád si odpočine při horolezectví. Žije v Cambridge v Massachusetts, od historického centra Bostonu jej dělí pouze řeka Charles a moc se mu tam líbí. Jon má bohaté zkušenosti s přednášením o mnoha různých linuxových technologiích a s jejich výukou a rád se aktivně zapojuje do dění linuxových uživatelských skupin s po celém světě. Richard Blum déle než 18 let pracoval jako správce sítě pro velkou americkou vládní organizaci. Během této doby měl mnoho příležitostí pracovat nejenom se servery od společností Microsoft a Novell, ale také s unixovými a linuxovými servery. Aplikace vytvářel v jazycích C, C++, Java, C# a Visual Basic. Rich je bakalářem elektrotechniky a magistrem managementu se specializací na řídící informační systémy; oba tituly získal na Purdue University. Napsal několik knih, jmenujme například "sendmail for Linux" (2000, Sams Publishing), "Running qmail" (2000, Sams Publishing), "Postfix" (2001, Sams Publishing), "Open Source E-mail Security" (2001, Sams Publishing), "C# Network Programming" (2002, Sybex), "Network Performance Open Source Toolkit" (2003, John Wiley & Sons) a "Professional Assembly Language Programming" (2005, Wrox). Když zrovna nesedí za počítačem, hraje na elektrickou baskytaru v církevní kapele nebo tráví svůj čas se svou ženou Barbarou a dcerami Katie, Jane a Jessicou.


5

Poděkování Toto poděkování píši v den svých 25. narozenin, po mnoha dlouhých večerech, které jsem minulý rok strávil doháněním termínů, plánováním a dokonce občas i nějakým psaním. Když jsem se poprvé rozhodl napsat tuto knihu, vůbec jsem si nedovedl představit to množství práce, která je potřebná pro dokončení takového projektu a ani obtíže, se kterými jsem se přitom musel vypořádat. Knihu jsem začal psát na okraji Londýna a dokončil ji za necelý rok ve svém novém domově v massachusettském Cambridge, protože jsem se rozhodl svou rodnou zemi opustit. V průběhu minulého roku se v mém osobním i profesním životě změnilo mnoho věcí, ale mám skvělé přátele a příbuzné, kteří mi s těmito změnami pomohli. Především bych chtěl poděkovat týmu, se kterým jsem pracoval v nakladatelství Wiley – Debře, Adaobimu, Kitovi, Howardovi a Carol stejně jako mnoha dalším, kteří dohlížejí na to, aby se z rukopisu stala hotová kniha. Zvláštní poděkování si zaslouží Kit Kemper, který akceptoval můj časový harmonogram psaní (a kterému se nějak podařilo zařídit, že vyšel) a Debra Williams-Cauley, která uvěřila tomu, že tento projekt je dobrý nápad. Výborná redaktorská práce, kterou odvedl Howard Jones, mi pomohla, abych psal poctivě. Tato kniha by nevznikla bez inspirace, kterou mi poskytli mí dobří přátelé (a někdejší šéfové) Malcolm Buckingham a Jamie McKendry z Resonance Instruments (později Oxford Instruments), kteří si neustále stěžovali na nedostatek knih věnovaných programování v Linuxu. Kniha za svůj vznik také vděčí milým příspěvkům od mých několika dobrých přátel – děkuji vám Kat a Davide Goodwinovi, Matthewe Waltone a Chrisi Aillone. Děkuji také Richardu Blumovi, který se ke mně a k celému týmu přidal, když mi začalo být jasné, že bych svou práci nestihl dokončit včas. Všichni jste odvedli skvělou práci! Při psaní mi pomáhala moje skvělá rodina – mí rodiče Paula a Charles, sestry Hannah a Holly, můj švagr Joe. Občas přišla i nějaká inspirace od mých babiček. Mohl jsem si také užívat s těmi nejlepšími přáteli, jaké si člověk může přát – je jich tolik, že každého zde uvést nemohu, nicméně bych chtěl zmínit alespoň Husseina Jodiyawalla, Johannese Klinga, Bena Swana, Paula Sladena, Markuse Koblera, Toma Hawleyho, Sidarshana Guru Ratnavellu, Chrise Balla a Mada (a jejich kočku Zoe), Emmu Maule, Johna a Jana Buckmanovy, Tobyho Jaffeyho a jeho Sáru, Svena Thorstena-Dietricha, Billa Weinberga, Daniela Jamese, Joea Casadu a Andrewa Huttona společně Emílií. Obzvláště děkuji svým přátelům ze společnosti Red Hat, svému šéfovi a všem ostatním, tvrdě pracujícím lidem, díky kterým je naše společnost tím nejlepším pracovním místem na světě. Red Hat skutečně ví, co to znamená pracovat s Linuxem a já jsem z celého srdce vděčný, že mohu pracovat v prostředí, které přesně v duchu linuxové komunity podporuje mé zapojení do různých projektů – díky chlapi, jste opravdu profesionálové. A nakonec bych chtěl poděkovat Karin Worleyové za její přátelství, které v závěrečných fázích tohoto projektu mělo nepochybně hodně příležitostí k otálení. Karin, nejsem si jistý, zdali bych schopen dokončit tuto knihu bez toho nově objeveného pocitu štěstí, který vstoupil do mého života. Jon Masters Cambridge, Massachusetts


6 Děkuji výtečnému týmu z Wiley, kteří v tomto projektu odvedli vynikající práci. Děkuji Kitu Kemperovi, náborovému redaktorovi, který mi umožnil na této knize pracovat. Děkuji také Howardu Jonesovi, odpovědnému redaktorovi, který držel všechny věci na uzdě a významně se zasloužil o to, že tato kniha vznikla. Chtěl bych také poděkovat Carol McClendonové z Waterside Productions, Inc., která mi tuto příležitost zprostředkovala a pomohla mi v mé spisovatelské dráze. A nakonec bych chtěl poděkovat svým rodičům, Mikovi a Joyce Blumovým, za jejich oddanost a podporu, se kterou mě vychovali, a své ženě Barbaře a dcerám Katie Jane a Jessice za jejich lásku, trpělivost a porozumění, zejména v dobách, kdy píšu nějakou knihu. Richard Blum


7

Obsah O autorech

4

Poděkování

5

Úvod

14

Pro koho je tato kniha určena

15

Co obsahuje tato kniha?

15

Jak je tato kniha uspořádána?

16

Konvence

16

Zdrojový kód

17

Sdělte nám svůj názor

17

Kapitola 1

Pracujeme s Linuxem

Stručná historie Linuxu Projekt GNU

19 20 20

Jádro Linuxu

21

Linuxové distribuce

22

Svobodný software a open source

23

Začátek vývoje

24

Výběr linuxové distribuce Instalace linuxové distribuce Komunita kolem Linuxu

25 28 35

Linuxové uživatelské skupiny

35

E-mailové konference

36

IRC

36

Soukromé komunity

36

Klíčové rozdíly mezi systémy

37

Linux je modulární

37

Linux je přenositelný

37

Linux je obecný

38

Shrnutí

Kapitola 2

38

Toolchain

Vývojářský proces v Linuxu

39 39

Práce se zdrojovými kódy

40

Konfigurace lokálního prostředí

41

Kompilace zdrojových kódů

42

Komponenty GNU Toolchain

43


8 Kolekce kompilačních nástrojů GNU binutils

44 56

GNU Make 61 GNU debugger

62

Jádro Linuxu a GNU Toolchain

66

Inline assembler

66

Atributy značek

67

Uživatelské skripty linkeru

68

Křížová kompilace

69

Kompilace GNU Toolchain

70

Shrnutí

71

Kapitola 3

Přenositelnost

73

Povídání o přenositelnosti

74

Přenositelnost Linuxu

75

Vrstvy abstrakce

76

Distribuce Linuxu

77

Kompilace balíčků

83

Přenositelný zdrojový kód Mezinárodní podpora

98 111

Přenositelnost hardwaru

119

64bitová čistota

120

Neutralita endianity

121

Svaté války endianity

123

Shrnutí

Kapitola 4

124

Správa zdrojových kódů

125

Proč potřebujeme SCM

126

Centralizovaný vs decentralizovaný vývoj

127

Centralizované systémy

128

CVS – systém pro sledování verzí

128

Subversion

138

Decentralizované nástroje

142

Bazaar-NG

143

SCM pro jádro Linuxu (git)

147

Integrované nástroje SCM Eclipse Shrnutí

151 151 153


9 Kapitola 5

Síťové programování

Programování linuxových socketů

155 155

Sockety

156

Síťové adresy

158

Použití spojově orientovaných socketů

159

Použití nespojovaných socketů

167

Přesuny dat

170

Datagramy versus datové proudy

170

Označování hranic zprávy

174

Knihovny pro síťové programování

177

Knihovna libCurl

178

Použití knihovny libCurl

179

Shrnutí

Kapitola 6

186

Databáze

Trvalé uložení dat

187 187

Použití standardního souboru

188

Použití databáze

188

Balíček Berkeley DB

190

Stažení a instalace

191

Kompilace programů

192

Základní práce s daty

193

Databázový server PostgreSQL

203

Stažení a instalace

204

Kompilace programů

205

Tvorba databáze pro aplikaci

206

Připojení k serveru

208

Spouštění příkazů SQL

212

Používání parametrů Shrnutí

Kapitola 7

220 224

Vývoj jádra

Začátek

225 225

Základní předpoklady

226

Zdrojové soubory jádra

227

Konfigurace jádra

231

Kompilace jádra

235

Zkompilované jádro

239


10 Testování jádra Zabalení a instalace jádra Koncepty jádra

240 243 243

Varování

244

Abstrakce úlohy

244

Virtuální paměť

250

Nepanikařte

254

Hackování jádra

254

Natažitelné moduly Proces vývoje jádra

255 258

Git – "hloupý sledovač obsahu"

258

LKML, e-mailová konference o jádru Linuxu

260

Vývojový strom "mm"

262

Stabilní tým jádra

263

LWN, Linux Weekly News

263

Shrnutí

Kapitola 8

263

Rozhraní jádra

Co je rozhraní?

265 265

Nedefinovaná rozhraní

266

Externí rozhraní jádra

267

Systémová volání

268

Abstrakce souboru

274

Události jádra

290

Ignorování ochrany jádra Vnitřní rozhraní jádra

291 295

API jádra

296

ABI jádra

296

Shrnutí

Kapitola 9

298

Moduly jádra Linuxu

Jak moduly pracují Rozšíření jmenného prostoru jádra Nalezení kvalitní dokumentace Manuálové stránky jádra Linuxu Psaní modulů jádra Linuxu

299 299 302 304 304 306

Než začnete

306

Základní požadavky modulů

307

Logování

310


11 Exportované symboly

311

Alokace paměti

313

Několik úvah o uzamykání

321

Odložení práce

330

Další čtení

338

Distribuce modulů jádra Linuxu

338

Přechod k upstreamu

338

Dodání zdrojových souborů

339

Dodání již zkompilovaných modulů

339

Shrnutí

Kapitola 10

340

Ladění

Přehled ladění

341 341

Pár slov o správě paměti Základní nástroje pro ladění

342 343

GNU debugger

343

Valgrind

353

Grafické ladicí nástroje

354

DDD

355

Eclipse

357

Ladění jádra

360

Nepanikařte!

361

Chápeme oops

362

Použití UML pro ladění

364

Zábavná anekdota

369

Poznámka o debuggerech jádra Shrnutí

Kapitola 11

369 370

Vývojová platforma GNOME

Knihovny v GNOME

371 371

Glib

372

GObject

372

Cairo

372

GDK

373

Pango

373

GTK+

373

libglade

374

GConf

374

GStreamer

374


12 Vybudování přehrávače hudby

375

Požadavky

375

Začínáme: hlavní okno

376

Sestavení GUI

378

Shrnutí

Kapitola 12

398

Projekt FreeDesktop

399

D-BUS: Desktop Bus

399

Co je D-Bus

400

Pozadí D-Busu

400

Metody D-Busu

404

Vrstva abstrakce hardwaru

409

Přimějte hardware k fungování

409

Objekty zařízení HAL

412

FreeDesktop NetworkManager

418

Další projekty FreeDesktopu

420

Shrnutí

421

Kapitola 13

Grafika a zvuk

Linux a grafika

423 423

X Windows

424

OpenGL

426

OpenGL Utilities Toolkit

427

Simple Directmedia Layer

427

Vytváření aplikací OpenGL

427

Stažení a instalace

428

Programovací prostředí

429

Použití knihovny GLUT

430

Vytváření SDL aplikací

445

Stažení a instalace

445

Programovací prostředí

446

Použití knihovny SDL Shrnutí

Kapitola 14

446 458

LAMP

459

Co je LAMP?

459

Apache

460

MySQL

460


13 PHP

461

"Pirátská platforma"

461

Zvažování platformy LAMP

462

Apache

464

Virtuální hostitelé

464

Instalace a konfigurace PHP 5

466

Základní autentizace Apache

467

Apache a SSL

468

Integrace SSL s HTTP autentizací MySQL Instalace MySQL

468 469 469

Konfigurace a spuštění databáze

470

Změna výchozího hesla

470

Rozhraní klienta MySQL

471

Relační databáze

471

SQL

472

Relační model

475

PHP

478 Jazyk PHP

478

Základy jazyka

479

Funkce

483

Viditelnost

484

Obsluha chyb

488

Obsluha chyb s výjimkami

489

Optimalizační techniky

491

Instalace dalšího software pro PHP

496

Protokolování

496

Ošetření zadaných parametrů

497

Správa relací

499

Testování jednotek

499

Databáze a PHP

501

Pracovní rámce pro PHP

502

Knihovna DVD

502

Verze 1 – noční můra vývojáře

503

Verze 2 – základní aplikace s konkrétní datovou vrstvou

504

Verze 3 – přepsání datové vrstvy, doplnění protokolování a výjimek

508

Verze 4 – použití šablonového systému

512

Shrnutí

513

Rejstřík

515


14

Úvod Linux v několika posledních letech urazil velký kus cesty. Po relativně skromných začátcích se dostal do pozice, kdy je na něm závislá celá řada společností z žebříčku Fortune 500. Vše – počínaje vaším mobilním telefonem a největšími superpočítačovými clustery konče – je nyní založeno na linuxovém jádře a distribucích postavených kolem něj. Ale co je to vlastně Linux? V čem se liší od jiných operačních systémů rodiny UNIX, které jsou dnes na trhu k dispozici? A co víc – jak můžete ve vašich projektech využít plnou sílu Linuxu a s tím související revoluci svobodného software? Tato kniha si klade za cíl zodpovědět tyto a další otázky. Jejím skutečným smyslem je sdělit vám, čtenářům, proč je Linux jedinečný, a přitom jít do větší hloubky, než je obvyklé u základních příruček pro začátečníky. Autor se během své dosavadní kariéry profesionálního programátora dostal do situací, kdy spolupracoval s velmi znalými softwarovými inženýry, kterým ovšem chyběly hlubší zkušenosti s Linuxem. Někteří z nich se snažili najít knihu, jako je tato, nicméně neúspěšně. Tato kniha, která je zrozena z jejich zklamání, by vám měla pomoci pochopit mocné působení linuxové komunity, model používaný pro vývoj software a způsob, jakým se provádějí věci ve světě Linuxu. Existuje mnoho jiných knih, které o sobě tvrdí, že se věnují programování v Linuxu. Většina z nich je opravdu výborná, ale příliš často se zaměřují na věci, ve kterých Linux pouze následuje své předchůdce. Tohle v této knize nenajdete, protože jejím zaměřením není to, co má Linux společného se starými unixovými systémy. Naopak. Tato kniha je o moderním operačním systému Linux a nepatří mezi ostatní knihy o programování v Unixu. Snaží se vám nejenom detailně vysvětlit, v čem vlastně tkví ten neuvěřitelný úspěch Linuxu, ale také se snaží předvést některé části systému, které ostatní knihy o Linuxu zmiňují ve stručnosti, nebo je zcela opomíjejí. V této knize se dozvíte, co představuje základ vývoje v Linuxu. Seznámíte se širokou paletou nástrojů, které linuxoví vývojáři běžně využívají při své práci – kompilátory, debuggery či nástroje pro správu verzí – a jak s nimi vytvářejí aplikace, nástroje, pomůcky a dokonce i samotné jádro Linuxu. Dozvíte se zajímavé informace o jedinečných komponentách linuxového systému, díky kterým se odlišuje od ostatních unixových systémů. Společně se také dostaneme i k popisu různých vnitřních mechanismů Linuxu. Dále pak poznáte různé vývojářské metody, včetně virtualizačních technologií a křížové kompilace, která představuje vhodný způsob, jak zkompilovat software pro různé kompatibilní platformy. Dále se naučíte používat Linux společně s Internetem a zkusíte si vytvořit software pomocí vyhlášené platformy LAMP (Linux, Apache, MySQL, Perl/Python). Linux znamená mnohem více, než samotné jádro – a jako linuxový vývojář byste si tuto skutečnost měli uvědomit. Tato kniha je hlavně o učení. Má vám přednést rozbor klíčových témat, která hýbou linuxovým vývojem, abyste mohli snáze objevovat svět svobodných softwarových projektů. Až si ji kompletně přečtete, měli byste získat přehled o všem, co potřebujete vědět. Tato kniha vám neposkytne odpověď na každou otázku, ale budete schopni se dále sami vzdělávat. Věřím, že tato kniha pro vás bude přínosná, ať už vytváříte svobodný software, nebo pracujete na velkých komerčních softwarových projektech.


15

Pro koho je tato kniha určena Tato kniha je napsána pro dvě různé skupiny čtenářů. Tou první a významnější jsou stávající programátoři, kteří přemýšlejí o přechodu na Linux. Tito čtenáři již mají nějaké znalosti programovacího jazyka C a chápou základní myšlenky – kompilátory, linkery, debuggery atd. Pravděpodobně již četli nějakou knihu, která se úvodu do této oblasti věnovala – např. knihu Beginning Linux Programming (Wiley 2004), ale zatím jim chybějí praktické zkušenosti. Jestliže jste v oblasti profesionálního vývoje software pro Linux nováčkem, mělo by vám použité uspořádání knihy vyhovovat. Měli byste být schopni ji přečíst v kuse – od začátku do konce. Materiál věnovaný jádru (kapitoly 7 až 9) můžete přeskočit a zaměřit se více na aplikace vyšší úrovně a na nástroje, které se používají v běžných projektech mimo linuxové jádro. Budou se vám zejména hodit kapitoly věnované různým nástrojům, přenositelnosti a systémům pro správu verzí. Tato kniha také obsahuje materiál zaměřený na linuxové nadšence, manažery a ostatní lidi, kteří projevují zájem o Linux, používají jej ve svém každodenním životě a chtějí opravdu porozumět chodu běžného linuxového systému – aniž by přitom museli vyvíjet software. Jak moderní linuxový systém provádí detekci hardware? Proč linuxové jádro neposkytuje jednotný model pro ovladače zařízení? Jak Linux podporuje národní prostředí? Najdete zde odpovědi na mnoho otázek. Ti, kteří již s Linuxem nějaké zkušenosti mají, nebudou muset knihu číst celou, ale přesto i pro ně se v každé kapitole najde něco zajímavého. Poznámky a různé komentáře obsahují příklady a rady, se kterými jste se možná ještě nesetkali. Najdete mezi nimi i historky a různá poučení, ke kterým dospěli ostatní. Pravděpodobně se ale více zaměříte na pozdější kapitoly, které jsou věnované linuxovému jádru, desktopovému prostřední a LAMP. Tato kniha vám tedy pomůže, ať již programujete pro platformu Microsoft Windows a máte pouze základní znalosti Linuxu a UNIXu, které si chcete rozšířit, nebo už hodně dlouho patříte mezi nezdolné unixové programátory, které zajímá, jakým způsobem Linux vlastně funguje.

Co obsahuje tato kniha? Tato kniha popisuje širokou paletu technologií, které se používají při vývoji linuxového softwaru. Naleznete zde nejenom přehled historie moderních unixových a linuxových systémů, ale také informace o přenositelnosti mezi jednotlivými platformami a nástrojích, které k tomuto účelu v moderních linuxových distribucích slouží. Dozvíte se více informací o interakci linuxových systémů prostřednictvím síťových rozhraní, o grafických uživatelských rozhraních, o složitých webových systémech založených na platformě LAMP a dokonce neopomeneme problematiku rozšiřování samotného jádra Linuxu. Zkrátka vše, co vývoj v Linuxu v současné době zahrnuje. Tato kniha reflektuje situaci, která byla aktuální v době, kdy byla napsána, nicméně verze software se v průběhu času pochopitelně mění. Z tohoto důvodu většina témat nevyžaduje nějakou konkrétní verzi nástroje, zdrojového kódu nebo balíčku. Na místech, kde se mluví o konkrétním vydání, jste na tuto skutečnost upozorněni. V opačném případě předpokládejte, že uvedené příklady budou pracovat s jakoukoliv novější linuxovou distribucí, kterou budete mít k dispozici.


16

Jak je tato kniha uspořádána? Tuto knihu lze volně rozdělit do čtyř částí. V prvních několika kapitolách naleznete informace o základních nástrojích a technologiích, které vám mají usnadnit život profesionálního linuxového programátora. Poznáte GNU Toolchain, význam přenositelnosti software, nutnost respektovat národní prostředí a mnoho dalších témat, jejichž cílem je, abyste zvládli sami pracovat na svých projektech. Tento materiál byste si měli přečíst jako první. Je možné, že později se k němu budete docela často vracet. Druhá část knihy se zabývá nízkoúrovňovými komponentami linuxového systému. Jedná se o témata tradičního systémového programování – včetně sítí, databázových pojmů a linuxového jádra. Tento materiál můžete použít k tomu, abyste lépe pochopili ty oblasti, které vás zajímají, nicméně nepočítejte s tím, že bude zcela vyčerpávající. Toto se hlavně týká hlavně pasáží věnovaných jádru, které mají za úkol povzbudit vaši zvědavost. Ve třetí části této knihy se společně podíváme na komponenty vyšší úrovně, včetně prostředí GNOME a jeho knihovny. Dozvíte se o projektu FreeDesktop a budete mít příležitost vytvořit vlastní CD přehrávač pomocí výkonné knihovny GStreamer, kterou využívají současné multimediální aplikace pro GNOME. Dále zjistíte, co všechno můžete dokázat díky opětovnému využití softwaru, a získáte základní představu o tom, jak psát vlastní aplikace pro GNOME. Poslední kapitola této knihy je pak věnována platformě LAMP. Jejím základem je svobodný software – Linux, Apache, MySQL a Perl (nebo Python), který vám umožňuje vytvářet velmi výkonné webové aplikace. Tato kapitola vás seznámí s jednotlivými komponentami platformy LAMP a předvede několik příkladů jejich použití.

Konvence Abyste si mohli z textu této knihy odnést co nejvíce a mohli jej snadno sledovat, používáme v knize několik následujících konvencí. Rámečky, jako je tento, obsahují důležité informace, které přímo související s okolním textem, a které byste si měli zapamatovat.

Co se týče použitého formátování v textu: 

Klávesové zkratky píšeme takto: Ctrl+A



Názvy souborů, URL a kód v textu píšeme takto: persistence.properties



Zdrojový kód uvádíme dvěma způsoby: V ukázkách kódu zdůrazňujeme nové a důležité úseky tučným řezem. Šedé zvýraznění není použito u kódu, který není v dané souvislosti tolik podstatný, nebo se neobjevuje poprvé.


17

Zdrojový kód Když si budete procházet příklady v této knize, můžete zdrojový kód opisovat ručně, nebo můžete použít doprovodné soubory ke knize. Veškeré zdrojové kódy, které jsou použité v této knize, jsou dostupné ke stažení na následující adrese (velikost 545 KB): http://zonerpress.cz/download/zdrojove-kody-linux-profesionalne.zip

Až si zdrojové kódy stáhnete, jednoduše je rozbalte vaším komprimačním nástrojem.

Sdělte nám svůj názor Jako čtenáři této knihy se stáváte těmi nejdůležitějšími kritiky a komentátory. Vážíme si vašeho názoru a chtěli bychom vědět, co děláme správně, co bychom mohli dělat lépe, ve kterých oblastech bychom měli publikovat a uvítáme také vaše další podnětné myšlenky, o které jste ochotni se s námi podělit. Jako odborný redaktor Zoner Press vítám vaše názory. Můžete mi psát – poslat e-mail nebo dopis – a sdělit mi, co se vám v této knize líbilo, nebo nelíbilo, stejně tak, co bychom měli udělat, aby naše další knihy byly lepší. Pokud mi napíšete, nezapomeňte prosím připojit název knihy, ISBN, jméno autora, vaše jméno, telefon, fax nebo e-mail. Pozorně zhodnotím vaše názory a poskytnu je autorovi a redaktorům, kteří pracovali na této knize. Prosím, vězte, že nemohu pomoci s technickými problémy, které se týkají obsahu knihy, a že díky velkému množství e-mailů, které dostávám, nemohu zaručit odpověď na každou zprávu. E-mail: miroslav.kucera@zoner.cz nebo knihy@zoner.cz. Adresa: Zoner Press, ZONER software, s.r.o., Miroslav Kučera, Nové sady 18, 602 00 Brno.


18


KAPITOLA 1 Pracujeme s Linuxem Jeden z největších kamenů úrazu při vytváření softwaru pro Linux je pochopení toho, co Linux je, a co není. Linux pro různé lidi znamená různé věci. Z technického pohledu je Linux jako takový jádro operačního systému, které bylo vytvořeno Linusem Torvaldsem, nicméně většina lidí si pod termínem Linux vybaví robustní operační systém. Za několik málo let Linux povstal z temnot a stal se široce akceptovaným u všech skupin uživatelů. Linux se v dnešní době vyrovná ostatním operačním systémům dostupným na trhu. Často se používá nejenom v největších superpočítačích, ale současně ve spoustě nejmenších přístrojů, u kterých byste nikdy nepředpokládali, že mohou být založeny na Linuxu. Teď ve svém rozmachu – díky velkému jménu v moderních technologiích – Linux není vlastněn žádnou velkou společností, která by tahala za provázky. Linux je úspěšný díky mnoha tisícům vývojářů po celém světě, kteří se neustále snaží udělat Linux lepším. Tito lidé se (stejně jako vy) zajímají o vytváření velmi kvalitního softwaru, který zvyšuje zkušenosti ostatních v linuxové komunitě. Ať už pro vás osobně Linux znamená cokoliv, tuto knihu čtete pravděpodobně z toho důvodu, že se chcete naučit více o tom, jak se stát profesionálním linuxovým programátorem. Protože jste si zvolili tuto dráhu, brzy nepochybně zjistíte, že bude velmi užitečné, když pochopíte různé věci kolem Linuxu, například to, jakým stylem se Linux vyvíjí nebo v čem je odlišná práce v Linuxu od práce s jinými platformami, které jsou dnes dostupné na trhu. Pokud sebe považujete za experta v Linuxu, bude stačit, když tuto kapitolu pouze proletíte očima. Pokud teprve pracujete na tom, abyste se jím stali, tato kapitola vám rozhodně poskytne několik užitečných informací do začátku. V této kapitole se dozvíte více informací o tom, co Linux vlastně je a jakým způsobem spolupracují jednotlivé části linuxové distribuce z hlediska profesionálního programátora. Naučíte se více o vývojovém procesu, který se skrývá za Free, Libre a Open Source Software (FLOSS), který se používá v linuxových systémech. Dále objevíte přínos online komunit, které posilují revoluci v oblasti otevřeného kódu. A na závěr kapitoly si popíšeme několik rozdílů mezi Linuxem a jinými operačními systémy, se kterými jste se pravděpodobně v minulosti setkali. Takže – jdeme na to!


20

Kapitola 1 – Pracujeme s Linuxem

Stručná historie Linuxu Linux má velice rozmanitou a zajímavou historii, která se začala psát mnohem dřív, než si pravděpodobně myslíte. Historie Linuxu zahrnuje více než 30 let a začíná u prvních unixových systémů ze 70. let. Tento fakt není podstatný jenom pro nezdolné nadšence. Pro vás je důležité znát alespoň všeobecné informace z unikátní historie, která vedla k vytvoření moderních linuxových systémů, se kterými dnes pracujete. Pochopení historie Linuxu vás nejenom lépe připraví na zvládnutí různých výstředností, které odlišují Linux od jiných alternativ na trhu, ale také pomůže udělat vývoj Linuxu mnohem zajímavějším. První práce na Linuxu jako takovém začaly v létě 1991, ale dlouho předtím, než se objevil Linux, existoval projekt GNU. Tento projekt byl zaměřen na svobodný software a byl inspirován operačními systémy unixového typu. Původním cílem projektu bylo vyvinout operační systém se svobodnou licencí, který by neobsahoval žádný kód z původního UNIXu. Musíme říci, že bez tohoto projektu by Linux asi nikdy nevznikl, a kdyby neexistoval Linux, v této knize byste nenalezli žádné informace o projektu GNU. Oba projekty totiž těží jeden z druhého, jak sami zjistíte v této knize.

Projekt GNU V roce 1983 Richard Stallman (aka RMS) pracoval v laboratoři MIT zabývající se umělou inteligencí. V této době bylo velké množství aplikací k dispozici ve formě zdrojového kódu, aby uživatelé mohli v případě potřeby upravit kód aplikace pro svůj systém. V této době se ovšem současně začínal prosazovat velmi zajímavý trend – stále větší a větší množství výrobců softwaru totiž začínalo distribuovat pouze binární verze svých aplikací. A toto nakonec vedlo k tomu, že zdrojový kód aplikací se velmi rychle stal "obchodním tajemstvím" společností, které tímto způsobem chtěly ochránit svou práci před konkurencí. Počátečním cílem projektu GNU bylo vytvořit svobodný operační systém podobný UNIXu, který by obsahoval všechny nástroje a programy ve formě zdrojového kódu. Vytvoření většiny těchto nástrojů, programů (včetně kompilátoru GCC a textového editoru GNU Emacs) a dokumentace k nim trvalo více než deset let. Mnoho z těchto nástrojů získalo vynikající pověst díky své vysoké kvalitě a bohatým možnostem – jmenujme například kompilátor GCC nebo GNU debugger. Ačkoliv projekt GNU zaznamenal velký úspěch, v průběhu 80. let mu stále chyběl jeden velmi důležitý prvek. Tímto prvkem bylo vlastní jádro operačního systému, což znamenalo, že uživatelé museli instalovat nástroje a programy z projektu GNU na různé komerční operační systémy jako byl proprietární UNIX. Ačkoliv uživatele, kteří používali GNU nástroje a programy na svých proprietárních systémech, tato skutečnost pravděpodobně moc netrápila, projekt GNU jako celek nemohl být kompletní bez vlastního jádra. Intenzivní diskuse o různých alternativách (jako je GNU HURD) trvaly celé roky, než konečně přišel na svět Linux. Linux ovšem nikdy nevytvořil tu část operačního systému GNU, kterou si Richard Stallman představoval. Ve skutečnosti to bylo tak, že projekt GNU ještě po mnoho let pokračoval v prosazování mikrojádra GNU HURD přes linuxové jádro v konceptuálním systému GNU, a to i přes skuteč-


Linux PROFESIONÁLNĚ – programování aplikací

21

nost, že Linux se stal ukázkovým "dítětem" pro novou generaci uživatelů a vývojářů (a to se ani nezmiňujeme o jeho mnohem větší popularitě). I přes tyto skutečnosti můžete i dnes často vidět termín GNU/Linux, který je použit pro označení kompletního linuxového systému, který používá velké množství nástrojů a aplikací pocházejících právě z projektu GNU.

Jádro Linuxu Jádro Linuxu vzniklo podstatně později než samotný GNU projekt – o více než dekádu po tom, co Richard Stallman přišel se svým počátečním vyhlášením. V této době se ostatní alternativní systémy stále nacházely ve vývoji, přičemž obsahovaly nejenom mikrojádro HURD, ale také výukové mikrojádro Minix, které bylo vytvořeno Andrewem Tanenbaumem. A z mnoha různých důvodů nebyl žádný z těchto alternativních systémů považován za natolik připravený, aby mohl být všeobecně používán koncovými uživateli. Tedy až do doby, než přišel Linux. Vše začalo tak, že mladý finský student, který pracoval na univerzitě v Helsinkách, začal být frustrován mnoha věcmi, jež považoval v Minixu1 za nesprávně fungující. Začal tedy pracovat na svém vlastním systému, který byl speciálně navržen pro jeho vlastní mikropočítač AT-386. V této době se jednalo o špičkový kus hardwaru. Tímto studentem byl Linus Torvalds a právě on vedl projekt, který později vedl ke vzniku velkého množství linuxových společností. 1

Některé z těchto problémů přetrvávaly po mnoho let, což dokazují různé diskuse v prvních minixových a linuxových diskusních skupinách. Protože Linux o několik let později potvrdil svou dominanci na trhu, další vývoj Minixu (a jeho různých nástupců) byl založen pouze na akademickém zájmu několika lidí, kteří přemýšleli nad budoucími návrhy operačních systémů.

Linus pak v létě roku 1991, při příležitosti vypuštění první verze Linuxu, poslal následující oznámení do diskusní skupiny comp.os.minic: Datum: 25Aug 91 20:57:07 GMT Organizace: Univerzita Helsinky Zdravím všechny, co používají Minix – vytvářím (zdarma) operační systém (pouze koníček, nic velkého a profesionálního jako GNU) pro AT klony 386 (486). Pracuji na tom od dubna a je to prakticky hotovo. Chtěl bych získal nějakou zpětnou vazbu ohledně toho, co máte a nemáte rádi na Minixu, protože můj OS je mu v některých věcech velmi podobný (z praktických důvodů například používám stejný návrh souborového systému). Aktuálně jsem naportoval bash (1.08) a gcc (1.40) a vypadá to, že to funguje dobře. To naznačuje, že za několik měsíců práce jsem vytvořil něco použitelného a chtěl bych vědět, které schopnosti požaduje většina lidí. Jakékoliv návrhy jsou sice vítány, nicméně neslibuji, že je nakone implementuji.


22

Kapitola 1 – Pracujeme s Linuxem

I přes Linusovu prvotní skromnost se zájem o toto linuxové jádro velmi rychle zvyšoval – a to po celém světě. To samozřejmě vedlo nejenom k vypuštění několika nových verzí, ale také k nárůstu komunity uživatelů. Tito uživatelé, kteří všichni bez výjimky patřili mezi zkušené vývojáře (protože i samotná instalace Linuxu vyžadovala velké znalosti), se dobrovolně zapojili do vyřešení různých technických výzev a implementace mnoha nových nápadů. S prvotním vývojem Linuxu je tak spojeno velké množství vývojářů, jejichž jména si dnes už nikdo nepamatuje. Tito lidé si užívali skutečnost, že mohou pracovat na moderním a svobodném systému podobném UNIXu, který netrpí komplexností návrhu alternativních systémů. Linuxoví vývojáři se při vývoji linuxového jádra a programování nových funkcí spoléhali na velké množství již existujících nástrojů GNU. Samozřejmě netrvalo dlouho a zájem o Linux vzrostl natolik, že uživatelé Minixu začali houfně přecházet na Linux, což vedlo k velmi bouřlivým diskusím mezi tvůrcem Minixu Andrewem Tanenbaumem a Linusem Torvaldsem. Tanenbaum tvrdil, že design Linuxu je podstatně nižší kvality než design Minixu. Z filozofického hlediska to sice může pravda, nicméně totéž může být řečeno také o ostatních moderních operačních systémech. Pokud vás více zajímá historie Linuxu a ostatních operačních systémů založených na UNIXu, doporučujeme k přečtění knihu A Quarter Century of UNIX, kterou napsal Peter H. Salus (Addison-Wesley, 1994).

Linuxové distribuce S rostoucí popularitou linuxového jádra přišel i zájem o vytvoření Linuxu, který by byl dostupný i lidem, kteří nemají potřebné znalosti v oblasti programování. Na vytvoření použitelného linuxového systému potřebujete více než jenom jádro. Skutečnost je taková, že libovolný linuxový systém, který je určen pro koncové uživatele, je dnes použitelný pouze díky mnoha tisícům existujících programů, jež zajišťují různé věci – od startu systému až po funkčnost grafického pracovního prostředí (jakým je například GNOME). Když byl Linux poprvé představen, neexistovalo pro něj velké množství softwaru. Abych byl přesný – Linus v té době pro něj nabízel pouze jednu jedinou aplikaci: GNU Bourne Again Shell (zkráceně bash, což v doslovném překladu znamená "znovunarozený příkazový řádek"). Lidé, kteří někdy nabootovali Linux nebo UNIX do omezeného jednouživatelského módu, kde běží jenom bash, ví moc dobře, o co se jedná. Linus pomocí příkazové řádky provedl mnoho počátečních testů Linuxu, jenže ta samozřejmě na Linuxu nefungovala hned od začátku. Aplikace bash musela být prvně naportována z nějakého již existujícího systému (jako je Minix) a poté případně upravena, aby mohla bez problémů fungovat na novém operačním systému. Když stále více a více lidí začalo používat a vyvíjet software pro Linux, pochopitelně se zvyšovalo množství dostupného softwaru pro ty, kteří měli trpělivost jej nainstalovat. Jak ovšem postupoval čas dopředu, bylo čím dál tím více zjevnější, že kompilace každé nové instalace Linuxu z ničeho je neuvěřitelně komplikovaná (a také nepodporovatelná a neaktualizovatelná) noční můra, která bránila nadšenému objevování toho, co Linux může nabídnout. Řešení této velmi problematické situace přišlo v podobě linuxových distribucí, což jsou v podstatě předem vytvořené kolekce růz-


Linux PROFESIONÁLNĚ – programování aplikací

23

ných nástrojů, aplikací a linuxového jádra, které mohou být rozšiřovány prostřednictvím diskety (později prostřednictvím CD a internetu) širokému okruhu zájemců. Prvotní distribuce Linuxu tak byly jednoduše vymoženostmi pro lidi, kteří se chtěli vyhnout zkompilování celého operačního systému z ničeho, a kteří se nechtěli zabývat hledáním a instalací nového softwaru. Než byly vynalezeny první správci balíčků (package managers) RPM v Red Hatu a dpkg v Debianu, obyčejní uživatelé v podstatě nebyli schopni Linux nainstalovat, pokud neměli znalosti na úrovni experta. Více informací o správcích balíčků se dozvíte později v této knize – konkrétně v části, kde se budeme věnovat kompilaci vaší vlastní linuxové distribuce. Moderní linuxové distribuce mají spoustu podob a velikostí, přičemž jsou určeny různým skupinám uživatelů. V současnosti tak existují nejenom distribuce pro koncové uživatele Linuxu, ale také robustní distribuce určené pro velké společnosti nebo distribuce pro různá kapesní zařízení, jako jsou PDA a chytré telefony (smartphone). I když tyto distribuce využívají odlišné balíčky, mají obvykle několik společných rysů, na které se můžete spolehnout. Například většina distribucí se snaží dosáhnout určité úrovně kompatibility s LBS (Linux Standard Base), což je v podstatě standard sloužící pro zajištění kompatibility jednotlivých linuxových prostředí.

Svobodný software a open source Richard Stallman odstartoval projekt GNU a založil neziskovou organizaci Free Software Foundation pro jeho zastřešení. Pracoval také na první verzi General Public License (GPL, všeobecná veřejná licence), pod kterou je licencováno velké procento softwaru běžícího na Linuxu. GPL je velmi zajímavý dokument, protože jeho cílem není omezovat použití licencovaného softwaru, ale chránit právo uživatelů a vývojářů na přístup ke zdrojovým kódům2. 2

V době, kdy byla psána tato kniha, podstupuje licence GPL velké změny. Nová verze licence bude pravděpodobně patřit mezi nejvíce kontroverzní licence pro svobodný software. Obsahuje totiž nejenom poznámky k licencování patentů a dalších technologií, ale také se snaží postavit mimo zákon DRM (digital right management, správa digitálních práv), což je souhrnný název pro technické postupy, jejichž účelem je kontrolovat nebo omezovat využívání obsahu digitálních médií.

GPL dovoluje dělat změny v jádru Linuxu a v ostatním svobodném softwaru vytvořeném pod GPL, a to za předpokladu, že provedené změny zpřístupníte ostatním, aby je mohli použít (nebo je začlenit do příští verze software). Např. licence GPL vám dovoluje opravit chybu ve velké aplikaci typu Open Office, nebo přidat podporu nějakého nového audio formátu do multimediálního přehrávače v desktopovém systému GNOME. GPL vám jako vývojářům nabízí obrovskou flexibilitu ohledně modifikace Linuxu pro libovolný účel, přičemž zveřejníte všechny změny, aby i ostatní mohli těžit z vašich úprav. Tohle je smysl GPL, která se snaží udržet vývojářský proces otevřený. Naneštěstí pro Richarda Stallmana angličtina není vybavena přesným ekvivalentem francouzského slova libre ("svobodný"), protože anglické slovo "free" je chápáno nejenom jako "svobodný", ale také jako "zdarma". To vede k tomu, že mnoho lidí si plete koncept svobodného softwaru (free soft-


24

Kapitola 1 – Pracujeme s Linuxem

ware) se softwarem, který je zdarma. V praxi je to sice tak, že drtivá většina svobodného softwaru je k dispozici zdarma, nicméně existují i organizace, které vydělávají peníze na poskytování technické podpory a dalších služeb k softwaru licencovanému pod GPL, který rovněž poskytují. Na snížení chaosu spojeného s termínem "free software" byl vytvořen pojem "open source" (doslova "otevřený zdroj"), který se stal velmi populárním v devadesátých letech. Na rozdíl od svobodného softwaru se termín "open source" výslovně nezaměřuje pouze na software licencovaný pod GPL. Místo toho se odkazuje na všeobecnou touhu po softwaru, který poskytuje své zdrojové kódy (takže může být vylepšován a opravován ostatními), i když samotný zdrojový kód se nachází pod mnohem přísnější licencí než je GPL. Z tohoto důvodu existuje velké množství softwaru, který splňuje definici termínu "open source", a jenž současně nepatří mezi svobodný software. Je velmi důležité, abyste pochopili požadavky, které GPL klade na práci, kterou můžete vykonat změnou existujícího softwaru licencovaného pod GPL. I když po vás není vyžadováno, abyste GPL licenci použili pro své programy, musíte respektovat práva ostatních, kteří tak učinili. Existuje velké množství situací, kdy je GPL licence porušena – obvykle firmami, které ani netuší, že své změny jádra Linuxu by měly zveřejnit, aby se na ně mohli podívat i ostatní. Protože určitě nechcete patřit do této skupiny, ujistěte se, že vy i vaši kolegové znáte licenci GPL a jsou vám zřejmá práva a povinnosti z ní vyplývající.

Začátek vývoje První krok, který jako vývojář Linuxu uděláte, je ten, že se vybavíte vším, co je potřeba na zvládnutí úloh, jež leží před vámi. To znamená, že budete potřebovat vhodný vývojářský systém, na kterém budete provádět kompilace a testování vašich vlastních linuxových programů. Ze začátku vám k této činnosti dobře poslouží jakákoliv pracovní stanice. Pokud ale plánujete pracovat na větším množství softwaru, pravděpodobně se neobejdete bez pořádně výkonné mašiny, která dokáže znatelně snížit dobu kompilace, takže je dobré naplánovat její pořízení. Chtěli bychom zdůraznit, že autoři této knihy vám nechtějí nařizovat, kterou distribuci Linuxu si máte stáhnout, nainstalovat a používat. Existuje velké množství dobrých linuxových distribucí, takže je vlastně jenom na vás, kterou si nakonec zvolíte. Rozhodně ale dává smysl se podívat na nejznámější distribuce (alespoň ze začátku), abyste měli přístup do velmi aktivních komunit vývojářů, kteří vám mohou ochotně poradit s řešením vašich prvních chyb, jež nepochybně přijdou. Na webu www.distrowatch.com můžete najít informace o nejnovějších trendech v moderních linuxových distribucích. Tento web také poskytuje ke každé distribuci odkazy na užitečné informační zdroje. Pokud nevíte, jaká distribuce Linuxu je pro vás nejvhodnější, podívejte se na webové stránky http://www.zegeniestudios.net/ldc, kde naleznete docela hezký test.


Linux PROFESIONÁLNĚ – programování aplikací

25

Výběr linuxové distribuce V době, kdy je psána tato kniha, existuje na světě kolem 300 linuxových distribucí, přičemž tohle číslo se zvyšuje každým dnem, takže v okamžiku, kdy čtete tuto knihu, můžete považovat tento údaj za zastaralý. Počet dostupných distribucí je velký hlavně díky domu, že skoro všechen software v průměrné distribuci Linuxu se nachází pod licencí GNU GPL, takže v podstatě kdokoliv může vzít existující nástroje a programy a udělat z nich balíček pro svou vlastní distribuci. Tím se sice podporuje iniciativa a experimentování, nicméně to může současně vést k nezvládnutelné noční můře pro ty, co se rozhodli vytvořit softwarové balíčky pro všech 300 distribucí. Naštěstí pro vás, jako softwarového vývojáře, většina uživatelů Linuxu, které budete chtít podporovat, používá pouze několik distribucí, obvykle těch nejznámějších. A ti uživatelé, kteří tyto distribuce nepoužívají, s velkou pravděpodobností používají distribuce, jež vychází z těchto populárních distribucí. Je potřeba si uvědomit, že nové distribuce obvykle vznikají na základě speciálních požadavků určité skupiny uživatelů, přičemž těmto uživatelům je zcela jasné, že podpora jejich speciální distribuce nikdy nebude na takové úrovni, jakou mají k dispozici uživatelé distribuce, kterou používají statisíce lidí. A zde je seznam deseti nejpopulárnějších distribucí v době psaní této knihy: 

Debian GNU/Linux.



Fedora (předtím známá jako Fedora Core).



Gentoo Linux.



Mandriva Linux.



Red Hat Enterprise Linux (RHEL).



Slackware Linux.



OpenSuSE.



SuSE Linux Enterprise Server (SLES).



Ubuntu.

Linuxové distribuce od Red Hatu Společnost Red Hat kdysi vytvořila linuxovou distribuci známou pod jménem Red Hat Linux (RHL). Tento název distribuce byl používán až do verze 0.9, kdy došlo k přejmenování této distribuce na Red Hat Enterprise Linux (RHEL). Přibližně ve stejném čase se distribuce Fedora od stejného výrobce stala komunitní distribucí pro všechny, kdo preferují kompletní open source verzi bez komerční podpory. Tato distribuce je velice populární mezi desktopovými uživateli a nadšenci, přičemž je široce používána nejenom vývojáři svobodného softwaru, ale také komerčními dodavateli, kteří potřebují ověřit funkčnost svého softwaru před tím, než ho přidají do verze Enterprise. Pro více informací o společnosti Red Hat se podívejte na web www.redhat.com. Projekt Fedora má svůj vlastní web na adrese www.fedoraproject.org.


KAPITOLA 4 Správa zdrojových kódů Tvorba moderního softwaru je složitý a zdlouhavý proces, který zahrnuje neustále se opakující kompilační cykly, starosti s chybami či nekonečné testování funkčnosti softwaru. Vývojáři jsou nuceni udržovat celý softwarový projekt v takovém stavu, aby bylo možné zajistit reprodukovatelnost výsledků, které byly získány během procesu kompilace a testování (a kromě toho jsou dále nuceni udržovat celkovou produktivitu). Ve světle těchto informací vás tudíž asi nepřekvapí skutečnost, že správa zdrojových kódů (SCM, Source Code Management) tvoří velkou část procesu vývoje softwaru. Toto mimo jiné znamená, že výběr toho správného řešení SCM je nejenom velmi důležitým, ale potenciálně i velmi nákladným procesem. Linuxoví vývojáři obvykle používají dvě diametrálně odlišné formy SCM. První z nich je založena na tradičním centralizovaném vývojovém modelu, v němž vývojáři upravují jednotlivé zdrojové soubory, přičemž své úpravy poskytují skrze nějaký centrální systém, který uchovává historii jednotlivých změn (takže není problém zjistit, kdo, kde a kdy provedl nějakou úpravu), a jenž kromě dalších věcí umožňuje spravovat přístupy konkrétních vývojářů ke konkrétním částem projektu v konkrétních časech (což usnadňuje spolupráci více vývojářů, kteří mohou na projektu pracovat současně). Druhá forma SCM je distribuovaná, nezávislá na centralizaci a je více vhodná pro velké geograficky distribuované projekty. V této kapitole se dozvíte více informací o různých SCM, které jsou dostupné pro linuxové systémy a budete moci experimentovat s různými implementacemi. Tato kapitola se sice nevěnuje práci s příslušnými nástroji, nicméně získáte dostatek znalostí, abyste byli schopni nalézt informace o všem, co ještě neznáte. Dále se naučíte, jak mohou být různé integrované nástroje, jako je Eclipse, rozšířeny o schopnosti SCM. Jakmile si přečtete celou tuto kapitolu, měli byste porozumět různým systémům pro správu zdrojových kódů, se kterými se můžete setkat při používání Linuxu. Získáte také znalosti, které jsou nutné pro pochopení práce s různými komerčními SCM systémy.


126

Kapitola 4 – Správa zdrojových kódů

Proč potřebujeme SCM Správa zdrojových kódů (SCM) může být pojmem, se kterým jste se pravděpodobně ještě nesetkali (nebo se s tímto pojmem setkáváte velmi zřídka). V reálném světě se velmi často stává, že v procesech, které probíhají celou řadu let, se postupně začínají používat různé modernější pojmy. To znamená, že SCM může pro různé lidi znamenat různé věci, nicméně v kontextu této knihy tento pojem chápeme jako systém, který je určen pro sledování a řízení procesu vývoje softwaru a dalších činností s tím spojených. Nejčastější činnosti, které souvisí s SCM, jsou následující: 

Kontrola zdrojových kódů v rámci repozitáře (repository).



Synchronizace práce s ostatními vývojáři.



Správa verzí projektu (a jeho větví).



Správa kompilace.



Integrace procesů vývoje softwaru.

Většina řešení SCM poskytuje určitou formu repozitáře zdrojů. Repozitář v tradičním slova smyslu představuje centrální prostor celého projektu, v jehož rámci mohou ostatní vývojáři, kteří se podílejí na projektu, vkládat své vlastní úpravy a sledovat úpravy jiných. Vývojáři svou práci na projektu vždy zahajují tím, že ve svém lokálním prostředí si vyhradí nějaký pracovní prostor, ze kterého mohou přímo pracovat se sdílenými soubory. Jakmile jsou změny, které provedli, považovány za vyhovující, jsou testovány a prověřovány v rámci samotného repozitáře. Vývojář, který pracuje v rámci SCM, často spolupracuje s několika dalšími vývojáři, kteří pracují na jiných částech stejného projektu (nebo dokonce se stejným zdrojovým souborem). Jednou z primárních funkcí SCM je spravovat tyto samostatně provedené změny a po celou dobu vývoje poskytovat vývojářům souvislý přehled repozitáře. Provedené změny (někdy označované jako changeset) mají za následek aktualizaci repozitáře, což v podstatě znamená, že tyto změny se promítnou do repozitáře, takže ostatní vývojáři se dozví, zdali mají aktualizovat svůj lokální obraz projektu. A pokud ano, do jejich obrazu projektu se zahrnou poslední provedené změny. Typický SCM dovoluje po ukončení vývojového cyklu označit aktuální stav repozitáře jako "vhodný k uvolnění". Toto řešení představuje nadstavbu k běžnému označování verzí, které se provádí vždy, když je zdrojový soubor v rámci repozitáře upraven a zaregistrován. Mnoho SCM rovněž podporuje koncepci větvení, která umožňuje vývoj několika souběžných variant stejného projektu. Tohle je potřeba v případech, kdy projekt musí podporovat několik odlišných platforem, přičemž práce na podporu těchto různých hardwarových / softwarových platforem je prováděna různými týmy. Jak můžete sami vidět, SCM zajišťuje všechno, co je nezbytné pro správu softwarového projektu. Pro samotné vývojáře a pro správce projektu (případně pro další, kteří se na daném projektu podílejí) je velmi důležité mít k dispozici možnost vizualizovat celý proces vývoje v jeho průběhu. Dobré SCM řešení by mělo být nenápadné, přičemž jeho nástroje musí být snadno použitelné samotnými vývojáři. Není nic více frustrující, než používání pomalých a těžkopádných nástrojů, které se navíc musí používat každý den opakovaně. Nástroj git, což je SCM systém používaný li-


Linux PROFESIONÁLNĚ – programování aplikací

127

nuxovou komunitou pro vývoj samotného linuxového jádra, je jedním z takových dobrých a lehce použitelných nástrojů. Více informací o něm naleznete později v této kapitole.

Centralizovaný vs decentralizovaný vývoj Jedno z prvních rozhodnutí, které je potřeba vykonat při práci s SCM na linuxových systémech, není to, jaký konkrétní systém vlastně použít, ale spíše jaký typ. V tradiční centralizované situaci budeme pracovat s centrálním repozitářem a používat nástroj jako je CVS (Concurrent Versioning System, systém pro sledování verzí) pro sledování změn v rámci tohoto repozitáře, které byly zrealizovány během práce s konkrétními zdrojovými soubory projektu. V této situaci si typicky přivlastníte nějakou konkrétní část projektu, abyste se vyhnuli konfliktům se změnami, které by mohly být pro tuto část projektu provedeny ve stejné době jiný vývojářem. V posledních letech se ovšem pozornost upírá na decentralizované SCM systémy. To vedlo k vytvoření mnoha mocných nástrojů, jako je například git, což je nízkoúrovňový nástroj používaný Linusem Torvaldsem pro vývoj samotného jádra Linuxu. V decentralizovaném prostředí SCM neexistuje žádný centrální repozitář, se kterým musejí všichni vývojáři pracovat. Místo toho má každý vývojář k dispozici svou část stromu projektu, ve které může provádět libovolné požadované změny. Po dokončení práce jsou tyto změny získány od jednotlivých vývojářů a následně sloučeny dohromady. Případné konflikty mezi různými verzemi kódu jsou samozřejmě řešeny. Oba přístupy mají své výhody i nevýhody. Centralizovaný přístup funguje dobře v silně strukturovaném prostředí, ve kterém jsou servery vždy dostupné, a kdy se od vývojářů očekává, že budou přesně postupovat podle konkrétních procedur, jež umožní korektní zavedení změn do projektu. Decentralizovaná řešení SCM jsou v zásadě méně organizovaná, nicméně poskytují tu výhodu, že jsou více bezpečnější (v porovnání s jedním jediným centrálním úložištěm centralizovaných SCM systémů). Dále mají schopnost fungovat kdekoliv a kdykoliv, a to ani nemluvíme o schopnostech inteligentního slučování mnoha souběžných změn od různých vývojářů. To, jakému SCM systému dát přednost, je závislé na stylu vývoje. Pokud pracujete jako samostatný vývojář (nebo v malém týmu v nějaké malé společnosti), má rozhodně smysl instalovat a používat centralizované řešení SCM. V takovém prostředí existuje velmi malé množství základních omezení a je docela nepravděpodobné, že by dva vývojáři pracovali ve stejnou dobu na stejném problému (a nevěděli o sobě), takže konkrétní vývojář si může v takové situaci (a bez jakýchkoliv skrupulí) rovnou přivlastnit daný zdrojový soubor a po nějakou dobu s ním pracovat. Pokud se ovšem stanete součástí mnohem většího projektu (ať už komerčního nebo komunitního), rozhodně zvažte použití nějakého decentralizovaného SCM řešení, které jednotlivým vývojářům umožní, aby byli tak výkonní a nezávislí, jak je to jenom možné. Mezi takové velké projekty například patří vývoj samotného linuxového jádra, přičemž stále více a více projektů se přiklání k používání decentralizovaných SCM řešení.


128

Kapitola 4 – Správa zdrojových kódů

Centralizované systémy Existuje celá řada centralizovaných SCM systémů, které se běžně používají na linuxových systémech. Ve skutečnosti jich existuje tolik, že jednoduše není vůbec možné, abychom se zaměřili na každý z nich. Většina těchto centralizovaných systémů se ovšem chová velmi podobně, přičemž mají i podobné schopnosti (a samozřejmě jsou v některých detailech odlišné). Tyto systémy si pochopitelně můžete sami vyzkoušet na vlastní kůži a následně se rozhodnout, který z nich je pro vaše centralizované prostředí nejlepší. Ničeho se nebojte – ať už si vyberete tak či onak, žádné vaše rozhodnutí v této věci nebude možné označit za "dobré" nebo "špatné" (ačkoliv na toto téma existuje velké množství rozdílných nástrojů). Na jisté úrovni je totiž volba konkrétního SCM systému pouze věcí vkusu a politiky vaší společnosti. Následující část této kapitoly popisuje SCM systémy CVS a Subversion, které jsou typickými představiteli centralizovaných SCM systémů, které jsou široce používány mnoha linuxovými vývojáři. Pomocí těchto dvou systémů jsou spravovány extrémně rozsáhlé projekty po celém světě.

CVS – systém pro sledování verzí Webové stránky projektu: http://www.nongnu.org/cvs. CVS (Concurrent Version System, systém pro sledování verzí) je v současné době jedním z nejvíce populárních nástrojů SCM, které jsou používány linuxovými vývojáři. Jedná se také o jeden z nejstarších dostupných nástrojů vůbec. Jeho kořeny sahají až do osmdesátých let 20. století, kdy byl vyvinut systém RCS (Revision Control System), který sloužil pro kontrolu revizí. Současný CVS je založen na centrálním repozitáři, který obsahuje jednotlivé zdrojové projekty, a jež jsou pod kontrolou systému CVS. Pro interakci s repozitářem a pro správu zdrojů v rámci daného projektu lze použít příkaz cvs. Téměř všechny distribuce Linuxu obsahují předinstalovaný nástroj CVS jako součást vývojářských balíčků. Pokud ovšem zjistíte, že systém CVS není na vašem počítači dostupný, zkuste ověřit, zdali jste během instalace Linuxu nezapomněli nainstalovat nástroje pro vývoj (nebo pro vaše experimenty použijte jiný počítač, pokud jej máte k dispozici).

Na rozdíl od mnoha jiných nástrojů, které existovaly před CVS, CVS podporuje souběžný (concurrent) vývoj (písmeno "C" ve zkratce CVS). To znamená, že vývojáři, kteří si vyzvednou konkrétní zdrojový soubor a začnou s ním pracovat, nebudou nijak blokovat ostatní vývojáře, kteří provedou stejnou činnost. Předchozí nástroje před CVS obvykle vyžadovaly, aby vývojáři striktně oznámili svůj záměr pracovat s daným souborem, čímž byl tento soubor zablokován pro ostatní vývojáře. Díky tomu samozřejmě vznikaly různé nepříjemné situace, kdy nějaký vývojář, který chvatně odcestoval na dovolenou, zapomněl v repozitáři odemknout soubory, se kterými před svým odjezdem pracoval. Ostatní vývojáři tak museli čekat na odblokování příslušných souborů. Nelze se tedy divit, že když se na scéně poprvé objevil systém CVS, byla to docela revoluční událost.


Linux PROFESIONÁLNĚ – programování aplikací

129

Systém CVS samozřejmě není samospasitelný. Aby mohl podporovat souběžný vývoj, muselo se přistoupit k některým kompromisům. Je možné, aby dva vývojáři mohli ve stejnou dobu upravovat jeden jediný soubor (a rovněž současně registrovat všechny změny, které byly v souboru provedeny). CVS tyto konfliktní situace zpracovává tak, že poskytne vývojáři možnost porovnat své změny se změnami ostatních vývojářů a rozhodnout, jakým způsobem tyto změny zkombinovat. Abyste rychle pronikli do způsobu práce s CVS, následující části obsahují užitečné informace o tom, jak vytvářet a spravovat repozitáře systému CVS. Kvůli svým experimentům sice nemusíte vytvářet svůj vlastní repozitář systému CVS, nicméně pokud to uděláte, získáte pro sebe vyšší stupeň svobody, nehledě na to, že budete schopni si libovolně vyzkoušet všechny vaše možné (i nemožné) experimenty bez toho, že byste někomu způsobili nějaké problémy. Pokud nepotřebujete vlastní repozitář, vězte, že mnoho velkých open source projektů může být spravováno prostřednictvím CVS, takže klidně použijte CVS server nějakého takového projektu. Populární webový server Source Forge (www.sourceforge.net), který je využíván velkým množstvím různých open source projektů, poskytuje zdarma zdroje CVS serveru každému projektu, který chce u nich hostovat. Budou vám zde také poskytnuty informace, pomocí kterých se dozvíte, jak využívat tyto prostředky serveru jako vzdálený anonymní uživatel. To sice znamená, že jako anonymní uživatel nebudete schopni zapisovat vámi provedené změny zpět do CVS repozitáře, nicméně pro naše následující experimenty není tato skutečnost nijak omezující.

Vytvoření CVS repozitáře Vlastní repozitář systému CVS můžete vytvořit prostřednictvím následujícího příkazu: $ cvs -d /usr/local/cvsroot init

Tento příkaz říká systému CVS, aby v adresáři /usr/local/cvsroot vytvořil nový repozitář. Adresář /usr/local je obvykle chráněn, takže do něj může zapisovat pouze uživatel root. Protože obvykle nejste ke svému systému přihlášeni jako uživatel root, můžete vytvořit nový repozitář buď jako uživatel root (s využitím příkazu sudo), a pak nastavit přístupová práva k souborům v adresáři cvsroot (prostřednictvím příkazu chown, nebo nastavením sdílené skupiny uživatelů pro přístup systému CVS do centrálního repozitáře), nebo zvolit jiné umístění pro váš nový repozitář. Pokud chcete pro vaše experimenty používat vlastní repozitář CVS, vůbec nezáleží na tom, kde bude umístěn. Pokud se vám to hodí, klidně použijte nějaký podadresář vašeho domovského adresáře.

Adresář cvsroot je velmi důležitý. Jedná se o kořen repozitáře, který bude obsahovat všechny projekty, jež jsou pod kontrolou systému CVS. Protože veškeré operace se budou vztahovat k tomuto adresáři, bude velmi užitečné nastavit proměnnou prostředí CVSROOT takovým způsobem, abyste nemuseli tuto informaci sdělovat systému pokaždé, když budete volat nějaký příkaz. Nastavení proměnné prostředí CVSROOT vykonáte prostřednictvím následujícího příkazu: $ export CVSROOT=/usr/local/cvsroot


130

Kapitola 4 – Správa zdrojových kódů

Vytvoření nového CVS projektu Jakmile máte vytvořený repozitář a nastavenou proměnnou prostředí CVSROOT, můžete buď vytvářet nové projekty, které budou spravovány systémem CVS, nebo vkládat do repozitáře vaše nějaké již existující projekty. Ve většině situací budete mít k dispozici nějaký projekt, takže předpokládejme, že jej budete chtít vložit do existujícího repozitáře. K tomu můžete samozřejmě použít libovolný projekt, takže pro účely tohoto příkladu použijeme například ukázkový kód z kapitoly 2. S využitím následujícího příkazu importujte adresář toolchains do vašeho nového repozitáře. $ cd toolchains $ cvs import -m "toolchains example" plp/toolchains plp start

Měli byste uvidět výstup podobný tomu následujícímu (je zkrácen kvůli stručnosti): cvs import: Importing /usr/local/cvsroot/plp/toolchains/src N plp/toolchains/src/Makefile N plp/toolchains/src/hello.c N plp/toolchains/src/hello I plp/toolchains/src/main.o N plp/toolchains/src/message.c N plp/toolchains/src/hello.s N plp/toolchains/src/main.c I plp/toolchains/src/message.o N plp/toolchains/src/trig I plp/toolchains/src/libmessage.so N plp/toolchains/src/trig.c N plp/toolchains/src/goodbye_shared No conflicts created by this import

Povšimněte si, že systém CVS na začátku každého řádku zobrazí znak N, nebo I pro každý importovaný soubor. Tímto způsobem je indikován stav příslušného souboru v rámci repozitáře. Znak N znamená, že daný soubor byl nově vytvořen během tohoto importu, zatímco znak I, který se objevil u objektových souborů s příponou .o a .so, vás informuje o tom, že systém CVS bere tyto soubory na vědomí, a že je bude ignorovat. Prostřednictvím speciálního souboru .cvsignore, který lze později vytvořit v rámci adresářové struktury konkrétního projektu, máte možnost specifikovat, jaké soubory budou ignorovány. Více informací naleznete v dokumentaci systému CVS.

Předchozí příkaz importuje projekt toolchains do repozitáře, který je uveden v proměnné prostředí $CVSROOT. Samotný kód projektu je uložen uvnitř repozitáře v adresáři $CVSROOT/plp/toolchains, což umožňuje seskupovat vzájemně související projekty pod stejný adresář plp. Parametr plp ve výše uvedeném příkazu je použit jako označení projektu dodavatele, zatímco start označuje první vydání. Tyto dva dodatečné parametry sice není nutné bezprostředně používat, nicméně systém CVS je při vytváření nového repozitáře vyžaduje.


Linux PROFESIONÁLNĚ – programování aplikací

131

Když importujete do repozitáře nějaké zdrojové soubory, systém CVS standardně spustí nějaký textový editor (většinou podle hodnoty proměnné prostředí $EDITOR), což vám umožní specifikovat text, který bude sloužit jako popis samotného importu. Tím, že v předchozím příkazu jsme použili parametr -m, jsme systém CVS informovali, aby pro tento konkrétní import použil popisný text "toolchains example", a aby nespouštěl žádný externí textový editor. Grafické nástroje CVS (včetně různých rozšíření k vývojovému open source prostředí Eclipse) obvykle použijí nějaký libovolný vestavěný editor, který je v době importu k dispozici.

Vyzvednutí zdrojů z CVS Jakmile se vám podařilo importovat projekt do repozitáře, před samotným zahájením prací musíte z repozitáře vyzvednout soubory, se kterými chcete pracovat. To se provádí tak, že vytvoříte nový pracovní adresář, ověříte, zdali je správně nastavena hodnota proměnné prostředí CVSROOT (což je cesta k repozitáři, který jste vytvořili), a pak vykonáte následující příkaz v rámci pracovního adresáře, do něhož se mají uložit vyzvednuté soubory: $ cvs co plp/toolchains

V příkazu cvs je možné použít parametr-d, čímž potlačíte proměnnou prostředí CVSROOT. Nahlédněte do dokumentace systému CVS, kde naleznete další informace o potlačení metod použitých pro přístup k repozitáři. Je například možné systém CVS informovat o tom, že prostřednictvím tzv. bezpečnostního lístku Kerberos musí být uživatel autentizován, aby bylo možné lépe zabezpečit server systému CVS. Pro bezpečnější komunikaci se vzdáleným serverem je také možné použít protokol SSH.

Jakmile požádáte systém CVS o vyzvednutí zdrojů z centrálního repozitáře, objeví se výpis o vyzvednutí příslušných adresářů a souborů, který je podobný následujícímu: cvs checkout: Updating plp/toolchains/src U plp/toolchains/src/Makefile U plp/toolchains/src/goodbye_shared U plp/toolchains/src/hello U plp/toolchains/src/hello.c U plp/toolchains/src/hello.s U plp/toolchains/src/main.c U plp/toolchains/src/message.c U plp/toolchains/src/trig U plp/toolchains/src/trig.c

Proces vyzvedávání vytvoří adresář plp, ve kterém bude umístěn podadresář toolchains se zdrojovými soubory našeho ukázkového projektu. Znak U na začátku každého řádku se jménem souboru ve výše uvedeném výpisu vás informuje o tom, že z repozitáře byla vyzvednuta aktuální verze příslušného souboru.


132

Kapitola 4 – Správa zdrojových kódů

Vyzvednutí budoucích verzí projektu – například těch, které obsahují změny, jež byly provedeny jinými vývojáři – lze provést následujícím jednoduchým příkazem: $ cvs update

Tímto budou z repozitáře staženy všechny zdrojové soubory, které byly změněny. Vámi provedené změny v souborech budou samozřejmě označeny, aby nemohlo dojít k nějakým konfliktům. Je dobrou programátorskou technikou se CVS dotázat na aktualizované soubory projektu ještě předtím, než se pokusíte zaregistrovat vámi provedené úpravy. Registraci vašich změn do systému CVS se detailněji věnuje následující část kapitoly.

Registrace provedených změn Úprava jednotlivých zdrojových souborů a jejich následná registrace do centrálního repozitáře je díky systému CVS velice snadná. Ukážeme si to pomocí následujícího příkladu. Zdrojový kód programu hello.c upravte podle tohoto výpisu (nově přidaný řádek je zvýrazněn tučným řezem): /* * Professional Linux Programming - Hello World */ #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { printf("CVS is a Software Configuration Management tool!\n"); return 0; }

Pomocí příkazu make tento program vybudujte a jako obvykle otestujte jeho funkčnost. Pak prostřednictvím následujícího příkazu zaregistrujte upravený soubor do vašeho repozitáře. $ cvs commit

Tím, že jsme nepoužili parametr -m, bude spuštěn nějaký textový editor, pomocí kterého lze vytvořit krátké shrnutí ohledně provedených úprav (například: "Na žádost hlavního programátora byla do kódu příkladu Hello world přidána nová zpráva"). Jakmile toto shrnutí vložíte a pomocí textového editoru uložíte, změny provedené ve vaší aplikaci budou zaregistrovány. Systém CVS po vykonání akce commit vypíše tuto zprávu: cvs commit: Examining . /usr/local/cvsroot/plp/toolchains/src/hello,v <-- hello new revision: 1.2; previous revision: 1.1 /usr/local/cvsroot/plp/toolchains/src/hello.c,v <-- hello.c new revision: 1.2; previous revision: 1.1


KAPITOLA 6 Databáze Když běží nějaká linuxová aplikace, všechna data, která jsou použita v této aplikaci, se nacházejí v systémové paměti. Jakmile běh aplikace skončí, data z paměti budou ztracena. Když aplikaci spustíte příště, libovolná data z předcházející relace již nebudou dostupná. Většina aplikací pracujících s daty ovšem vyžaduje, aby data byla dostupná v různých relacích. Možnost ukládat data je tudíž zásadním požadavkem pro každou aplikaci, která pracuje s historickými daty, což mohou být například záznamy o zaměstnancích, evidence majetku, vedení účetnictví atd. Tato kapitola popisuje dvě metody, které implementují ukládání dat v linuxových aplikacích. Nejprve vám předvedeme metodu, která využívá zabudovaný databázový engine. Zabudování databázového enginu do aplikace vám poskytne jednoduchou funkcionalitu pro uložení dat bez toho, abyste museli řešit režii a správu samostatného databázového serveru. Následně vám předvedeme metodu, která využívá plnohodnotný databázový server s otevřeným zdrojovým kódem. Když je použit databázový server, zákazníci mohou k vašim datům přistupovat z kteréhokoliv místa v místní síti (nebo také prostřednictvím sítě internet!).

Trvalé uložení dat Klíčem k trvalému ukládání dat je schopnost rychle získávat uložená data. Moderní databáze využívají pro rychlý přístup k uloženým datům poměrně velké množství různých technik a metod, přičemž existuje spousta názorů na to, jak má vypadat ideální návrh, konfigurace a řízení databáze. Linux naštěstí nabízí produkty, které pokrývají široké spektrum řešení. Ukládání dat bývá v linuxových aplikacích obvykle implementováno jedním ze tří následujících způsobů: 

Prostřednictvím čtení a zápisu do standardních souborů.



Prostřednictvím zabudovaného databázového enginu.



Prostřednictvím externího databázového serveru.

Každá z metod má svá pro i proti, která je nutné při tvorbě aplikace ukládající data brát v úvahu.


188

Kapitola 6 – Databáze

Použití standardního souboru Nejzákladnější formou používanou pro ukládání dat je uložení dat do nějakého standardního souboru na vašem pevném disku. V Linuxu je možné zapsat data do nějakého souboru na disku a následně k těmto datům přistupovat. Systém Linux může kontrolovat přístup uživatelů k těmto souborům, což znamená, že můžete zajistit, aby k uloženým datům nemohli neoprávněně přistupovat cizí uživatelé nebo aplikace. Ve většině linuxových aplikací probíhá práce se soubory v několika krocích. Tyto kroky názorně ukazuje obrázek 6.1.

Obrázek 6.1. Většina programovacích jazyků v Linuxu poskytuje funkce, které jsou nezbytné pro otevření souborů, zápis dat, čtení dat a uzavření souborů. Velkou nevýhodou použití standardních souborů pro ukládání dat je výkon. Ačkoliv vytvoření souborů a následný zápis dat je velmi jednoduchý úkol, vyhledávání dat uložených v souboru už tak jednoduché není. Vyhledání konkrétního záznamu v souboru, který například obsahuje tisíce různých záznamů, obvykle znamená, že pro jeho získání musíte přečíst všechny záznamy, jež jsou v daném souboru k dispozici. A to může být hodně pomalá činnost. Pro ukládání dat je tak mnohem vhodnější použít databázi.

Použití databáze Současná databázová teorie nabízí mnoho metod vedoucích ke zvýšení výkonu vyhledávání dat v databázi. Místo ukládání datových záznamů do souboru v pořadí, v jakém byly přidány, databázový systém umožňuje uspořádat záznamy podle hodnot, které jsou nazývány jako klíče, přičemž pro tyto klíče může vytvořit samostatné soubory, jež obsahují ukazatele na příslušné záznamy. Tímto vám chceme sdělit, že uspořádání dat podle nějakého jedinečného klíče slouží k tomu, aby databáze mohla opravdu rychle získat požadované informace. Rychlost této metody pro přístup k datům se vůbec nedá srovnat s rychlostí metody, ve které je nezbytné prohledat všechny záznamy.


Linux PROFESIONÁLNĚ – programování aplikací

189

Samozřejmě se pak nabízí otázka, jak takový databázový systém vůbec naprogramovat. Vytvoření řádné logiky pro implementaci databáze vyžaduje velké množství kódu, přičemž existují dva přístupy, jak implementovat databázovou logiku pro vaši aplikaci. První přístup spočívá v tom, že do vaší aplikace se zahrnou jednoduché databázové funkce, jejichž funkcionalita je zajišťována prostřednictvím jednoduchých knihoven. Toto ukazuje obrázek 6.2.

Obrázek 6.2. Knihovna databázového enginu poskytuje funkce pro vytváření databázových souborů, pro vkládání, změny a odstraňování záznamů a v neposlední řadě i funkce používané pro dotazy na obsah databáze. Protože tyto databázové funkce jsou implementovány do kódu samotné aplikace, nepotřebujete nějaký externí databázový server, který by bylo nutné spravovat. Řečeno jinými slovy – všechny databázové funkce tvoří nedílnou součást aplikace. To znamená, že aplikace jako taková si sama spravuje příslušné datové soubory (včetně přístupu k nim). Nedostatky zabudovaného databázového enginu se projeví ve víceuživatelském prostředí. Když používáte pouze jedinou aplikaci, nevznikají žádné problémy s přístupem k databázovému souboru a s jeho případnou aktualizací. Pokud se ale více uživatelů začne současně snažit o přístup k souboru databáze (a o uložení svých změn), může snadno dojít k porušení integrity dat. V takovém případě je potřeba, aby přístup k databázovým datům řídil jeden jediný subjekt, který bude rovněž rozhodovat o tom, kdy budou aktualizovaná data k dispozici pro ostatní uživatele. A toto je okamžik, kdy přichází na scénu databázový server, který má na starosti kompletní správu dat v databázi. Aplikace, které chtějí přistupovat k datům v databázi, tak musí činit prostřednictvím tohoto databázového serveru. Databázový server může nejenom určovat, k jakým datům mohou mít jednotliví uživatelé přístup, ale také to, jak budou data od jednotlivých uživatelů uložena do databáze. Typické prostředí s databázovým serverem je ukázáno na obrázku 6.3.


190

Kapitola 6 – Databáze

Obrázek 6.3. Aby mohly aplikace komunikovat s databázovým serverem, opět musejí používat nějakou knihovnu funkcí. Taková knihovna poskytuje funkce, které například zajišťují připojení k serveru, vkládání, změnu a odstraňování dat v databázi či vykonávání dotazů pro databázi. Aby s databázovými servery mohla pracovat velká skupina různých klientů, bylo pro zjednodušení celého procesu vymyšleno několik standardů. Sem například patří standard SQL (Standard Query Language, doslova standardní dotazovací jazyk), který je používán jako standardní protokol pro zasílání příkazů databázovému serveru a pro získávání výsledků. Následující části této kapitoly představují dva oblíbené databázové servery pro Linux. Berkeley DB je ukázkou databázového enginu zabudovaného do aplikace, zatímco PostgreSQL demonstruje možnosti centrálního databázového serveru.

Balíček Berkeley DB Open source balíček Berkeley DB patří mezi nejvíce oblíbený a nejvíce používaný databázový engine, který vám nabízí velké množství pokročilých databázových funkcí prostřednictvím snadno použitelné knihovny, kterou můžete připojit k vašim aplikacím napsaným v jazyce C nebo C++. Životní dráha Berkeley DB je docela pestrá. Jak již napovídá samotný název balíčku, jeho vývoj odstartoval na kalifornské univerzitě v Berkeley jako jednoduchý databázový projekt, který byl určen pro operační systém BSD verze 4.4. Po nějaké době se ovšem stal natolik oblíbeným, že společnost Netscape Corporation v roce 1996 požádala jeho autory o uvolnění Berkeley DB k obecnému použití. Díky tomu byla založena společnost Sleepycat Software Incorporated, která měla pokračovat v dalším vývoji Berkeley DB – ovšem již nezávisle na unixové distribuci BSD. Společnost Sleepycat


Linux PROFESIONÁLNĚ – programování aplikací

191

Software následně tento produkt vydala nejenom pod komerční licencí (pro podporu komerčních instalací), ale také ve formě otevřeného kódu (tzv. licence Sleepycat). Před nějakou dobou byla společnost SleepyCat Software (a tudíž i produkt Berkeley DB) odkoupena společností Oracle. Přestože je Oracle jedním z předních komerčních dodavatelů databázových systémů, produkt Berkeley DB je stále k dispozici ve formě otevřeného kódu. Následující části této kapitoly popisují, jak se dá balíček Berkeley DB stáhnout, zkompilovat, nainstalovat a používat ve vašich linuxových aplikacích.

Stažení a instalace Protože Berkeley DB patří mezi oblíbené balíčky, je součástí mnoha linuxových distribucí (a v některých je dokonce k dispozici i ve standardních instalacích). Pokud Berkeley DB není nainstalován ve vašem systému, můžete jej nainstalovat dodatečně v podobě balíčku předkompilovaného pro vaši konkrétní distribuci, nebo si z webu Oracle stáhnout nejnovější verzi zdrojových souborů, které si sami zkompilujete a následně nainstalujete. Když se rozhodnete použít předkompilovaný balíček, postupujte podle obvyklého postupu pro instalaci softwaru ve vaší distribuci. Nezapomeňte nainstalovat jak samotné soubory knihoven, tak i soubory pro vývoj. Obvykle jsou rozděleny do dvou balíčků, které je potřeba nainstalovat samostatně. Nejnovější verze Berkeley DB je k dispozici na webu Oracle. V současné době ji můžete najít na adrese www.oracle.com/technology/products/berkeley-db/index.html. V pravém horním rohu stránky klikněte na červené tlačítko Download. V době psaní této knihy byla nejnovější verze označena 4.5.20 (v době překladu této knihy je aktuální verze 4.6.21, poznámka redaktora). Berkeley DB je pochopitelně k dispozici v několika různých konfiguracích a formátech balíčků. Pro instalaci balíčku v Linuxu si stáhněte balíček s příponou .tar.gz (je jedno, zdali se šifrováním AES nebo bez něj). Stažený soubor si ve vašem linuxovém systému uložte do pracovního adresáře. Protože je balíček distribuován ve formě zdrojového kódu, musíte jej prvně rozbalit a následně zkompilovat. Pro rozbalení zdrojového balíčku použijte následující příkaz: $ tar -zxvf db-4.5.20.tar.gz

Tento příkaz vytvoří ve vašem pracovním adresáři nový podadresář db-4.5.20 a rozbalí do něj všechny soubory se zdrojovým kódem. Balíček Berkeley DB se kompiluje poněkud odlišným způsobem, než jak je tomu v případě jiných balíčků, které jsou k dispozici ve formě otevřeného kódu. Jako první krok musíte přejít do příslušného podadresáře build_xxx, který se nachází v hlavním adresáři. V případě linuxových systémů se jedná o adresář build_unix. Z tohoto místa pak spusťte konfigurační program, který se nachází v adresáři dist. Kód pro vykonání těchto činností vypadá takto: [db-4.5.20]$ cd build_unix


192

Kapitola 6 – Databáze

[build_unix]$ ../dist/configure

Konfigurační utilita ověří vlastnosti systému a následně vytvoří soubory, které jsou potřebné pro zkompilování aplikace. Jakmile je tato činnost ukončena, v adresáři build_unix spusťte příkaz make: [build_unix]$ make

Po skončení kompilace nainstalujte do vašeho systému knihovnu a soubory pro vývoj prostřednictvím příkazu make s parametrem install: [build_unix]$ make install

Nezapomeňte, že tento krok byste měli provést jako uživatel root. Jakmile máte knihovnu a soubory pro vývoj úspěšně nainstalovány, můžete se pustit do programování.

Kompilace programů Knihovna Berkeley DB a soubory pro vývoj se standardně nainstalují do čtyř podadresářů, které jsou umístěny v adresáři /usr/local/BerkeleyDB.4.5. Jedná se o tyto čtyři podadresáře: 

Bin. Obsahuje utility pro zkoumání a opravování databázových souborů Berkeley DB.



Docs. Obsahuje HTML dokumentaci pro API C a další utility.



Include. Obsahuje hlavičkové soubory C a C++ pro komplikaci aplikací využívajících knihovnu Berkeley DB.



Lib. Obsahuje soubory sdílených knihoven pro kompilaci a běh aplikací využívajících knihovnu Berkeley DB.

Abyste mohli spouštět aplikace, které využívají knihovnu Berkeley DB, musíte do seznamu knihoven dostupných v systému přidat adresář lib. Seznam adresářů, které Linux prochází při hledání souborů knihoven, máte k dispozici v souboru /etc/ld.so.conf. Jako uživatel root přidejte do tohoto seznamu nový adresář /usr/local/BerkeleyDB.4.5/lib (a pochopitelně neodstraňujte žádnou položku z tohoto seznamu). Jakmile máte obsah souboru /etc/ld.so.conf aktualizovaný, spusťte utilitu ldconfig (opět jako uživatel root), aby se změna projevila v systému. Nyní je váš systém připraven na běh aplikací využívajících knihovnu Berkeley DB. Když budete kompilovat nějakou takovou aplikaci, musíte kompilátoru sdělit, kde jsou k dispozici hlavičkové soubory a soubory knihovny. U linkeru musíte dále specifikovat knihovnu db. Zde je ukázka kompilace aplikace, která využívá knihovnu Berkeley DB: $ cc -I/usr/local/BerkeleyDB.4.5/include -o test test.c -L/usr/local/BerkeleyDB.4.5 -ldb

Parametrem -I specifikujete umístění hlavičkových souborů, potřebných ke kompilaci. Parametrem -L pak umístění souborů knihoven, které jsou nutné pro zkompilování spustitelné aplikace.


Linux PROFESIONÁLNĚ – programování aplikací

193

Základní práce s daty Když nyní máte knihovny Berkeley DB nahrány a nakonfigurovány ve vašem systému, můžete je začít používat ve vašich vlastních aplikacích. Následující část popisuje kroky, které jsou nezbytné k tomu, abyste mohli začít využívat Berkeley DB pro databázovou podporu ve vašich aplikacích.

Otevření a zavření databáze Než můžete přistoupit k databázovému souboru Berkeley DB, musíte jej prvně otevřít. Jakmile s ním přestanete pracovat, musíte jej zavřít, jinak riskujete poškození dat. Pro přístup k databázovému souboru se používá ovladač DB. Ten získáte prostřednictvím funkce db_create(): int db_create(DB **dbp, DB_ENV *env, u_int32_t flags)

Parametr dbp specifikuje ovladač DB, který bude použit pro přístup k souboru. Parametr env specifikuje prostředí, pod kterým bude databázový soubor otevřen. Pokud je tento parametr roven NULL, databáze je považována za samostatnou, takže veškerá provedená nastavení se budou týkat pouze tohoto souboru. Alternativně můžete specifikovat hodnotu DB_ENV pro seskupení této databáze společně s jinými databázemi do nějakého prostředí. Všechna nastavení, která budou provedena pro dané prostředí (např. zamykání souborů), se pak projeví ve všech databázích, jež do něj patří. Parametr flags by měl být nastaven na 0 pro databáze, které běží v linuxovém prostředí. Když funkce db_create() uspěje, vrátí hodnotu 0. Když dojde k chybě, vrácená hodnota je nenulová. Jakmile máte vytvořen ovladač DB, prostřednictvím funkce open() otevřete nový nebo nějaký stávající soubor databáze: int DB->open(DB *db, DB_TXN *txnid, const char *file, const char *database, DBTYPE type, u_int32_t flags, int mode)

Funkce open() používá ovladač db, který byl vytvořen funkcí db_create(). Parametr txnid specifikuje otevřený objekt transakce, pokud příkaz je součástí transakce. Parametr file specifikuje název souboru, který je používán pro databázi; parametr database pak specifikuje název databáze, jež je uložena v tomto souboru. Berkeley DB umožňuje, aby v jednom fyzickém souboru mohlo být uloženo více databází. Pokud nějaký databázový soubor obsahuje větší množství databází, musíte každou z nich otevírat samostatným voláním open(). Pokud vytváříte novou databázi, musíte v parametru type uvést typ databáze. V době psaní této knihy byly podporovány následující čtyři typy: 

DB_BTREE. Databáze má strukturu uspořádaného stromu. To znamená, že data jsou uspořá-

dána podle hodnot klíče. 

DB_HASH. Rozšířená lineární hashovací tabulka (extented linear hash table) – data jsou uspořádána podle hashované hodnoty klíče.



DB_QUEUE. Fronta záznamů s pevnou délkou. Jako klíč slouží pořadové číslo záznamu.


Kapitola 6 – Databáze

194 

DB_RECNO. Fronta záznamů s pevnou nebo proměnlivou délkou. Jako klíč slouží pořadové číslo záznamu.

Typy DB_BTREE a DB_HASH poskytují rychlý přístup k datům, neboť data jsou uspořádána již během svého vkládání do databázového souboru. To samozřejmě znamená, že vkládání nových záznamů probíhá o něco pomaleji, protože data musejí být v databázovém souboru umístěna na konkrétní místo. Různými experimenty bylo zjištěno, že v případě velmi velkých databází poskytuje metoda DB_HASH o něco lepší výkon než metoda DB_BTREE. Typy DB_QUEUE a DB_RECNO se často používají pro data, která jsou uspořádána podle pořadového čísla záznamu. A právě toto pořadové číslo je použito jako klíč, což znamená, že záznamy je možné získávat pouze pomocí těchto čísel. To se vám může zdát jako omezení, ovšem pouze do té doby, než zjistíte, že vkládání a získávání záznamů v těchto typech databází probíhá extrémně rychle. Pokud tedy potřebujete rychle ukládat a získávat data z databáze, tyto typy budou pro vás ideální. Když otevíráte nějakou existující databázi, pro parametr type můžete použít hodnotu DB_UNKNOWN. V takovém případě se Berkeley DB automaticky pokusí určit typ databáze. Pokud se určení typu databáze nepovede, funkce open() skončí neúspěchem. Parametr flags určuje, jakým způsobem může být soubor databáze otevřen. Hodnoty, které je možné použít, názorně shrnuje následující tabulka. Hodnoty pro flags

Popis

DB_AUTO_COMMIT

Použije transakci pro otevření souboru s databází. Když volání uspěje, operaci bude možné obnovit (recoverable). Když volání neuspěje, soubor s databází nebude vytvořen.

DB_CREATE

Vytvoří databázi (pokud neexistuje).

DB_DIRTY_READ

Operace čtení v databázi může vyžadovat vrácení změněných, ale zatím neuložených dat.

DB_EXCL

Vrátí chybu, pokud soubor databáze již existuje.

DB_NOMMAP

Soubor databáze nebude mapován do paměti.

DB_RDONLY

Databáze bude otevřena v režimu pouze pro čtení.

DB_THREAD

Vrácený ovladač databáze bude možné použít ve více vláknech.

DB_TRUNCATE

Vyprázdní libovolnou databázi, která existuje v databázovém souboru.

Hodnoty uvedené v této tabulce je možné kombinovat prostřednictvím symbolu | (logický operátor OR). To znamená, že můžete například použít hodnoty DB_CREATE | DB_EXCL pro vytvoření nové databáze a vrácení chyby v případě, kdy soubor databáze již bude existovat. Parametr mode specifikuje unixová přístupová práva k souboru. Když zadáte nulovou hodnotu, vlastník souboru i skupina budou mít právo pro čtení a zápis, zatímco zbytek světa k danému souboru mít přístup nebude. A zde je příklad, který ukazuje vytvoření ovladače databáze a otevření nové databáze:


Linux PROFESIONÁLNĚ – programování aplikací

195

DB *dbp; int ret; ret = db_create(&dbp, NULL, 0); if (ret != 0) { perror("create"); return 1; } ret = dbp->open(dbp, NULL, "test.db", NULL, DB_BTREE, DB_CREATE, 0); if (ret != 0) { perror("open"); return 1; }

Pomocí tohoto krátkého kódu zavoláme funkci db_create(), která vytvoří ovladač databáze dbp. Prostřednictvím něj pak vytvoříme nový databázový soubor test.db se strukturou uspořádaného stromu (DB_BTREE, viz dříve uvedený seznam typů databáze) a s výchozími přístupovými právy.

Vkládání nových dat Když teď máte otevřen nový databázový soubor, je ten správný čas do něj vložit nějaká data. K tomu slouží funkce put(). Její syntaxe je následující: int DB->put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags)

Parametry db a txnid mají stejný význam jako u funkce open(). Specifikují ovladač databáze a transakci, která má být použita pro funkci. Parametry key a data pak určují dvojici klíč-hodnota, která bude uložena do databáze. Struktura DBT je použita pro každý definovaný prvek data a size. To znamená, že prvek key.data obsahuje hodnotu pro klíč záznamu, zatímco prvek data.data obsahuje datovou hodnotu záznamu. Parametr flags určuje, jakým způsobem budou nová data vložena do souboru databáze. U databází DB_QUEUE a DB_RECNO můžete použít hodnotu DB_APPEND, která vloží data na konec souboru. U databází DB_BTREE a DB_HASH můžete použít hodnotu DB_NOUPDATA, která zajistí, že záznam bude do databáze přidán pouze tehdy, když databáze nebudou obsahovat stejnou kombinaci klíče a hodnoty. Hodnota DB_NOOVERWRITE pak zabraňuje, aby nová data přepsala stávající klíč. Kombinace klíče a hodnoty může být občas matoucí. Spousta lidí se totiž domnívá, že jsou díky tomu omezeni na jednu datovou hodnotu na záznam. Ale tato datová hodnota může být libovolného typu (včetně struktury). To znamená, že si můžete vytvořit vlastní strukturu s mnoha prvky dat (v závislosti na požadavcích vaší aplikace). Každá instance struktury C pak bude v souboru databáze uložena jako jediná datová hodnota.


Kapitola 6 – Databáze

196

Tuto situaci demonstruje program newemployee.c, který je uveden v následujícím výpisu: /* * Professional Linux Programming - Adding new employee record. */ #include <stdio.h> #include <db.h> #define DATABASE "employees.db" int main() { DBT key, data; DB *dbp; int ret; struct data_struct { int empid; char lastname[50]; char firstname[50]; float salary; } emp; ret = db_create(&dbp, NULL, 0); if (ret != 0) { perror("create"); return 1; } ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0); if (ret != 0) { perror("open: "); return 1; } while(1) { printf("Enter Employee ID: "); scanf("%d", &emp.empid); if (emp.empid == 0) break; printf("Enter Last name: "); scanf("%s", &emp.lastname); printf("Enter First name: "); scanf("%s", &emp.firstname); printf("Enter Salary: "); scanf("%f", &emp.salary);


Linux PROFESIONÁLNĚ – programování aplikací

197

memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.data = &(emp.empid); key.size = sizeof(emp.empid); data.data = &emp; data.size = sizeof(emp); ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE); if (ret != 0) { printf("Employee ID exists\n"); } } dbp->close(dbp, 0); return 0; }

Program newemployee.c vytvoří ovladač databáze a otevře soubor employees.db jako jedinou samostatnou databázi. Přípona .db sice není povinná, nicméně v případě databázových souborů Berkeley DB se používá docela často. Následně je cyklus while() použit pro získání informací o novém zaměstnanci od uživatele. Pro prvek dat (data element) je v databázi použita strukturu emp. Ta obsahuje celočíselné ID zaměstnance, řetězce lastname a firstname a hodnotu platu. Jakmile jsou od uživatele získány tyto hodnoty, jsou ihned umístěny do struktury emp. Před použitím objektů DBT key a data je vždy dobré vynulovat prostřednictvím funkce memset oblast paměti, která je pro ně vyhrazena. Tím zabráníte tomu, aby se do prvků dat zatoulaly nějaké nechtěné bity. Následně je hodnota klíče nastavena na ID zaměstnance a hodnota dat na celou strukturu emp. Jakmile je vše na svém místě, je zavolána funkce put() s parametrem DB_NOOVERWRITE, aby pokus o přidání zaměstnance, jehož ID v databázi již existuje, vyhodil chybu. Pokud chcete aktualizovat záznamy existujících zaměstnanců, stačí tento parametr odebrat. Cyklus while() skončí tehdy, jakmile uživatel zadá nulové ID zaměstnance. Následně bude soubor databáze zavoláním funkce close() korektně uzavřen. Při kompilaci této aplikace nezapomeňte použít správné hlavičkové soubory a knihovny. Poté aplikaci spusťte. Pokud je všechno v pořádku, měli byste být schopni přidávat do databáze nové záznamy o zaměstnancích. Když ukončíte běh programu, měli byste v adresáři vidět soubor databáze pojmenovaný jako employees.db.

Získávání dat Když do souboru databáze ukládáte nějaká data, je velmi pravděpodobné, že je budete chtít taky někdy později získat zpět. K tomu slouží funkce get(): int DB->get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags)


KAPITOLA 9 Moduly jádra Linuxu V předchozích dvou kapitolách jste zjistili, jak probíhá vývojový proces pro linuxové jádro. Seznámili jste se s vývojovou komunitou upstreamu jádra a zjistili jste, že projekt jádra se nachází v neustálém vývoji. Tato devátá kapitola má za úkol položit základy, které jsou nezbytné pro skutečné vytváření vašich vlastních modulů jádra. Tyto moduly jsou často označovány jako ovladače jádra, protože většina modulů je určena pro podporu specifických zařízení. Už jste napsali jednoduchý modul jádra nazvaný plp v kapitole sedm. Tento jednoduchý natažitelný modul prostě vytiskl pozdrav do kernel buffer ringu (zobrazený pomocí příkazu dmesg) a demonstroval základní koncepty psaní modulů, bez hlubšího záběru. Tato kapitola vychází z příkladu předchozí kapitoly a uvádí daleko víc konceptů, které budete potřebovat při psaní skutečných modulů jádra pro reálné uživatele. Ne všechen vývoj jádra ovšem probíhá ve formě modulů třetí strany. Existuje mnoho částí jádra, které nelze modifikovat pomocí samotných natažitelných modulů, protože vyžadují změny v kódu jádra namísto jednoduchého načtení příslušného modulu. Protože v této kapitole poprvé okusíte příchuť vývoje jádra ve formě natažitelných modulů, nemusíte mít strach, že bychom na konci této kapitoly rovnou přešli k úpravám základních algoritmů jádra. Abyste něco takového mohli provádět, budete muset získat ještě velké množství vědomostí, protože se jedná o opravdu složitou látku, která se nedá naučit za týden.

Jak moduly pracují Jádro Linuxu je schopno rozšíření za běhu pomocí natažitelných modulů. Dynamicky načítané moduly linuxového jádra (neboli LKM, Linux Kernel Modules) jsou velmi podobné ovladačům, které můžete získat pro Microsoft Windows, některé proprietární systémy UNIX (jako například Sun Solaris) nebo Mac OS X. LKM jsou zkompilovány pro konkrétní sadu zdrojů jádra a částečně linkovány do souboru objektu modulu, který má příponu .ko. Tyto soubory jsou načteny do běžícího jádra Linuxu prostřednictvím speciálních systémových volání.


300

Kapitola 9 – Moduly jádra Linuxu

Když je modul načten do jádra, jádro pro něj alokuje dostatek paměti a extrahuje informace ze sekce "modinfo" ELF1, která byla přidána k modulu během kompilace, aby mohly být splněny požadavky daného modulu. V době načtení je modul konečně linkován k exportovaným verzím funkcí běžícího jádra, k nimž se vztahují jeho závislosti a veřejně exportované symboly modulu se stanou součástí běžícího jádra. Tohle znamená, že modul se stane částí jádra. 1

Jak už bylo vysvětleno v kapitole 2, Linux široce využívá binární formát ELF jako de facto standard pro všechny uživatelské programy (a nahrazuje zastaralý formát a.out). Formát ELF specifikuje standardní kontejner pro binární data (včetně programů), která jsou rozdělena do mnoho různých sekcí.

V tuto chvíli nepochybně ve vašem systému využíváte některé natažitelné moduly jádra, protože jádro vašeho Linuxu bylo určitě zkompilováno tak, aby tyto natažitelné moduly podporovalo (pokud používáte nějakou standardní distribuci Linuxu). Vás systém má tudíž načteno několik modulů, aby bylo možné podporovat hardware detekovaný při startu počítače. Tyto moduly byly načteny automatickým správcem zařízení jako je například udev (který spravuje nejenom souborový systém v /dev, ale také načtené moduly pro nově detekovaná zařízení). Seznam aktuálně načtených modulů si můžete prohlédnout pomocí příkazu lsmod: $ /sbin/lsmod Module

Size

Used by

procfs

1732

0

char

2572

0

raw

7328

0

tun

9600

0

snd_rtctimer

2636

0

vmnet

35172

13

vmmon

111244

0

capability

3336

0

commoncap

5504

1

thermal

11272

0

fan

3588

0

button

5200

0

processor

19712

1

ac

3652

0

battery

7876

0

8250_pnp

8640

0

8250

25492

3

8250_pnp

serial_core

18944

1

8250

floppy

59972

0

pcspkr

1860

0

rtc

10868

1

usbnet

14024

0

capability

thermal

snd_rtctimer


Linux PROFESIONÁLNĚ – programování aplikací sd_mod

16704

2

eth1394

18376

0

ohci1394

33268

0

ieee1394

292568

2

emu10k1_gp

3072

0

ehci_hcd

32008

0

usb_storage

64128

1

scsi_mod

94760

2

ohci_hcd

19652

0

via686a

16712

0

i2c_isa

3968

1

uhci_hcd

31504

0

usbcore

120452

6

parport_pc

38276

0

parport

33608

1

shpchp

44512

0

pci_hotplug

11780

1

tsdev

6336

0

md_mod

64916

0

dm_mod

54552

0

psmouse

36420

0

ide_cd

38212

0

cdrom

37152

1

snd_cmipci

32288

1

gameport

12808

3

emu10k1_gp,snd_cmipci

snd_opl3_lib

9472

1

snd_cmipci

snd_mpu401_uart

6720

1

snd_cmipci

snd_emu10k1_synth

7040

0

snd_emux_synth

36160

1

snd_emu10k1_synth

snd_seq_virmidi

6464

1

snd_emux_synth

snd_seq_midi_emul

6784

1

snd_emux_synth

snd_seq_oss

32960

0

snd_seq_midi

7328

0

snd_seq_midi_event

6400

3

snd_seq_virmidi,snd_seq_oss,snd_seq_midi

snd_seq

50512

8

snd_emux_synth,snd_seq_virmidi,

eth1394,ohci1394

sd_mod,usb_storage

via686a usbnet,ehci_hcd,usb_storage,ohci_hcd,uhci_hcd parport_pc shpchp

ide_cd

snd_seq_midi_emul,snd_seq_oss, snd_seq_midi,snd_seq_midi_event snd_emu10k1

119652

5

snd_emu10k1_synth

snd_rawmidi

21600

4

snd_mpu401_uart,snd_seq_virmidi, snd_seq_midi,snd_emu10k1

snd_seq_device

7628

8

301

snd_opl3_lib,snd_emu10k1_synth, snd_emux_synth,snd_seq_oss,snd_seq_midi,


302

Kapitola 9 – Moduly jádra Linuxu snd_seq,snd_emu10k1,snd_rawmidi

snd_ac97_codec

94304

1

snd_emu10k1

snd_pcm_oss

50784

1

snd_mixer_oss

17728

3

snd_pcm_oss

snd_pcm

83460

4

snd_cmipci,snd_emu10k1,snd_ac97_codec,

snd_timer

22404

5

snd_ac97_bus

2176

1

snd_ac97_codec

snd_page_alloc

8904

2

snd_emu10k1,snd_pcm

snd_util_mem

3776

2

snd_emux_synth,snd_emu10k1

snd_hwdep

7840

3

snd_opl3_lib,snd_emux_synth,snd_emu10k1

snd

47844

20 snd_cmipci,snd_opl3_lib,snd_mpu401_uart,

snd_pcm_oss snd_rtctimer,snd_opl3_lib,snd_seq, snd_emu10k1,snd_pcm

snd_emux_synth,snd_seq_virmidi,snd_seq_oss, snd_seq,snd_emu10k1,snd_rawmidi, snd_seq_device,snd_ac97_codec, snd_pcm_oss,snd_mixer_oss,snd_pcm, snd_timer,snd_hwdep soundcore

8224

4

snd

r128

46912

1

drm

68308

2

r128

agpgart

29592

1

drm

8139too

23424

0

mii

5120

1

8139too

Jak sami vidíte, výstup je docela rozsáhlý a to se jedná o docela obyčejnou pracovní stanici. Výstup příkazu lsmod ukazuje, že v tomto linuxovém systému je načteno celkem 77 modulů. Některé z těchto modulů nemají jiné moduly, které by používaly jejich symboly exportované do jmenného prostoru jádra (znak nula ve třetím sloupci), zatímco jiné vytvářejí komplexní hierarchie zásobníků modulů – podívejte se například na ovladač zvuku ALSA, který poskytuje podporu pro dvě nainstalované zvukové karty (Creative Labs emu10k chipset a C-Media cmpci chipset) nebo na několik nainstalovaných USB modulů.

Rozšíření jmenného prostoru jádra Natažitelné moduly jádra Linuxu často exportují nové funkce pro použití jinými částmi jádra (dále v této kapitole se dozvíte, jak tato činnost probíhá). Tyto nové symboly budou zobrazeny uvnitř procfs prostřednictvím /proc/kallsyms (pokud vaše jádro obsahuje podporu pro toto sestavení) společně s adresami nových symbolů, které byly přidány do obrazu jádra. Zde je výpis z běžícího jádra pro /proc/kalsyms. Nejprve začátek tabulky symbolů: $ cat /proc/kallsyms | head c0100220 T _stext


Linux PROFESIONÁLNĚ – programování aplikací

303

c0100220 t rest_init c0100220 T stext c0100270 t do_pre_smp_initcalls c0100280 t run_init_process c01002b0 t init c0100430 t try_name c0100620 T name_to_dev_t c01008e0 t calibrate_delay_direct c0100a60 T calibrate_delay

A nyní následující spodní část tabulky symbolů jádra. Protože nové symboly jsou vždy přidávány na konec tabulky, můžete v tomto výstupu vidět několik symbolů modulů (jméno modulu je vypsáno v hranatých závorkách – v tomto případě pro správu zařízení MII Ethernet): $ cat /proc/kallsyms | tail e0815670 T mii_check_media

[mii]

e08154f0 T mii_check_gmii_support

[mii]

c023d900 U capable

[mii]

e0815600 T mii_check_link

[mii]

c011e480 U printk

[mii]

e08155a0 T mii_nway_restart

[mii]

c032c9b0 U netif_carrier_off

[mii]

e0815870 T generic_mii_ioctl

[mii]

c032c970 U netif_carrier_on

[mii]

e0815000 T mii_ethtool_gset

[mii]

Jak už jsme si uvedli výše, natažitelné moduly jsou uvedeny na konci výpisu tabulky se symboly jádra, přičemž jejich jméno je uvedeno v hranatých závorkách (viz [mii]). Také je snadno rozeznáte podle adresy v prvním sloupci výpisu. Protože jádro Linuxu je obvykle linkováno tak, aby běželo z 3 GB virtuální paměti, vestavěné symboly se objevují s malým offsetem nad 3 GB (0xc0000000). Načtené moduly ovšem existují v paměti, která je alokována pro jádro – v tomto případě nad 0xe0000000. To proto, že paměť pro moduly je alokována jádrem za běhu. Tento příklad byl záměrně upraven tak, aby vám dával větší smysl. Jádro obsahuje moduly, které nejsou šířeny pod licencí GPL, a jež jsou načteny výhradně kvůli podpoře oblíbeného komerčního produktu sloužícího k vytvoření virtuálního stroje. Stejná situace nastává v případě moderních grafických chipsetů. Vývojářská komunita ovšem nesnáší všechny moduly, které nejsou šířeny pod GPL, takže abyste mohli získat požadovanu podporu od vývojářské komunity, měli byste takové moduly odstranit z vašeho testovacího stroje.


304

Kapitola 9 – Moduly jádra Linuxu

Garance kompatibility modulů? Neexistuje! Na rozdíl od jiných operačních systémů Linux záměrně neposkytuje nějaký standardizovaný model ovladače, který byste mohli použít jako vzor při kompilaci vašich vlastních modulů za účelem dosažení kompatibility mezi aktuální verzí linuxového systému a budoucími verzemi. To znamená, že Linux je optimalizován pro případy, ve kterých je vždy dostupný zdrojový kód modulu (což by normálně mělo platit, protože mnoho lidí považuje moduly ovladačů, jež nejsou šířeny pod GPL licencí, za omezování práv vývojářů jádra, takže při psaní vašich modulů vám příliš nedoporučujeme experimentovat s binárními ovladači). Všeobecně byste neměli předpokládat, že moduly, které byly zkompilovány pro váš konkrétní linuxový systém, budou ve zkompilované binární formě běžet i na nějakých jiných linuxových strojích. Tyto moduly budou obvykle před svým spuštěním vyžadovat novou kompilaci ze zdrojů daného linuxového stroje. Existují ovšem významné výjimky – jádra dodavatelů Linuxu jsou často kompatibilní s jinými.

Nalezení kvalitní dokumentace Jedním z největších problémů, kterému musí čelit noví vývojáři pro Linux (a zvláště noví vývojáři pro jádro), je nalezení kvalitní API dokumentace pro každou z mnoha stovek a tisíců funkcí, s nimiž musí pracovat, aby využili možnosti, jež jsou jim nabízeny linuxovým jádrem. Pokud každodenně nepracujete s jádrem Linuxu, nedá se předpokládat, že byste pro tuto chvíli měli nějaké extra znalosti, takže práce s dobrou dokumentací bude nepostradatelnou součástí vaší práce. Jak jistě tušíte, problém spočívá v tom, že neexistuje dostatek kvalitní dokumentace. Linux se neustále vyvíjí, takže i dobrá dokumentace může být zastaralá již v okamžiku, kdy ji čtete. Povšimněte si, že autoři této knihy se ani nepokoušejí napsat dokumentaci k jádru Linuxu, takže tato kniha se spíše snaží vysvětlit povahu jádra a nabídnout příklady, které názorně demonstrují koncepty, jež můžete sami použít. Hlavními zdroji dokumentace ohledně vytváření nových modulů jádra jsou tak již existující moduly jádra2. 2

To znamená linuxové jádro, které je dostupné na adrese http://www.kernel.org.

Manuálové stránky jádra Linuxu Situace ovšem není tak špatná, jak by se mohlo zdát z předchozích odstavců. Existuje totiž jeden dobrý zdroj dokumentace k API – manuálové stránky jádra Linuxu. Tato dokumentace se snaží být za všech okolnosti co nejvíce aktuální a je dostupná na webu kernel.org, společně s mnoha jinými zdroji: http://www.kernel.org/pub/linux/docs/manpages. Tyto manuálové stránky si můžete ze zdrojových souborů jádra klidně vybudovat i sami. Stačí použít cíl mandocs příkazu make:


Linux PROFESIONÁLNĚ – programování aplikací

305

$ make mandocs MAN Documentation/DocBook/usb.9 Writing struct_usb_ctrlrequest.9 for refentry Writing struct_usb_host_endpoint.9 for refentry Writing struct_usb_interface.9 for refentry etc.

Vytvořené manuálové stránky pro jádro následně nainstalujte prostřednictvím cíle installmandocs příkazu make, aby mohly být dostupné pro příkaz man. Vaše linuxová distribuce může obsahovat balíčky s již vybudovanou verzí těchto manuálových stránek pro jádro Linuxu (společně s obvyklými manuálovými stránkami Linuxu), takže možná ani nebudete muset provádět jejich budování. Pokud máte distribuci Debian či Ubuntu (nebo distribuci odvozenou z nich), zkuste se po těchto balíčcích podívat.

A zde je jednoduchá ukázka, jak si můžete na vašem systému vyvolat manuálovou stránku pro funkci vmalloc(), která slouží pro alokaci paměti jádra. $ man vmalloc VMALLOC(9) LINUX VMALLOC(9) NAME vmalloc - allocate virtually contiguous memory SYNOPSIS void * vmalloc (unsigned long size); ARGUMENTS size allocation size DESCRIPTION Allocate enough pages to cover size from the page level allocator and map them into contiguous kernel virtual space. For tight cotrol over page level allocator and protection flags use __vmalloc instead. DESCRIPTION Allocate enough pages to cover size from the page level allocator and map them into contiguous kernel virtual space. For tight control over page level allocator and protection flags use __vmalloc instead. Kernel Hackers Manual July 2006 VMALLOC(9)

Tyto manuálové stránky vám budou pravděpodobně velmi užitečné, až začnete pracovat s linuxovým jádrem. Pokud máte odpovídající znalosti, nezapomeňte pomoci ostatním zdokumentovat ty části jádra, kde nedostatek informací způsobuje bolení hlavy mnoha vývojářům. Pokud každý vývojář pomůže zdokumentovat alespoň nějaký kousek chybějící části, bude vývoj jádra pro ostatní vývojáře mnohem méně komplikovanější.


306

Kapitola 9 – Moduly jádra Linuxu

Psaní modulů jádra Linuxu V kapitole 7 jsme vám na velmi jednoduchém příkladu předvedli ukázku vývoje pro jádro. Tento příklad předvedl, jak jsou kompilovány moduly jádra a jak jsou načteny do (binárně kompatibilního) běžícího jádra. Pomocí funkce jádra printk() mohl modul provádět zápis do logu při svém načtení či uvolnění z paměti jádra. V tomto okamžiku byste měli znát základní proces kompilace jádra a kompilaci modulů pro jádro. Pokud jste kapitolu 7 z nějakého důvodu vynechali, podívejte se zpět a ujistěte se, že těmto popsaným postupům rozumíte. Tato kapitola se bude věnovat základům psaní užitečných modulů jádra a bude se vás snažit vybavit schopností samostatně získat nové znalosti prostřednictvím dalších dostupných zdrojů. V rozsahu této jedné kapitoly bohužel není možné popsat všechny možné problémy, na které můžete narazit při vytváření kódu jádra (na něco takového by pravděpodobně nestačila ani celá kniha), nicméně informace, jež zde naleznete, byste měli být schopni vcelku bez problémů využít ve vaší programátorské praxi (za předpokladu, že budete studovat existující zdrojové kódy a používat už dříve zmiňovanou dokumentaci pro vytváření kompletních modulů linuxového jádra). Vaše programování by nemělo spočívat pouze ve vývoji natažitelných modulů, které budou drženy mimo hlavní linii vývoje Linuxu. Linux jako takový je mnohem více než jádro, pro které vytváříte ovladače – je to celá komunita. Vaším cílem by vždy mělo být dostat nový kód co nejdříve do hlavní vývojové linie jádra. Je možné, že při vaší vývojářské práci zjistíte, že některé věci, které si přejete udělat, nelze implementovat pomocí modulů, protože vyžadují změny v základním kódu samotného jádra. To je ovšem problematika, které se tato kniha specificky nevěnuje, protože změny základního kódu s sebou nesou obrovské množství otázek, jejichž zodpovězení je lepší nechat na větších znalcích z této oblasti.

Než začnete S odpovídajícím vývojovým a testovacím prostředím jste se seznámili v kapitole 7. Pamatujte si, že i ti nejzkušenější linuxoví odborníci dělají chyby, dopouštějí se různých překlepů, či provádějí jiné činnosti, které mají za následek destabilizaci jejich testovacího prostředí. Jakmile ztratíte přehled o ukazatelích a jiných zdrojích uvnitř jádra, jsou pro vás ztraceny navždy. Při zápisu dat do paměti můžete také omylem odstranit celý obsah paměti RAM, takže už vám nic nebude stát v cestě. Pokud budete testovat kód jádra na stejném počítači, na kterém provádíte jeho vývoj, s velkou pravděpodobností nakonec skončíte s ošklivými pády systému a neustálým rebootováním, takže něco takového prostě nedělejte. Pro testování vašeho kódu si pro začátek obstarejte nějaký starší, nicméně stále funkční stroj, který je určen na vyhození. Pokud budete později potřebovat pro váš vývoj nějaký specifický hardware, nezapomeňte ho přidat k vhodnému počítači. Důrazně vám radíme, abyste na vašem vývojovém stroji používali síťové sdílení pro rychlé zpřístupnění jádra a modulů vašemu testovacímu počítači – pro další podrobnosti se podívejte do online nápovědy. A na závěr tohoto úvodního textu musíme zmínit jeden důležitý bod, který vyžaduje neustálé opakování – nikdy nepředpokládejte, že váš testovací stroj bude stabilní.


Linux PROFESIONÁLNĚ – programování aplikací

307

Základní požadavky modulů Každý modul jádra Linuxu vyžaduje definovaný vstupní a výstupní bod. Tyto dva body popisují funkce, které budou volány při načtení a uvolnění modulu z paměti. Každý modul by navíc měl specifikovat svého autora, číslo verze a poskytnout stručný popis služeb, které zpřístupňuje, aby uživatelé, administrátoři a vývojáři mohli rychle získat představu o účelu zkompilovaných modulů prostřednictvím standardních utilit, jako například modinfo (viz kapitola 7 a 8). A zde je příklad holého minima pro natažitelný modul, který může být zkompilován: /* * plp_min.c - Minimal example kernel module. */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> /* function prototypes */ static int __init plp_min_init(void); static void __exit plp_min_exit(void); /* * plp_min_init: Load the kernel module into memory */ static int __init plp_min_init(void) { printk("plp_min: loaded"); return 0; } /* * plp_min_exit: Unload the kernel module from memory */ static void __exit plp_min_exit(void) { printk("plp_min: unloading"); } /* declare init/exit functions here */ module_init(plp_min_init); module_exit(plp_min_exit); /* define module meta data */ MODULE_AUTHOR("Jon Masters <jcm@jonmasters.org>"); MODULE_DESCRIPTION("A minimal module stub"); MODULE_ALIAS("minimal_module"); MODULE_LICENSE("GPL"); MODULE_VERSION("0:1.0");


308

Kapitola 9 – Moduly jádra Linuxu

Tento modul zkompilujte obvyklým způsobem: $ make –C 'uname –r'/build modules M=$PWD

A následně se podívejte na výstup z běžícího příkazu modinfo použitého na tento modul: $ /sbin/modinfo plp_min.ko filename:

plp_min.ko

author:

Jon Masters <jcm@jonmasters.org>

description:

A minimal module stub

alias:

minimal_module

license:

GPL

version:

0:1.0

vermagic:

2.6.15.6 preempt K7 gcc-4.0

depends: srcversion:

295F0EFEC45D00AB631A26C

Povšimněte si, že verze modulu je zobrazena společně s vygenerovaným kontrolním součtem. Zvykněte si vždy přidávat k vašim modulům verzi, aby vývojáři, kteří budou později balíčkovat vaše moduly, mohli používat nástroje jako modinfo pro automatické získání těchto informací.

module.h Všechna linuxová jádra musí obsahovat <linux/module.h> společně s dalšími hlavičkovými soubory, které používají. Module.h definuje řadu maker, která jsou používána kompilačním systémem jádra pro přidání nezbytných metadat ke zkompilovaným souborům modulů. Když si prohlédnete vygenerované zdrojové soubory v C, které končí na .mod.c, a jež vznikly během kompilace, můžete získat představu o tom, jakým způsobem jsou tato makra používána. Následující tabulka popisuje některá speciální hlavičková makra a funkce, jež jsou dostupné. Makra a funkce, které jsou uvedeny v této tabulce, by měly být použity v každém modulu vždy, když je to vhodné. Obvykle jsou vloženy na konec zdrojového kódu modulu. makro/funkce

Popis

MODULE_ALIAS (_alias)

Poskytuje alias pro uživatelský prostor. Dovoluje nástrojům, které načítají a uvolňují moduly, rozpoznat alias. Modul intel-agp (stejně jako mnoho ovladačů pro PCI) specifikuje řadu identifikátorů PCI zařízení, které jsou podporovány ovladačem, a jež mohou nástroje uživatelského prostoru použít pro automatické nalezení ovladače: MODULE_ALIAS ("pci:v00001106d00000314sv *sd*bc06sc00i00*")


KAPITOLA 13 Grafika a zvuk Mnoho aspektů profesionálního programování vyžaduje pokročilou podporu grafiky a zvuku. Vše od vytváření matematických modelů až po psaní nejnovějších akčních her vyžaduje schopnost kreslit (a také animovat) složité geometrické objekty. V případě současného šílení po multimédiích je zase vyžadováno zpracování zvukových souborů jak v digitální podobě, tak i přímo z audio CD. Bohužel, většina standardních programových nástrojů, které jsou obsaženy ve většině linuxových systémů, neposkytuje metody potřebné pro vývoj pokročilých grafických a zvukových programů. Tato kapitola popisuje dva nástroje, které lze přidat do vašeho programového vybavení, a jež vám pomohou ve vašem úsilí vytvářet pokročilou grafiku a zvuky pro vaše linuxové aplikace.

Linux a grafika Většina linuxových distribucí je dnes založena na grafice. Když startujete systém, jste přivítáni grafickou přihlašovací obrazovkou, která často obsahuje efektní obrázek na pozadí a grafický seznam uživatelů a příslušných voleb. Jakmile se přihlásíte do linuxového systému, ocitnete se v grafickém desktopovém prostředí, které obsahuje nejenom různé ikony pro programy a zařízení, ale také systémové menu s ikonami pro vybrané aplikace. Spuštění programu pak spočívá v jednoduchém kliknutí na příslušnou ikonu na ploše nebo výběrem odpovídající položky z menu. Aby se tohle mohlo uskutečnit, Linux musí za scénou provádět velkou spoustu věcí. Existuje mnoho programového kódu, který je použit pro zobrazení grafiky na Linuxu. Grafické programování je jedním z nejsložitějších programovacích prostředí v Linuxu. Manipulace grafickými objekty vyžaduje znalost, jak grafická karta komunikuje s monitorem při vytváření obrázků na obrazovce. Naštěstí dnes už existuje několik nástrojů, které dokáží programátorům grafiky v Linuxu hodně usnadnit život. Tato sekce popisuje celkem čtyři nástroje, které jsou používány pro práci s grafikou v prostředí Linuxu: X Windows, OpenGL, GLUT a SDL.


Kapitola 13 – Grafika a zvuk

424

X Windows Nejrozšířenější formou grafiky, která je poskytována současnými operačními systémy, je systém oken. Kromě populárního systému od Microsoftu, který je podle nich nazván, existuje několik dalších operačních systémů, jež poskytují programátorům grafické okenní prostředí. Linux se k této grafické revoluci připojil tím, že rovněž nabídli několik prostředí založených na oknech. Ve všech operačních systémech existují dva základní prvky, které ovládají grafické prostředí: grafická karta instalovaná v počítači a monitor, jenž všechno zobrazuje. Oba tyto prvky musí být správně detekovány a řízeny, aby nějaký program mohl zobrazovat grafiku. Celý vtip spočívá v získání snadného přístupu k těmto prvkům. Linuxové distribuce pro ovládání grafiky používají grafický standard X Windows. Standard X Windows definuje protokoly, které slouží jako rozhraní mezi grafickými aplikacemi a systémovou grafickou kartou + monitorem. Od té doby, co se X Windows stal standardem, poskytuje společné rozhraní pro mnoho různých grafických karet a monitorů. Aplikace, které jsou napsány pro X Windows, mohou běžet na jakémkoliv systému s libovolnou kombinací grafické karty a monitoru, pokud daná kombinace grafické karty a monitoru umí pracovat s rozhraním X Windows. To je znázorněno na obrázku 13.1.

Obrázek 13.1. Standard X Windows sám o sobě představuje pouze specifikaci, nikoliv konkrétní produkt. Jednotlivé operační systémy používají odlišný software X Windows pro implementaci standardu X Windows. V linuxovém světě dnes existují dva softwarové balíčky, které X Windows implementují: 

XFree86.



X.org.

Softwarový balíček XFree86 je nejstarší implementací standardu X Windows. Po dlouhou dobu se jednalo o jediný balíček X Windows, který byl dostupný pro Linux. Jak už plyne z jeho jména, jedná se o svobodnou (a open source) implementaci navrženou pro systémy Intel x86.


Linux PROFESIONÁLNĚ – programování aplikací

425

Nedávno ovšem na linuxovou scénu vstoupil nový balíček nazvaný jako X.org. Program X.org je považován za vývojového následníka programu XFree86 a rychle si získal oblibu v různých linuxových distribucích – hlavně díky podpoře pokročilejších vlastností než měl XFree 86. Mnoho distribucí Linuxu tak v současnosti používá X.org místo staršího XFree86. Oba balíčky pracují stejným způsobem – řídí komunikaci Linuxu s grafickou kartou a zobrazují grafický obsah na monitoru uživatele. Aby tohle bylo možné, X Windows vyžaduje specifickou konfiguraci vzhledem k systému, na kterém běží. V dávných dobách Linuxu jste se museli prodírat ohromným konfiguračním souborem a ručně upravovat volby programu XFree86 pro konkrétní typ grafické karty a monitoru. Použití špatné konfigurace mohlo znamenat zničení drahého monitoru. V současnosti ovšem většina linuxových distribucí při své instalaci automaticky detekuje vlastnosti grafické karty a monitoru, takže bez jakéhokoliv zásahu uživatele dojde k vytvoření odpovídajících konfiguračních souborů. V době své instalace Linux detekuje vlastnosti grafické karty a monitoru a následně vytvoří odpovídající konfigurační soubor pro X Windows, který obsahuje nalezené informace. Při instalaci Linuxu si můžete povšimnout okamžiku, kdy je zkoumán monitor kvůli zjištění podporovaných grafických režimů. Někdy to způsobí, že monitor po několik sekund nic nezobrazuje. Protože existuje mnoho rozdílných typů karet a monitorů, dokončení tohoto procesu může trvat nějakou dobu. Pokud váš systém obsahuje nějakou novější a pokročilejší grafickou kartu, instalační proces nemusí zvládnout proces automatické detekce. A aby se věci ještě více zhoršily, některé distribuce Linuxu se nedokáží nainstalovat, pokud nebudou schopny zjistit nastavení grafické karty. Jiné distribuce vám v případě selhání autodetekce mohou položit několik otázek, aby bylo možné alespoň tímto způsobem získat nějaké informace. A ještě jiné distribuce mohou přejít v případě selhání autodetekce na nejnižší společný jmenovatel, čímž se vytvoří obraz, který není přizpůsoben konkrétnímu grafickému prostředí. Mnoho uživatelů PC má k dispozici fantastické grafické karty, aby mohli hrát moderní počítačové hry ve vysokém rozlišení. Tyto grafické akcelerátory obsahují specializovaný hardware, který společně s dodávaným softwarem dokáže zvyšovat rychlost vykreslování trojrozměrných objektů na obrazovce. V minulosti ovšem tento speciální grafický hardware způsoboval spoustu problémů při pokusu o instalaci do linuxového systému. Výrobci těchto grafických karet ovšem pomalu začínají tyto problémy řešit, takže ke svým produktům konečně poskytují ovladače určené pro Linux. A mnoho dnešních linuxových distribucí, které jsou upraveny pro koncové uživatele, dokonce obsahuje i vlastní ovladače pro takové grafické karty. Jakmile je dostupné prostředí X Windows, aplikace ho mohou použít pro interakci s grafickým prostředím na linuxovém systému. Oblíbené desktopy KDE a GNOME běží v prostředí X Windows a využívají volání API X Windows pro vykonání všech vykreslovacích funkcí. Přestože X Windows je výborný pro tvorbu programů v okenním prostředí, existují určité meze toho, co všechno smí systém X Windows dělat. Protože se jedná o trochu starší standard, systém X Windows neobsahuje podporu pro spoustu moderních věcí. Tento nedostatek se projeví zejména v případě, kdy chce programátor vytvářet pokročilé grafické aplikace, které mají pracovat s trojrozměrnými objekty. K tomuto typu programování tak musíte použít jiné balíčky.


426

Kapitola 13 – Grafika a zvuk

OpenGL Knihovna OpenGL (Open Graphic Library) byla vytvořena za účelem poskytnutí společného API pro přístup k pokročilým grafickým vlastnostem, které jsou obsaženy v grafických kartách s 3-D akcelerátorem. Zatímco standard X Windows se zaměřuje na poskytnutí okenního prostředí pro programátory, OpenGL projekt se zaměřuje na poskytnutí API, které jsou specifické pro vykreslování pokročilých dvojrozměrných (2D) a trojrozměrných (3D) objektů. Podobně jako X Windows, ani projekt OpenGL projekt není specifickou softwarovou knihovnou s funkcemi. Naopak – jedná se o obecné specifikace pro funkce, které jsou vyžadovány pro vykreslování grafických objektů na výkonných grafických pracovních stanicích. Jednotliví výrobci grafických karet si pořizují licence ke specifikacím OpenGL, aby mohli vytvořit příslušné API pro své konkrétní grafické karty. Programátoři pak mohou využívat tato stejná API pro interakci s různými grafickými kartami podporujícími OpenGL. Místo použití specifické knihovny OpenGL pro konkrétní grafickou kartu je rovněž možné použít obecnou OpenGL knihovnu, která je implementována plně softwarově. Tato softwarová knihovna převede všechny 2D a 3D objekty do standardních volání funkcí X Windows, které mohou být obslouženy standardními grafickými kartami. Podívejte se na obrázek 13.2.

Obrázek 13.2. Program Mesa je oblíbeným balíčkem, který poskytuje softwarovou implementaci funkcí knihovny OpenGL. Program Mesa je často standardně instalován na linuxovém systému, který sice nemá k dispozici moderní grafickou 3D kartu, nicméně potřebuje implementovat pokročilou 3D grafiku. Program Mesa totiž obsahuje několik knihoven pro vývojáře, takže ho lze použít k vytvoření vlastních 2D a 3D aplikací bez nutnosti kupovat moderní grafickou kartu s 3D akcelerátorem. Libovolný program, který je napsán tak, aby běžel v Mese, bude fungovat i případě použití pokročilé grafické kartě s podporou OpenGL.


Linux PROFESIONÁLNĚ – programování aplikací

427

OpenGL Utilities Toolkit Knihovna OpenGL sice poskytuje funkce pro pokročilou 2D a 3D grafiku, nicméně neposkytuje funkce pro standardní programování oken. Aby se mohl kompenzovat tento nedostatek OpenGL, Mark Kilard vyvinul GLUT (OpenGL Utility Toolkit). GLUT je založen na specifikacích OpenGL, které jsou zkombinovány s obecnými funkcemi pro okna. Tím je vytvořena kompletní knihovna funkcí, která se dá použít pro snadnější vytváření oken, interakci s uživatelem či vykreslování 2D/3D objektů. Knihovna GLUT tak slouží jako zprostředkující vrstva mezi OpenGL a systémem X Windows. Stejně jako v případě OpenGL i v tomto případě mnoho výrobců grafických karet pro své výrobky poskytuje specifickou knihovnu GLUT. I program Mesa poskytuje plně softwarovou implementaci GLUT pro méně pokročilé grafické systémy. Pokud využíváte OpenGL pro vytváření grafických objektů, pravděpodobně budete chtít používat i knihovnu GLUT pro usnadnění vaší práce.

Simple Directmedia Layer OpenGL a GLUT jsou výborné, pokud potřebujete vykreslovat mnohoúhelníky a rotovat je kolem vlastní osy, ale v některých grafických prostředích si s tímto nemusíte vystačit. Mnoho programů (zejména hry) kromě vykreslování objektů rovněž potřebuje rychle zobrazovat na monitoru různé obrázky. Většina her také potřebuje přístup k zvukovému systému pro přehrávání zvukových efektů a hudby, stejně jako přístup ke klávesnici (či joysticku) kvůli interakci s uživatelem. Dělat tyto činnosti prostřednictvím GLUT rozhodně není snadný úkol. V takových situacích se hodí herní knihovny vyšší úrovně. Nejoblíbenější grafickou a zvukovou knihovnou pro Linux je knihovna nazvaná Simple Directmedia Layer (SDL). Knihovna SDL poskytuje mnoho pokročilých funkcí pro manipulaci se soubory obrázků na obrazovce, vytváření animací z obrázků, přístup ke zvuku či k obsluze událostí klávesnice a myši (a dokonce joysticku). Knihovna SDL je určena pro více platforem, takže můžete snadno najít implementace SDL pro většinu operačních systémů. Aplikaci můžete vyvinout pomocí SDL na vašem Linuxu a snadno ji portovat do prostředí Microsoft Windows nebo Apple Macintosh. Tato vlastnost vlastně způsobila, že knihovna SDL je velmi oblíbena mezi profesionálními programátory her. Díky této skutečnosti rovněž spousta profesionálních vývojářů her přechází k SDL, aby si usnadnili portaci her z platformy Windows na Linux.

Vytváření aplikací OpenGL Pro vytvoření aplikace OpenGL potřebujete mít na vašem Linuxu nejenom runtime knihovnu OpenGL, ale také mnoho dalších vývojových knihoven. Splnit tyto požadavek může být obtížné, protože knihovna OpenGL není open source. Specifikace k OpenGL nejsou k dispozici zdarma. Jinak řečeno – od společnosti SGI (Silicon Graphics Incorporated) musíte mít k dispozici licencovanou kopii tohoto softwaru, abyste ho mohli provozovat na vašem linuxovém systému. Mnoho


428

Kapitola 13 – Grafika a zvuk

výrobců grafických karet ovšem pro své konkrétní grafické karty poskytuje licencované knihovny OpenGL. Pokud takovou grafickou kartu se specifickými ovladači OpenGL nemáte k dispozici – a přesto chcete programovat v OpenGL – můžete použít nějakou softwarovou implementaci OpenGL, např. již zmiňovaný program Mesa. Tento open source program, který byl vytvořen Brianem Paulem ve formě jednoduché implementace knihovny OpenGL, lze označit za daleko nejoblíbenější softwarovou implementaci OpenGL. Protože jeho autor netvrdí, že Mesa je kompatibilní náhradou za OpenGL, neposkytuje žádnou licenci OpenGL pro Mesu. Mesa vám místo toho nabízí prostředí, které je podobné syntaxi příkazů OpenGL, a jež bylo společností SGI autorizováno pro distribuci v podobě otevřeného kódu. Použitím Mesy neporušíte žádná licenční omezení. Pomocí programového prostředí Mesa tak můžete vyvíjet OpenGL aplikace, které budou fungovat na každé implementaci OpenGL. Na vašem linuxovém prostředí navíc můžete spouštět runtime knihovny Mesy bez nutnosti vlastnit licenci od SGI. Jak už bylo zmíněno v sekci OpenGL Utilities Toolbox, knihovna OpenGL neposkytuje nezbytnou funkcionalitu pro vytváření oken. Naštěstí projekt Mesa zahrnuje i knihovny GLUT, což vám dovoluje vytvářet plně funkční aplikace s grafickými okny v jediném vývojovém prostředí. Tato kapitola předvádí vývoj OpenGL aplikací prostřednictvím knihoven Mesa. Následující sekce popisuje, jak stáhnout a nainstalovat knihovny Mesy a jak je použít pro vytvoření OpenGL aplikací, které mohou běžet na libovolné implementaci OpenGL.

Stažení a instalace Mnoho distribucí Linuxu již obsahuje instalační balíčky pro Mesu, nehledě na skutečnost, že většina linuxových distribucí instaluje runtime knihovny zcela standardně. To umožňuje spouštět OpenGL aplikace i bez přítomnosti pokročilé 3D grafické karty. Abyste mohli vyvíjet OpenGL aplikace, pravděpodobně budete muset nainstalovat hlavičkové soubory Mesy společně se soubory knihovny. Obojí je obsaženo v instalačních balíčcích se jmény jako mesa-devel. Pokud nemůžete najít vývojový balíček Mesy pro vaši konkrétní distribuci Linuxu, nebo pokud dáváte přednost práci s poslední verzí balíčku, nahlédněte na webovou stránku Mesy. Webová stránka projektu Mesa se nachází na adrese www.mesa3d.org. Na hlavní stránce klikněte na odkaz Downloading/Unpacking (Stáhnout/Rozbalit) a stáhněte si nejnovější knihovny Mesy. Existují tři softwarové balíčky, které lze stáhnout: 

MesaLib-x.y.z. Hlavní soubory knihovny Mesa OpenGL.



Mesa-demos-x.y.z. Skupina ukázkových programů OpenGL pro demonstraci programování v OpenGL.



MesaGLUT-x.y.z. Implementace GLUT (OpenGL Utility Toolkit) pro Mesu.

Označení x.y.z specifikuje verzi balíčku Mesy, kde x znamená hlavní číslo verze, y vedlejší číslo verze a z číslo záplaty. Mesa dodržuje systém číslování, kde všechna sudá vedlejší čísla verze (y)


Linux PROFESIONÁLNĚ – programování aplikací

429

znamenají stabilní verze. Lichá čísla pak označují vývojové verze. V době psaní této knihy byla nejnovější stabilní verzí 6.4.2 a vývojovou verzí 6.5.1. Pro tvorbu OpenGL aplikací na vašem linuxovém systému byste si měli stáhnout minimálně balíčky MesaLib a MesaGLUT. Tohle vám poskytne kompletní vývojové prostředí OpenGL a GLUT pro vytváření vašich aplikací. Nicméně i balíček Mesa-demos je užitečný. Soubory můžete stáhnout ve formátech .tar.gz nebo .zip (podle toho, který se více hodí pro vaši konkrétní distribuci Linuxu). Balíčky stáhněte do pracovního adresáře a pro jejich rozbalení použijte příkazy tar nebo unzip. Všechny balíčky rozbalte do stejného adresáře Mesa-x.y.z. Po stažení a rozbalení balíčků můžete zkompilovat knihovny (a ukázkové programy, pokud jste si stáhli i balíček Mesa-demos). Mesa nepoužívá program configure pro zjištění kompilačního prostředí. Místo toho se používají různé cíle programu make (jeden cíl pro každý typ podporovaného prostředí). Pro zobrazení všech dostupných cílů napište do příkazové řádky příkaz make. Následně bude zobrazen seznam všech dostupných cílů příkazů make. Pro linuxové systémy můžete použít obecný cíl Linux nebo cíl, který je specifický pro vaše prostředí (jako například Linux-x86). Odpovídající název cíle jednoduše vložte ihned za příkaz make. $ make linux-x86

Po zkompilování souborů knihovny na vašem systému se můžete rozhodnout, že hlavičkové soubory a soubory knihovny nainstalujete do jejich standardních umístění ve vašem systému. Implicitní cíl příkazu make install nainstaluje hlavičkové soubory do adresáře /usr/local/include/GL. Soubory knihovny pak do adresáře usr/local/lib. Jednou z hezkých věcí na OpenGL je skutečnost, že do různých umístění můžete nainstalovat více verzí souborů knihovny OpenGL (například jednu verzi pro grafickou kartu + softwarové knihovny Mesa). Když spustíte vaši aplikaci, můžete si zvolit, kterou knihovnu použijete pro implementaci funkcí OpenGL. Můžete tak porovnat výkon různých verzí knihoven.

Programovací prostředí Po instalaci všech souborů potřebných pro Mesu OpenGL a GLUT můžete začít vytvářet vaše vlastní programy. Do vaší aplikace ovšem musíte zahrnout umístění hlavičkových souborů (pomocí standardního příkazu #include): #include <GL/gl.h> #include <GL/glut.h>

Když kompilujete vaše aplikace OpenGL, musíte prostřednictvím parametrů -l pro linker zahrnout nejenom umístění hlavičkových souborů, ale také knihovny Mesa OpenGL a GLUT: $ cc -I/usr/local/include -o test test.c -L/usr/local/lib -lGL -lglut

Povšimněte si, že knihovna pro Mesa OpenGL (GL) je specifikována velkými písmeny, zatímco knihovna GLUT písmeny malými. Do souboru /etc/ld/so.conf byste také měli zahrnout adre-


430

Kapitola 13 – Grafika a zvuk

sář /usr/local/lib, aby Linux mohl vyhledat dynamické soubory knihovny OpenGL a GLUT. Po úpravě tohoto souboru nezapomeňte spustit program ldconfig. A tímto jsme si řekli všechno potřebné, takže se konečně můžeme pustit do vytváření vaší první aplikace OpenGL.

Použití knihovny GLUT Jak lze očekávat, knihovna GLUT obsahuje mnoho funkcí pro vytváření oken, kreslení objektů či obsluhu vstupu od uživatele. Tato sekce ukazuje několik základních principů ohledně používání knihovny GLUT pro tvorbu následujících jednoduchých grafických aplikací. 

Vytvoření okna.



Kreslení objektů v okně.



Zpracování vstupu od uživatele.



Animace kreseb.

Předtím, než budete moci kreslit, musíte mít pracovní prostor. Pracovním prostorem v GLUT je okno. Následující první téma ukazuje, jak pomocí knihovny GLUT vytvořit okno standardního prostředí X Windows. Po úspěšném vytvoření okna můžete použít základní příkazy knihovny GLUT pro kreslení různých objektů, jako například čar, trojúhelníků, mnohoúhelníků a dalších komplexních matematických modelů. Při práci v prostředí okna je klíčové zachytit vstup od uživatele. Vaše aplikace musí být schopna detekovat nejenom události klávesnice, ale také pohyb kurzorem myši. A nakonec skoro každý herní program vyžaduje nějakou animaci. Knihovna GLUT naštěstí poskytuje příkazy pro jednoduchou animaci objektů, které mohou oživit vaše objekty.

Vytvoření okna Nejzákladnějším prvkem každého grafického programu je okno, do kterého jsou umístěny samotné grafické objekty. Existuje celkem pět funkcí, které jsou běžně používány pro inicializaci prostředí GLUT a vytvoření okna: void glutInit(int argc, char **argv); void glutInitDisplayMode(unsigned int mode); void glutInitWindowSize(int width, int height); void glutInitWindowPosition(int x, int y); int glutCreateWindow(char *name);

Tato uvedená volání funkcí jsou přítomna prakticky v každém OpenGL programu. Funkce glutInit() inicializuje knihovnu GLUT a používá parametry příkazové řádky k definici toho, jak bude GLUT komunikovat se systémem X Windows. Parametry funkce glutInit() pro příkazový řádek jsou následující: 

display. Specifikuje X server, ke kterému se má připojit.


Linux PROFESIONÁLNĚ – programování aplikací 

geometry. Specifikuje umístění okna na X serveru.



iconic. Vyžaduje, aby všechna okna nejvyšší úrovně byla vytvořena v ikonickém stavu.



indirect. Vynucené použití nepřímého kontextu renderování OpenGL.



direct. Vynucené použití přímého kontextu renderování OpenGL.



gldebug. Zavolá glGetError po každém volání funkce OpenGL.



sync. Povoluje synchronní transakce protokolu X Windows.

431

Další funkce glutInitDisplayNode() pak specifikuje režim zobrazení, který bude použit pro prostředí OpenGL. Režim zobrazení je možné definovat následující řadou hodnot přepínačů: Přepínač

Hodnota

GLUT_SINGLE

Poskytuje jedno bufferované okno.

GLUT_DOUBLE

Poskytuje dvě bufferovaná okna, mezi kterými se lze přepínat.

GLUT_RGBA

Řídicí okno založené na hodnotách RGB.

GLUT_INDEX

Řídicí okno založené na indexu barev.

GLUT_ACCUM

Poskytuje akumulační buffer pro okno.

GLUT_ALPHA

Poskytuje komponentu průhlednosti pro barvu okna.

GLUT_DEPTH

Poskytuje okno s bufferem barevné hloubky.

GLUT_STENCIL

Poskytuje okno s bufferem šablon.

GLUT_MULTISAMPLE

Poskytuje okno s podporou multisamplingu.

GLUT_STEREO

Poskytuje stereo buffer okna.

GLUT_LUMINANCE

Poskytuje komponentu průhlednosti pro barvu okna.

Funkce glutInitWindowSize() a glutInitWindowPosition() dělají přesně to, co naznačuje jejich název – dovolují vám stanovit počáteční velikost okna (v pixelech) a jeho pozici (založenou na souřadnicovém systému okna). Základní bod souřadnicového systému oken (0,0) je v levém dolním rohu okna displeje. Osa x probíhá podél dolní strany displeje, osa y podél levé strany displeje. Funkce glutCreateWindow() vytváří skutečné okno. Použité parametry specifikují název okna, který je zobrazen v pruhu v horní části okna. Po vytvoření okna může začít skutečná zábava. Protože se jedná o programování řízené událostmi, GLUT se v tomto ohledu podobá všem ostatním programovacím jazykům, které jsou založeny na oknech. Místo lineárního postupu kódem aplikace při provádění příkazů čeká GLUT na události, které se stanou uvnitř vytvořeného okna. Když dojde k takové události, bude vykonána funkce zpětného volání, která je s ní spojena. GLUT pak začne čekat na další událost.


432

Kapitola 13 – Grafika a zvuk

Všechna činnost v programech, které jsou založeny na oknech, probíhá prostřednictvím funkcí zpětného volání. To znamená, že musíte poskytnout kód pro události, které se stanou ve vaší aplikaci (což je například situace, kdy uživatel stiskne tlačítko myši nebo klávesu na klávesnici). GLUT poskytuje několik volání funkcí, která vám umožní registrovat vaše vlastní funkce zpětného volání, jež budou GLUT zavolány při výskytu specifických událostí: Funkce

Popis

GlutDisplayFunc (void (*func) void)

Specifikuje funkci, která bude zavolána, když bude potřeba překreslit obsah okna.

GlutReshapeFunc (void (*func)

Specifikuje funkci, která bude zavolána, když bude potřeba změnit velikost nebo polohu okna.

int width, int height) GltKeyBoardFunc (void (*func ) (unsigned int key, int x, int y) GlutSpecialFunc (void (*func) (int key, int x, int y) GlutMouseFunc (void )*func) intButton, int state, int x, int y) GlutMotionFunc (void (*func) (int x, int y) GlutTimerFunc (int msec, void

Specifikuje funkci, která bude zavolána při stisknutí nějaké ASCII klávesy. Specifikuje funkci, která bude zavolána při stisknutí speciální klávesy, například šipka nebo F1-F12. Specifikuje funkci, která bude zavolána při stisknutí nebo uvolnění tlačítka myši. Specifikuje funkci, která bude zavolána při pohybu kurzoru myši v okně.

(*func) (int value), value)

Specifikuje funkci, která bude zavolána po uplynutí času specifikovaného pomocí argumentu msec.

GlutPostRedisplay (void)

Označuje aktuální okno k překreslení.

Pokud nebudete registrovat nějakou funkci s nějakou událostí, GLUT se nebude snažit předat výskyt této události vašemu programu. Jinak řečeno – taková událost bude ignorována. Po registraci vašich funkcí s událostmi musíte použít funkci glutMainLoop(), aby GLUT mohl začít čekat na výskyt daných událostí. Program testwin.c, který je ukázán v následujícím výpisu, demonstruje vytvoření okna v prostředí GLUT a nakreslení jednoduchého objektu v okně. /* * Professional Linux Progamming - OpenGL window test */ #include <GL/gl.h> #include <GL/glut.h> void display(void) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT);


Linux PROFESIONÁLNĚ – programování aplikací

433

glColor3f(1.0, 1.0, 1.0); glRotatef(30, 1.0, 0.0, 0.0); glRotatef(30, 0.0, 1.0, 0.0);) glutWireTetrahedron(); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowSize(250, 250); glutInitWindowPosition(0, 0); glutCreateWindow("Test Window"); glutDisplayFunc(display); glutMainLoop(); return 0; }

Sekce main() programu testwin.c používá standardní inicializační funkce GLUT pro vytvoření okna, které zobrazí OpenGL kreslení. Je registrována funkce zpětného volání pro obsluhu zobrazení okna. Následně je spuštěna hlavní smyčka událostí GLUT. Funkce zpětného volání display je použita pro kontrolu toho, co je umístěno do okna. To je místo, kde se odehrává veškerá činnost. Předtím, než do okna cokoliv umístíte, bude vhodné okno vyčistit od čehokoliv, co se v něm může nacházet. Pro takové vyčistění okna je použita funkce glClear(). Barvu pozadí použitou pro vyčistění okna lze nastavit pomocí funkce glClearColor(), která používá následující čtyři parametry: glClearColor(float red, float green, float blue, float alpha)

Parametry red, green a blue určují množství červené, zelené a modré přidané do barvy pozadí. Hodnota 0.0 znamená vůbec nic, hodnota 1.0 pak maximální hodnotu dané barvy. Pokud stejně jako já nevíte, jak smícháním červené, zelené a modré barvy vytvořit požadovanou barvu, zde je tabulka, která ukazuje některé základní barevné kombinace: Červená

Zelená

Modrá

Barva

0.0

0.0

0.0

černá

1.0

0.0

0.0

červená

0.0

1.0

0.0

zelená

1.0

1.0

0.0

žlutá

0.0

0.0

1.0

modrá

1.0

0.0

1.0

fialová


434

Kapitola 13 – Grafika a zvuk

Červená

Zelená

Modrá

Barva

0.0

1.0

1.0

modrozelená

1.0

1.0

1.0

bílá

Pamatujte si, že se jedná o hodnoty s plovoucí desetinnou čárkou, takže mezi hodnotami 0.0 a 1.0 existuje velké množství odstínů. Nicméně věříme, že tato tabulka vám poskytla alespoň základní představu o tom, jak namíchat požadovanou barvu. Parametr alpha řídí průhlednost aplikovanou na barvu. Hodnota 0.0 indikuje, že žádná průhlednost není použita, hodnota 1.0 pak znamená, že je použita maximální průhlednost. Po nastavení hodnoty barvy pozadí a vyčistění pozadí můžete začít kreslit. Barva kresleného objektu je stanovena pomocí funkce glColor3f(). Tato funkce definuje barvu pomocí tří RGB hodnot (červená, zelená, modrá). Hodnoty je opět možné zadávat v rozmezí od 0.0 do 1.0. Tabulku s kombinacemi hodnot, které jsme použili u funkce glClearColor(), můžete využít i pro tuto funkci. Po nastavení barev je čas začít kreslit objekt. Pro tento příklad jsme použili vestavěný geometrický objekt z knihovny GLUT. Existuje několik typů vestavěných tvarů, které můžete použít – od jednoduchých objektů, jako například krychle, válce a kužely, až po pokročilejší objekty jako jsou osmistěny, čtyřstěny či dvanáctistěny. Funkce glutWireTetrahedron() slouží k vytvoření obrysu čtyřstěnu. Objekt je standardně vycentrován na počátek osy. Abychom věci trochu pozměnili, použili jsme funkci glRotate() pro rotaci objektu. Funkce glRotate() má čtyři parametry: glRotate( float angle, float x, float y, float z)

První parametr, angle, určuje úhel rotace objektu ve stupních (zvolili jsme otočení o 30 stupňů). Další tři parametry určují směr od počátku, ke kterému rotace směřuje. Dvojí zavolání funkce glRotate() otočí objekt o 30 stupňů na ose x a poté o 30 stupňů na ose y. To umožňuje dosáhnout výraznějšího trojrozměrného dojmu. Funkce glFlush() je použita k tomu, aby kresba mohla být poslána na monitor uživatele (na konci volání funkce zpětného volání). Jakmile máte vytvořený kód programu testwin.c, zkompilujte ho na vašem systému: $ cc –I/usr/local/include –o testwin testwin.c –L/usr/local/lib –lGL –lglut

Aby bylo možné program spustit, musíte mít na vašem systému otevřenou relaci X Windows. Pokud používáte nějakého správce desktopu (jako například KDE nebo GNOME), můžete pro odstartování programu testwin.c otevřít okno příkazové řádky. Okno programu by se následně mělo objevit na vašem desktopu společně s nakresleným objektem, jak je ukázáno na obrázku 13.3.

Linux profesionálně  

Linux profesionálně

Read more
Read more
Similar to
Popular now
Just for you