Tady sem nasel pro zacatecniky programovani pro zacatecniky ja si to sam prectu
max je 24 dilu
1 dil
Editace zdrojových souborů
První věcí, kterou bychom se měli naučit, je překládání zdrojových souborů. Než však přeložíme první program, řekneme si něco o editačním programu Emacs. Samozřejmě, že nikoho nenutím, aby používal právě Emacs, ale poklám ho za velice zdařilý program k editaci veškerého textu.
Otevření souboru se zdrojovým kódem
Editor Emacs můžete spustit, jak z terminálového okna příkazem emacs, tak kliknutím na příslušnou nabídku/ikonu v X-Windows. Kliknutím na nabídku File-Open File... se v dolní části zobrazí kurzor a vy můžete napsat cestu k souboru. Pokud máte spuštěn Emacs v terminálu, zpřístupníte nabídku klávesou F10.
Automatické formátování textu a zvýraznění syntaxe
Emacs umožňuje automatické formátování textu, co to znamená? Pokud napíšete nějaký příkaz, "odenterujete" a stisknete TAB, Emacs správně odsadí od kraje. To je velice výhodné, protože kód je přehledný a navíc máte kontrolu, že jste neudělali chybu.
Další věcí, která velice zpřehledňuje kód, je zvýraznění syntaxe. Jde o to, že text bude barevně rozdělen, například klíčová slova mohou být zobrazena jednou barvou, předdefinované typy jinou a komentáře mohou mít opět jinou barvu. Pokud chcete zvýraznění syntaxe zapnout, vytvořte soubor .emacs ve vašem domovském adresáři a zapište do něj:
(global-font-lock-mode t)
Uložte soubor, ukončete editor a znovu jej spusťte. A nyní se můžete kochat barvami.
Překlad zdrojového souboru pomocí GCC
Překladač je program, který překládá zdrojový kód na kód, jemuž počítač "rozumí" a "umí" jej spustit. V Linuxu se nejčastěji používá překladač GCC, který umí překládat zdrojové kódy jazyků C, C++, Java, Objective-C, Fortran... Nyní si předvedeme na ukázkovém programu různé volby překladače.
Hello.c:
#include <stdio.h>
main()
{
printf("Hello world");
}
Myslím, že tento program zná každý :-)
Pro překlad programu zadejte gcc main.c. Pokud jste v programu neudělali žádný překlep, objeví se v adresáři soubor a.out, což je spustitelný program, který můžete libovolně přejmenovat. Jestliže se v průběhu kompilace objevil nějaký výpis, pozorně si jej přečtěte, protože obsahuje důležité informace (nejčastěji chyby, které jste udělali). Že umíte přeložit program, je sice moc hezké, ale kdo by se pořád přepisoval s názvem. Zkuste spustit kompilaci s přepínačem -o a názvem souboru: gcc -o main main.c. A co se nestalo, místo programu a.out je na jeho místě program main.
Co když se však bude program skládat z více souborů(nemyslím soubory .h, ale soubory .c)? V tomto případě nám pomůže přepínač -c. Pomocí něj se nevytvoří spustitelný soubor, ale přemístitelný soubor, tj. soubor, který sice obsahuje část programu, ale není ještě "slinkovaný". Spuštěním příkazu gcc -c main.c vznikne soubor main.o. A pokud bychom měli další část programu také jako přemístitelný soubor, můžeme je spojit příkazem gcc -o main main.o soubor.o.
Při použití hlavičkových souborů GCC prohledává adresáře se systémovými hlavičkovými soubory (většinou /usr/include, /usr/local/include a jiné). Pokud si vytvoříte vlastní hlavičkové soubory, nemusíte je kopírovat do /usr/include, ale stačí uvést přepínač -I při překladu. Volba -I říká překladači, v jakém adresáři má hledat hlavičkové soubory. Např. gcc -I ./include main.c.
V některých případech budete chtít zadat z příkazového řádku makro. Umožní to volba -D. Například budete chtít zapnout ladící volby programu: gcc -c -D DEBUG main.c či gcc -c -D DEBUG=2 main.c.
Až budete překládat finální verzi programu, pravděpodobně budete chtít, aby "běžel" co nejrychleji. Pro tento případ zadejte na příkazový řádek volbu optimalizace -O2 (GCC má několik úrovní optimalizace, viz man gcc): gcc -c -O2 main.c.
Pokud používáte funkce, které nejsou ve standardní knihovně C, budete muset použít volbu -l. Všechny knihovny mají v názvu předponu lib. Pokud je přidáte do svého překladu, nemusíte tuto předponu vpisovat, překladač to udělá za vás. Stejně tak nemusíte psát přípony pro knihovny (.a, .so). Např. gcc -c main.c -lm, přidá do vašeho programu funkce z matematické knihovny. Stejně jako u hlavičkových souborů i u knihoven se prohledávají určité adresáře(/lib a /usr/lib). Pokud má překladač vyhledávat v jiných adresářích, uveďte je za volbou -L. Pokud máte své knihovny v adresáři, odkud spouštíte kompilaci, musíte uvést volbu -L., protože GCC neprohledává aktuální adresář.
Automatický překlad pomocí GNU Make
Budete-li překládat nějaký větší program, pravděpodobně nebudete překládat každý zdrojový soubor do přenositelného kódu a posléze je spojovat a kopírovat do určeného adresáře ručně. Pro tento účel byl vytvořen GNU Make. Základní idea programu Make je jednoduchá, programu je třeba říci, jaký cíl (target) se má sestavit a jaká pravidla (rules) pro jeho sestavení platí. Také je nutné specifikovat tzv. závislosti (dependencies), jež indikují, za jakých podmínek se má konkrétní cíl sestavit.
Pokud budeme mít program o dvou souborech program.c a výpočty.c, budou tři cíle: program.o, výpočty.o a program(.exe;)). Když si uvědomíte, jaké příkazy jste použili ke kompilaci kódu, bude vám jasné, jaká pravidla máte použít. Specifikace závislostí je poněkud komplikovanější, je zřejmé, že program závisí na program.c a výpočty.c. Dále je důležité, že program.o a výpočty.o je nutné vytvořit pokaždé, když se změní příslušný soubor. Zpravidla se také specifikuje cíl zvaný clean, jenž má za úkol odstranit generované přemístitelné kódy a samotné sestavené programy, aby bylo možné sestavovat vše od začátku. Cíle, pravidla a závislosti se definují v souboru Makefile.
Ukázkový soubor Makefile:
program: program.o výpočty.o
gcc $(CFLAGS) -o program program.o výpočty.o
program.o: program.c
gcc $(CFLAGS) -c program.c
výpočty.o: výpočty.c
gcc $(CFLAGS) -c výpočty.c
clean:
rm -f *.o program
Proměnná CFLAGS slouží k dodatečnému předávání parametů překladači, např. make GFLAGS=-g. Nyní můžete zadat v shellu:
# make
a na obrazovce uvidíte tento výstup:
# make
gcc -c program.c
gcc -c výpočty.c
gcc -o program program.o výpočty.o
Pokud nyní změníte nějaký výše uvedený soubor, make bude překládat jen soubory, které přímo závisejí na tomto souboru. Např. pokud změníte soubor výpočty.c, bude výstup make vypadat takto:
# make
gcc -c výpočty.c
gcc -o program program.o výpočty.o
# make clean
rm -f *.o program
Ještě bych chtěl upozornit, že pravidla se musí oddělit od začátku řádku tabulátorem.
V příštím dílu budeme už konečně programovat. Ukážeme s,i jak používat funkci getopt_long, řekneme si něco o systémových a uživatelských proměnných, vytváření dočasných souborů a bezpečném programování.
Ohodnoťte jako ve škole: 1 2 3 4 5
Průměrná známka: 2.00
Top 20
Seriál Programování pod Linuxem pro všechny
* Programování pod Linuxem pro všechny
* Programování pod Linuxem pro všechny (2)
* Programování pod Linuxem pro všechny (3)
* Programování pod Linuxem pro všechny (4)
* Programování pod Linuxem pro všechny (5)
* všechny díly seriálu ...
Jaggni to! Del.icio.us
Tiskni Doporuč
Názory
Sledování názorů
Zasílání upozornění na nové názory je dostupné jen registrovaným uživatelům.
Prosím, přihlaste se a nebo se zaregistrujte.
Přehled názorů
Nastavení kvality: Vlastní Vše 2 3 4 5 6 7 8 9
Pro všechny? Marek Paška 23. 1. 2004 00:12 Nový
├ Re: Pro všechny? Johanka the Editor 23. 1. 2004 00:53 Nový
├ Re: Pro všechny? asdf 23. 1. 2004 08:56 Nový
│├ Re: Pro všechny? Drahos 23. 1. 2004 12:00 Nový
│└ Re: Pro všechny? Drahos 23. 1. 2004 12:04 Nový
│ └ Re: Pro všechny? Petr Tesařík 23. 1. 2004 13:33 Nový
│ └ Re: Pro všechny? Kocovina 27. 1. 2004 16:36 Nový
└ Re: Pro vsechny? pooh 23. 1. 2004 10:20 Nový
odentrovani Maude Lebowski 23. 1. 2004 01:14 Nový
└ Re: odentrovani George007 23. 1. 2004 03:01 Nový
└ Re: odentrovani Culibrk 23. 1. 2004 22:36 Nový
bez editoru joe ani ranu !!! xChaos 23. 1. 2004 05:27 Nový
├ Re: bez editoru joe ani ranu !!! Michal Kara 23. 1. 2004 07:15 Nový
│└ Re: bez editoru joe ani ranu !!! xChaos 12. 2. 2004 02:31 Nový
├ Re: bez editoru joe ani ranu !!! sokrates 23. 1. 2004 08:44 Nový
│└ Re: bez editoru joe ani ranu !!! Mti. 23. 1. 2004 16:45 Nový
│ └ Re: bez editoru joe ani ranu !!! Vít Heřman 23. 1. 2004 19:02 Nový
│ ├ Re: bez editoru joe ani ranu !!! gmmns 23. 1. 2004 20:29 Nový
│ └ Re: bez editoru joe ani ranu !!! kavol 23. 1. 2004 20:39 Nový
├ Re: bez editoru joe ani ranu !!! asdf 23. 1. 2004 08:53 Nový
│├ Re: bez editoru joe ani ranu !!! Tomas Dean 26. 1. 2004 09:09 Nový
│└ Re: bez editoru joe ani ranu !!! Jan Šimůnek 28. 1. 2004 14:50 Nový
│ └ Re: bez editoru joe ani ranu !!! tsunami 27. 2. 2004 20:36 Nový
├ Re: bez editoru joe ani ranu !!! Mormegil 23. 1. 2004 13:37 Nový
│└ Re: bez editoru joe ani ranu !!! xChaos 12. 2. 2004 02:28 Nový
└ Re: bez editoru joe ani ranu !!! anonymní uživatel 24. 1. 2004 00:54 Nový
└ NAS*ANY UZIVATEL tomas 27. 1. 2004 02:18 Nový
preklepy David Brodsky 23. 1. 2004 06:19 Nový
Pro zapšklé magory: Bacil 23. 1. 2004 06:27 Nový
└ Re: Pro zapšklé magory: Pavel 23. 1. 2004 07:38 Nový
programovani v Gnome a spol. Hunterz 23. 1. 2004 07:47 Nový
├ Re: programovani v Gnome a spol. peto 23. 1. 2004 09:15 Nový
│├ Re: programovani v Gnome a spol. Michal Kara 23. 1. 2004 09:40 Nový
││├ Re: programovani v Gnome a spol. peto 23. 1. 2004 13:14 Nový
││└ Re: programovani v Gnome a spol. Vítězslav Novák 30. 4. 2004 15:58 Nový
│└ Re: programovani v Gnome a spol. Matej Zagiba 27. 1. 2004 17:12 Nový
├ Re: programovani v Gnome a spol. Johanka the Editor 23. 1. 2004 10:41 Nový
├ programovani GUI v UNIXu pomoci Tcl/Tk Ludvik Tesar 23. 1. 2004 14:44 Nový
│├ Re: programovani GUI v UNIXu pomoci Tcl/Tk hkmaly 23. 1. 2004 16:41 Nový
│├ Re: programovani GUI v UNIXu pomoci Tcl/Tk Petr Baudis 23. 1. 2004 17:12 Nový
│└ Re: programovani GUI v UNIXu pomoci Tcl/Tk Laszlo 23. 1. 2004 19:11 Nový
├ programovani GUI v UNIXu pomoci Tcl/Tk Ludvik Tesar 23. 1. 2004 15:39 Nový
│└ Re: programovani GUI v UNIXu pomoci Tcl/Tk vrabcak 23. 1. 2004 17:51 Nový
│ ├ Re: programovani GUI v UNIXu pomoci Tcl/Tk Pavel 23. 1. 2004 20:30 Nový
│ │└ Re: programovani GUI v UNIXu pomoci Tcl/Tk Lubos Lunak 24. 1. 2004 11:54 Nový
│ │ └ Re: programovani GUI v UNIXu pomoci Tcl/Tk gmmns 25. 1. 2004 18:34 Nový
│ └ Re: programovani GUI v UNIXu pomoci Tcl/Tk gmmns 23. 1. 2004 20:36 Nový
├ Re: programovani v Gnome a spol. Honza 23. 1. 2004 17:11 Nový
│├ Aky je vlastne stav vyvojoveho prostredia pre GTK? Martin [X] 26. 1. 2004 09:25 Nový
││└ Re: Aky je vlastne stav vyvojoveho prostredia pre mirco 7. 2. 2004 11:45 Nový
│└ Re: programovani v Gnome a spol. Milos 26. 1. 2004 09:53 Nový
└ Re: programovani v Gnome a spol. Grumpa 25. 1. 2004 12:23 Nový
Jeste jeden parametr pro gcc... Karel Zak 23. 1. 2004 08:08 Nový
├ Re: Jeste jeden parametr pro gcc... Yeti 23. 1. 2004 08:58 Nový
│└ Re: Jeste jeden parametr pro gcc... Karel Zak 23. 1. 2004 09:04 Nový
└ Re: Jeste jeden parametr pro gcc... Tomas Janousek 23. 1. 2004 23:13 Nový
Include path muflon 23. 1. 2004 09:17 Nový
├ Re: Include path sd 23. 1. 2004 09:37 Nový
│└ Re: Include path m1c4a1 23. 1. 2004 22:37 Nový
└ Re: Include path Pet 23. 1. 2004 10:19 Nový
└ Re: Include path muflon 23. 1. 2004 11:30 Nový
├ Re: Include path Pet 23. 1. 2004 14:10 Nový
└ Re: Include path Emil Jerabek 23. 1. 2004 14:26 Nový
programovani neologism 23. 1. 2004 09:32 Nový
├ Re: programovani sd 23. 1. 2004 09:52 Nový
└ Re: programovani Petr Baudis 23. 1. 2004 17:27 Nový
thanks Shamot 23. 1. 2004 09:32 Nový
├ Re: thanks karelklic 23. 1. 2004 10:11 Nový
│├ Re: thanks Jerry III 23. 1. 2004 11:06 Nový
│├ Re: thanks Pet 23. 1. 2004 11:16 Nový
││└ Re: thanks Papa 23. 1. 2004 19:06 Nový
│├ Re: thanks covex 23. 1. 2004 15:08 Nový
│├ Re: thanks blami 23. 1. 2004 15:41 Nový
││└ Re: thanks vrabcak 23. 1. 2004 17:58 Nový
││ └ Souhlasi Jan 24. 1. 2004 14:14 Nový
││ └ Re: Souhlasi gmmns 25. 1. 2004 18:40 Nový
│├ Re: thanks venca 23. 1. 2004 22:34 Nový
│└ cmake zen master 27. 1. 2004 12:52 Nový
│ └ Re:thanks galaxi 30. 1. 2004 19:26 Nový
└ Re: thanks galaxi 23. 1. 2004 19:51 Nový
├ Re: thanks Pavel 23. 1. 2004 20:41 Nový
│├ Re: thanks Krata 23. 1. 2004 23:04 Nový
│└ Re: thanks Josef Pavlik 23. 1. 2004 23:54 Nový
│ └ Re: thanks Lubos Lunak 24. 1. 2004 11:45 Nový
└ Re: thanks Tomas Janousek 23. 1. 2004 23:31 Nový
Emacs a makefile Pet 23. 1. 2004 10:06 Nový
├ Re: Emacs a makefile Glin 23. 1. 2004 11:25 Nový
├ Re: Emacs a makefile Petr Tesařík 23. 1. 2004 13:41 Nový
└ VIM a makefile Petr Baudis 23. 1. 2004 17:45 Nový
Ja bych to naflagal do KDevelop,prelozil,sl inkoval Pavel P 23. 1. 2004 11:37 Nový
└ Re: Ale stejne sem si to vytiskl a jdu to zkusit Pavel P 23. 1. 2004 11:42 Nový
make, vice libs z jednoho source jenda 23. 1. 2004 12:40 Nový
└ Re: make, vice libs z jednoho source hkmaly 23. 1. 2004 16:44 Nový
emacs s_d 23. 1. 2004 17:22 Nový
hezky clanek
mt 24. 1. 2004 14:03 Nový
nepresnost? Grumpa 25. 1. 2004 12:21 Nový
k programovani pod X Johanka the Editor 26. 1. 2004 17:58 Nový
GUI programovanie zen master 27. 1. 2004 19:34 Nový
gcc a java Jan Šimůnek 28. 1. 2004 15:05 Nový
└ Re: gcc a java zen master 29. 1. 2004 15:05 Nový
pomoc lamerom uplne suchy zemiak 29. 1. 2004 02:34 Nový
├ Re: pomoc lamerom Jan Šimůnek 29. 1. 2004 10:36 Nový
└ Re: pomoc lamerom zen master 29. 1. 2004 11:51 Nový
└ Re: pomoc lamerom uplne suchy zemiak 29. 1. 2004 22:17 Nový
└ Re: pomoc lamerom me 8. 2. 2004 09:28 Nový
FreeBSD Aplt 2. 2. 2004 14:42 Nový
└ Re: FreeBSD ToM 5. 2. 2004 10:16 Nový
└ Re: FreeBSD xChaos 12. 2. 2004 02:41 Nový
$PATH Jiří Novák 20. 12. 2005 14:33 Nový
Prosim poradte!! Cagik 11. 8. 2007 14:01 Nový
└ Re: Prosim poradte!! Jan Cagan 12. 8. 2007 10:06 Nový
Zobrazit kvalitníZobrazit všePřidat
Další informace
Vyhledávání
Rozšířené
Reklama
Reklama
Průvodce finančními produkty
Potřebujete životní pojištění, spořící účet nebo hypoteční úvěr? Nevyznáte se v platebních kartách ani v investičních produktech?
Nová služba serveru Měšec.cz vám poradí, jak a kde sjednat optimální finanční produkt přímo vám na míru.
Reklama
May Consulting zaměstnání »
May Consulting
* DMS KONZULTANT (i3533) / VELMI ZAJÍMAVÁ NABÍDKA / PRAHA
* VÝVOJÁŘ .NET (i10743) / ZAJÍMAVÁ NABÍDKA / PRAHA
* IT ADMINISTRÁTOR (i11057) / ŠANCE I PRO ABSOLVENTY / KOLÍNSKO
* PROGRAMÁTOR/ ANALYTIK JAVA/J2EE (i5683) / MEZINÁRODNÍ SPOL. / P
* INTEGRATION ARCHITECT (i10910) / NADNÁR. SPOL. / PRAHA
* JUNIOR SAP SPECIALISTA (i8333) / MEZINÁRODNÍ PROJEKTY / BRNO
* JAVA / C# DEVELOPER PRO MEZINÁRODNÍ PROJEKTY (i8291) / BRNO / 25 - 40.000,-
* DATAWARHOUSE SPECIALISTA (i8148) / MEZINÁRODNÍ PROJEKTY / BRNO
Reklama
Nenechte se omezovat s UPC Internet
Objednejte nyní vysokorychlostní internet a máte 6 měsíců s 50% slevou! Žádné limity dat, žádné další poplatky za telefon! Modem zapůjčíme zdarma a profesionální instalaci provedeme za 1 Kč!
Více informací zde.
Reklama
Reklama
Reklama
Reklama
Další články v rubrice Linux
1. Prostředí KDE a jeho aplikace
2. Kdo ještě používá jádro z řady 2.4?
3. Poskytovatel internetu si pochvaluje Linux: je levný a stabilní
4. Co je to desktopové prostředí?
5. Instalace linuxové distribuce (teoreticky)
Další články v sekci Vývoj
1. Perličky: prototypy
2. GIT: naše první vydání
3. Perličky: symbolické reference, typegloby
4. GIT: config, commit, e-mail a browsing
5. Ostrava má potenciál a nové vývojářské centrum
Vyzkoušejte na Root.cz
* Uživatelský profil
* Diskusní fóra
* Rubriky, Nálepky, Seriály
* Slovníček pojmů
* Tutoriály, Knihy
* Píšou jinde, Kalendář akcí
* Hlídač
* Novinky e-mailem (Newsletter)
* Butik – trička, mikiny, tanga
* Postranní lišta do Mozilly
* Reklama na Root.cz
2 dil
getopt_long()
Jak už jste si určitě někdy všimli, většině programů se při jejich spouštění předávají parametry. Někdy to je jen písmeno uvedené pomlčkou (-), ale někdy to jsou dvě pomlčky (--) následované slovem či více slovy. Tyto parametry mění chod programu. Pro obsluhu parametrů se používá funkce getopt_long. Při použití této funkce musíte do svého kódu vložit hlavičkový soubor getopt.h.
Při použití funkce getopt_long musíte definovat dvě speciální datové struktury. První je znakový řetězec obsahující krátké volby. Píší se bez pomlčky a ty, za nimiž bude náslodovat další argument, jsou následovány dvojtečkou. Pokud chcete používat dlouhé volby, musíte sestavit pole, které bude obsahovat struktury struct option. Každá tato struktura představuje jednu volbu a obsahuje čtyři položky. První položkou je jméno volby (znakový řetězec uzavřený do uvozovek); druhá obsahuje 1, pokud má za volbou následovat další argument, nebo 0. Třetí položkou je konstanta NULL a čtvrtou je odpovídající krátká volba. Posledními elementy by měly být nuly. Menší příklad pro názornost:
/* retezec obsahujici kratke volby */
const char *kratke_volby = "ho:i:";
/* pole s dlouhymi volbami */
const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "output", 1, NULL, 'o' },
{ "input" 1, NULL, 'i' },
{ NULL, 0, NULL, 0 }
};
Při volání funkce getopt_long je nutné předat jako parametry proměnné argc, argv, řetězec s krátkými volbami a pole s dlouhými volbami. Funkce pracuje následovně:
* Po každém volání provádí syntaktickou analýzu volby a vrátí jednoznakové písmeno pro volbu, nebo -1, pokud další volby nebyly nalezeny.
* Běžně se funkce volá v cyklu, a tak se postupně zpracují všechny volby předané z shellu. Každá konkrétní volba se pak zpracuje v příkazu switch.
* Pokud funkce getopt_long zjistí zadání neplatné volby, zobrazí chybové hlášení a vrátí znak ?. Většina programů na to reaguje ukončením a vypsáním zprávy o zadání neplatné volby.
* Pokud za volbami následuje další argument, vrátí se globální proměnná optarg ukazující na textový řetězec.
* Po ukončení syntaktické analýzy vrátí funkce getopt_long v globální proměnné optind index (do pole argv) prvního argumentu, který není volbou.
Všechny výše napsané informace si předvedeme na příkladu:
#include <getopt.h> #include <stdio.h> #include <stdlib.h> /* Jmeno programu. */ const char *program_name; /* Tato funkce vypise napovedu do vystupniho * proudu STREAM(stderr, stdout) a ukonci se * s kodem EXIT_CODE. */ void print_help(FILE *stream, int exit_code) { fprintf(stream, "Usage: %s options\n", program_name); fprintf(stream, " -h --help Display this help screen.\n" " -o --output file Write output to file.\n" " -i --input file Read input from file.\n"); exit(exit_code); } /* Funkci main zacina program. */ int main(int argc, char *argv[]) { int next_option; /* Retezec obsahujici kratke volby */ const char *short_options = "ho:i:"; /* Pole struktur s dlouhymi volbami */ const struct option long_options[] = { { "help", 0, NULL, 'h' }, { "output", 1, NULL, 'o' }, { "input", 1, NULL, 'i' }, { NULL, 0, NULL, 0 } }; /* Jmeno souboru pro vystup nebo NULL pro stdout */ const char *output_file = NULL; /* Jmeno souboru pro vstup nebo NULL pro stdin */ const char *input_file = NULL; /* Jmeno programu je ulozeno v promene argv[0]. */ program_name = argv[0]; do { next_option = getopt_long(argc, argv, short_options, long_options, NULL); switch(next_option) { case 'h': /* -h nebo --help */ print_help(stdout, 0); case 'o': /* -o nebo --output */ output_file = optarg; break; case 'i': /* -i nebo --input */ input_file = optarg; break; case '?': /* Uzivatel specifikoval neznamou volbu */ print_help(stderr, 1); case -1 : /* Konec */ break; default: abort(); } } while(next_option != -1); /* Volby byly zpracovany. Promena OPTIND ukazuje * na prvni argument, ktery neni volbou. */ ... ... ... return(0); /* Ukonceni programu s kodem 0 */ }
To by bylo vše k funkci getopt_long. Někomu by se mohlo zdát ze je její použití příliž pracné. Ale pokud byste si vytvořili vlastní funkci, stálo by vás to mnohem více úsilí.
Systémové proměnné
Každý program běžící v Linuxu ma přiřazeno jisté prostředí (enviroment). Prostředí je množina dvojic [systémová proměnná, hodnota]. Systémové proměnné jsou znakové řetězce a jejich jména se píší velkými písmeny. Je vysoce pravděpodobné, že jste se už setkali s proměnnými USER, HOME, PATH, DISPLAY. Proměnné můžete vytvářet v shellu zápisem PROMENNA=hodnota, poté je nutné je exportovat z shellu do prostředí příkazem export PROMENNA. Zjistit hodnotu proměnné můžete příkazem echo $PROMENNA. A konečně, chcete-li vypsat prostředí shellu, zadejte příkaz printenv.
V programu lze systémové proměnné zpřístupňovat pomocí funkce getenv, která je popsána v stdlib.h. Tato funkce má jediný argument, a to jméno proměnné, jejíž hodnotu chcete zjistit. Pokud není systémová proměnná definována, vrací funkce NULL, jinak vrací textový řetězec, který obsahuje hodnotu proměnné. Jestliže budete chtít nastavit nebo zrušit systémovou proměnnou, použijte funkci setenv resp. unsetenv. Menší příklad použití systémových proměnných:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *conf_file = getenv("CONFIG_FILE");
if(conf_file == NULL)
/* Promenna CONFIG_FILE nebyla definovana,
* pouzije se defaultni configuracni soubor
*/
conf_file = "/etc/config";
...
...
...
return(0);
}
To by bylo pro dnešek vše, slíbené vytváření dočasných souborů si necháme na příště. A navíc si povíme něco o statických a dynamických knihovnách.
3 dil:
V minulém dílu jsem pasáž o systémových proměnných napsal trochu stroze. Úplným začátečníkům se omlouvám. Napíšu zde ještě pár doplňujících informací.
Proměnné se dědí z procesu na proces, tzn. rodičovský proces předá spouštěnému procesu všechny své proměnné. Všechny proměnné, které jsou součástí prostředí (environment) procesu si můžete prohlédnout v souboru /proc/cislo-procesu/environ. Přidávat proměnné do prostředí (bashe nebo vašeho programu) můžete pomocí metod napsaných v minulém dílu. Proč musíte proměnnou předávanou z bashe exportovat? Bash funguje také jako programovací jazyk (snad všechny systémové skripty jsou napsány v něm). Jak určitě víte, programovací jazyky používají proměnné k uchovávání hodnot a bylo by krajně nepraktické ukládat proměnné do prostředí bashe, dokonce by mohly vznikat kolapsy se spouštěnými programy. Proto se proměnné ukládají interně v bashi, a pokud je chcete použít v prostředí, musíte je exportovat.
Vytváření dočasných souborů
Občas je potřeba zapsat data do dočasného (temporary) souboru, přečíst je nebo pomocí tohoto souboru předat data jinému procesu. V Linuxu se dočasné soubory ukládají v adresáři /tmp. Měli byste si však dát při používání dočasných souborů pozor na několik záludností:
* V první řadě mějte na paměti, že na počítači může běžet v jeden moment několik instancí vašeho programu. Pokud budete používat neměnný název dočasného souboru, všechny instance tohoto programu budou zapisovat jen do jednoho souboru. A může se stát, že budou číst data, která nejsou jejich. Každá instance by měla používat jiný název dočasného souboru.
* Práva souboru by měla být nastavena tak, aby případný útočník nemohl měnit jeho obsah a tím i chod celého programu.
* Jméno dočasného souboru by mělo být generováno tak, aby nemohlo být externě předpovězeno. Jinak by mohl útočník využít prodlevy mezi testem, zda se již dané jméno používá, a mezi otevřením nového dočasného souboru.
Tyto problémy vám pomohou řešit dvě funkce: 1) Funkce mkstemp(), která je definována v hlavičkovém souboru stdlib.h. Tato funkce využívá deskriptor souboru pro práci se souborem. 2) Funkce tmpfile() je obsažena v hlavičkovém souboru stdio.h a využívá pro práci se soubory ukazatel typu FILE. Ve stejném hlavičkovém souboru jsou také definovány funkce jako mktemp(), tempnam() nebo tmpnam(). Tyto funkce slouží také k práci s dočasnými soubory, ale v tomto článku se jimi zabývat nebudu. Zájemce mohu odkázat na manuálové stránky jmenovaných funkcí. Nyní si povíme něco o funkcích mkstemp() a tmpfile().
Funkce mkstemp()
Funkce mkstemp() vytváří dočasný soubor s jedinečným jménem. Toto jméno se generuje pomocí šablony. Funkci se předává jako parametr znakový řetězec obsahující jméno souboru s šablonou. Šablona je "XXXXXX" a funkce tato X nahradí jinými znaky, aby se vytvořilo jedinečné jméno. Funkce otevře nový soubor s právy číst a zapisovat do souboru pro vlastníka procesu.
Pokud nebudete chtít pomocí dočasného souboru předávat data jinému procesu, pravděpodobně budete chtít soubor zrušit, až nebude potřeba. Soubory vytvořené funkcí mkstemp() se neruší automaticky. Proto použijte po zavolání mkstemp() funkci unlink(), která zruší jméno souboru v souborovém systému. Se souborem bude možné nadále pracovat a po uzavření deskriptoru souboru se odstraní. Snad bych ještě měl upozornit na to, že k zápisu a čtení dat pomocí deskriptoru souboru se používají funkce write() a read(), pokud nevíte, jak se funkce používají, prohlédněte si manuálové stránky, případně se poohlédněte po nějakém článku na Internetu.
V příkladu jsou použity funkce demonstrující použití mkstemp(). První funkce slouží k vytvoření a zápisu dat do dočasného souboru. Vrací deskriptor souboru pro případný další zápis dat a čtení pomocí druhé funkce.
#include <stdlib.h> #include <unistd.h> /* Novy datovy typ file_decriptor pro deskriptor souboru */ typedef int file_descriptor; /* Funkce zapise LENGTH bytu z BUFFER do docasneho souboru. * Pote je jmeno souboru zruseno v filesystemu(unlink). * Vraci deskriptor souboru. */ file_descriptor write_tmp(char *buffer, size_t length) { /* Vytvori nazev souboru a samotny soubor. XXXXXX bude * prepsano nejakymi znaky, aby bylo jmeno unikatni. */ char temp_filename[] = "/tmp/temp_file.XXXXXX"; int fd = mkstemp(temp_filename); /* Zrusi jmeno souboru v filesystemu, az se * uzavre deskriptor souboru soubor se smaze. */ unlink(temp_filename); /* Zapise velikost zapisovanych dat v bytech. */ write(fd, &length, sizeof(length)); /* Nyni zapise samotna data. */ write(fd, buffer, length); /* Vrati deskriptor souboru docasneho souboru */ return(fd); } /* Precte data z docasneho souboru, jehoz deskriptor * souboru je ji predan jako 1. parametr(TEMP_FILE). * Vraci nove alokovany buffer s prectenymi daty, po * pouziti musi byt manualne dealokovany pomoci free(). * Pomoci *LENGTH se vraci velikost bufferu v bytech. * Funkce nakonec uzavre deskriptor souboru a tim se * pri ukonceni souboru odstrani docasny soubor. */ char *read_tmp(file_descriptor temp_file, size_t *length) { char *buffer; /* Vrati se na zacatek souboru. */ lseek(temp_file, 0, SEEK_SET); /* Precte velikost zapsanych dat v souboru. */ read(temp_file, length, sizeof(*length)); /* Alokuje pamet pro buffer a cte data. */ buffer = (char *) malloc (*length); read(temp_file, buffer, *length); /* Zavre deskriptor souboru */ close(temp_file); return(buffer); }
Funkce tmpfile()
Pokud budete chtít použít k zápisu a čtení dat knihovní funkce fwrite() a fread(), můžete použít funkci tmpfile(). Funkce vygeneruje unikátní jméno a použije cestu uloženou v symbolické konstantě P_tmpdir definované v stdio.h. Soubor je otevřen v binárním módu pro čtení i zápis (w+b). Dočasný soubor je již odpojen, jako v předcházejícím příkladě, proto je automaticky odstraněn, jakmile se soubor uzavře, nebo po skončení programu. Následující příklad je pouze přepsaným příkladem funkce mkstemp():
#include <stdio.h>
FILE *write_tmp(char *buffer, size_t length)
{
/* Vytvori ukazatel pro praci se souborem */
FILE *temp_file;
/* Vytvori novy docasny soubor */
temp_file = tmpfile();
fwrite(&length, sizeof(length), 1, temp_file);
fwrite(buffer, length, 1, temp_file);
return(temp_file);
}
char *read_tmp(FILE *temp_file, size_t *length)
{
char *buffer;
fseek(temp_file, 0, SEEK_SET);
fread(length, sizeof(*length), 1, temp_file);
buffer = (char *) malloc(*length);
fread(buffer, *length, 1, temp_file);
fclose(temp_file);
return(buffer);
}
Tak to by bylo pro dnešní díl vše, doufám, že si nových znalostí užijete. Příště se podíváme na knihovny. Nejdříve probereme statické knihovny, a jestli zbyde nějaké místo, nakousneme knihovny dynamické.
4 dil :
Název knihovny je v podstatě oprávněný, protože knihovny "počítačové" se chovají jako knihovny "knižní". Představte si část programového kódu (např. funkci) jako knihu, kterou máte založenou v knihovně podle určitého systému. Pokud potřebujete použít tuto knihu, jednoduše přijdete, sáhnete přesně tam, kam máte, a knihu použijete.
Knihovny umožňují programátorům efektivněji pracovat. Programátor nemusí vymýšlet nové algoritmy, pokud jej již někdo předešel a svůj algoritmus uložil do knihovny. Tímto systémem je také zajištěna přenositelnost programů. Programátor nemusí znát do podrobností architekturu počítače, pro který je program psán, stačí, pokud zná příslušné knihovny. Samotný jazyk C je navržen tak, že maximálně využívá výhod knihoven.
Knihovny jsou statické a dynamické (sdílené); jak samotný název napovídá statické knihovny jsou určeny k "pevnému" připojení ke kódu a dynamické se zavádějí, jen když je jich potřeba. Všechny knihovny v systému Linux mají předponu lib a některou ze dvou přípon, podle typu knihovny.
Statické knihovny
Statické knihovny jsou vlastně jednoduchou kolekcí přemístitelného kódu uloženého v jediném souboru, proto se někdy též nazývají archivy. Když spojovacímu programu specifikujete nějakou statickou knihovnu, bude v ní program vyhledávat kódy funkcí, jež používáte ve svém programu. Vyhledanou funkci extrahuje a spojí ji s vaším programem stejně, jako byste přemístitelný kód specifikovali spojovacímu programu odděleně.
Pro vytvoření statické knihovny můžete použít program ar. Statické knihovny používají příponu .a. Následující příklad vytváří ze souborů test1.o a test2.o knihovnu libtest.a.
# ar cr libtest.a test1.o test2.o
Menší přehled voleb programu ar:
* c ... vytvoří nový archiv
* r ... vloží soubory do archivu
* d ... maže moduly podle jejich jména
* t ... vypíše tabulku modulů, ze kterých byl archiv vytvořen
* p ... vypíše specifikované položky archivu na standardní výstup
Při spojování programů s knihovnami se používá program ld. Jeho použítí má však jednu záludnost. Když program identifikuje v příkazovém řádku statickou knihovnu, vyhledá v ní všechny definice a symboly, na které našel odkazy v doposud zpracovaném přemístitelném kódu a které nemá doposud definovány. Přemístitelné kódy definující tyto symboly vyjme ze statické knihovny a spojí je s výsledným spustitelným kódem. Je tedy důležité specifikovat v příkazovém řádku statické knihovny jako poslední, jinak se překlad nezdaří.
Dynamické/sdílené knihovny
Dynamické knihovny jsou podobné knihovnám statickým v tom smyslu, že obsahují kolekci přemístitelných kódů. Ale program používající dynamickou knihovnu vlastně vůbec neobsahuje její kód. Obsahuje jen odkaz na tento kód v dynamické knihovně. A je celkem samozřejmé, že dynamické knihovny může naráz využívat několik současně běžících programů (odtud termín sdílená knihovna).
Další důležitou informací je, že dynamická knihovna není pouhou kolekcí přemístitelných kódů, z nichž si spojovací program vybírá odkazy na nedefinované symboly. V dynamické knihovně jsou přemístitelné kódy spojeny do jediného celku a program tak má v době své realizace k dispozici všechen kód obsažený v knihovně.
Chceteli vytvořit dynamickou knihovnu, musíte nejdříve její moduly přeložit speciálním způsobem - s použižím volby -fPIC:
# gcc -c -fPIC test1.c
Zkratka PIC označuje Position-Independent Code(kód nezávislý na pozici). Co to znamená? Funkce ve sdílené knihovně mohou být zavedeny do paměti na různých pozicích. Proto kód těchto funkcí nesmí záviset na pozici v paměti.
Po překladu lze přemístitelné kódy spojit do jediného souboru, tedy do dynamické knihovny:
# gcc -shared -fPIC -o libtest.so test1.o test2.o
Volba -shared sděluje programu ld, že má vytvořit sdílenou knihovnu a nikoliv spustitelný kód. Sdílené knihovny mají příponu .so (shared object).
Spojování kódu s dynamickými knihovnami je stejné jako spojování se statickými knihovnami:
# gcc -o egg -egg.o -L. -ltest
Předpokládejme nyní, že existují dynamická knihovna libtest.so i statická knihovna libtest.a. Spojovací program bude prohledávat adresáře (nejdříve ten, který je uveden za volbou -L, pak systémové), dokud nenajde adresář obsahující libtest.a nebo libtest.so, pak prohledávání ukončí. Pokud se v daném adresáři nachází pouze první z uvedených knihoven, spojovací program si ji vybere. Jinak si vybere druhou knihovnu, je-li přítomna. Abyste se vyhnuli těmto nejasnostem s vybíráním knihoven, můžete zvolit při překladu volbu -static. Při zapnutí této volby bude použita jen statická knihovna, i když je v adresáři přítomna dynamická.
# gcc -static -o egg egg.o -L. -ltest
Pomocí příkazu ldd si můžete vypsat seznam všech sdílených knihoven, které jsou spojeny s daným spustitelným programem. V seznamu dynamických knihoven se vždy zobrazí knihovna ld-linux.so, která je standardní součástí spojovacího mechanismu v systému GNU/Linux.
To by bylo pro dnešek vše. V příštím dílu dokončím pasáž o knihovnách vysvětlením použití proměnné LD_LIBRARY_PATH a zavádění dynamických knihoven za běhu programu. A pokud zbude nějaké místo, začnu s úvodem do práce s procesy.
5 dil ;
V diskusi k minulému dílu jste se zmiňovali, že byste chtěli nějaké informace o libtool, rozhodl jsem se tedy tomuto nástroji věnovat příští díl (nebo několik dílů).
Nestandardní knihovní adresáře
Když spojíte váš program s dynamickou knihovnou, vloží spojovací program do spustitelného kódu pouze její jméno. Když se program spustí, jsou sdílené knihovny zaváděny z adresářů /lib a /usr/lib. Pokud není daná knihovna v některém z adresářů, systém odmítne spustit program.
Budete-li chtít použít nestandardní adresáře, máte na výběr ze dvou řešení. Prvním z nich je, že při spojování programu použijete volby -Wl, -rpath
# gcc -o egg egg.c -L. -ltest -Wl, -rpath, /usr/local/lib
Volba -Wl ,option slouží k předání dodatečných argumentů linkovacímu programu. Nyní spustitelný kód obsahuje i adresář, kde má hledat sdílenou knihovnu.
Pokud ovšem nemůžete program znovu přeložit (např. je distribuován v binární formě), můžete použít systémovou proměnnou LD_LIBRARY_PATH. Podobně jako proměnná PATH obsahuje seznam adresářů oddělených dvojtečkou. Pokud si například do proměnné uložíte /usr/local/lib, bude se tento adresář prohledávat před adresáři /lib a /usr/lib. Dále je důležité vědět, že se při dalším spojování programů budou prohledávat také adresáře uvedené v proměnné.
Zavádění dynamických knihoven
Někdy je nutné zavést jistý kód do paměti až v době realizace programu. Příkladem může být třeba webový prohlížeč. Do většiny prohlížečů je možné zavádět moduly, čímž rozšiřujete funkce programu.
Pro zavádění dynamických knihoven do paměti je možné použít funkci dlopen(), funkční prototyp funkce je
void *dlopen (const char *filename, int flag);
Drhuhý parametr je přepínač, který nastavuje způsob vazby symbolů ve sdílené knihovně. Nejčastěji se používá volba RTLD_LAZY (další volby viz # man 3 dlopen). Návratový kód se používá jako odkaz na sdílenou knihovnu. Hodnotu návratového kódu můžete předat funkci dlsym(), a obdržíte tak adresu funkce, jež byla zavedena spolu s dynamickou knihovnou. Funkční prototyp funkce je
void *dlsym(void *handle, char *symbol);
handle je zmíněný odkaz na knihovnu, symbol je název funkce, jejíž adresu chcete předat jako návratový kód. Funkce dlsym může být použita také k získání ukazatele na statickou proměnnou ve sdílené knihovně.
Obě funkce vracejí hodnotu NULL, pokud se ukončí s chybou. V takovém případě můžete volat funkci dlerror() (bez parametrů), a získat tak textový popis příčiny.
int dlclose (void *handle);
Tato funkce se používá k uvolnění knihovny z paměti.
Pokud chcete využívat uvedených funkcí, musíte vložit do vašeho zdrojového souboru odkaz na hlavičkový soubor dlfcn.h a přeložit program s volbou -ldl. Uvedu zde příklad z manuálových stránek. Program vypočítá cosinus dvou funkcí cos() z dynamicky zavedené knihovny libm.so:
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("/lib/libm.so", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}
To je dnes vše, doufám, že se vám nově získané informace budou hodit. A jak jsem se na začátku článku zmínil, příští díl se budeme věnovat libtool.
To snad zatim bude stacit.
Tady mate stranku dal
http://www.root.cz/serialy/programovani-pod-linuxem-pro-vsechny/