Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.
Vaše pomoc je stále potřeba!

Autor Téma: Programování pod Linuxem pro všechny  (Přečteno 4138 krát)

Tygr

  • Návštěvník
  • Příspěvků: 66
Programování pod Linuxem pro všechny
« kdy: 11 Června 2008, 20:02:52 »
Tady sem nasel pro zacatecniky programovani pro zacatecniky ja si to sam prectu  8) 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/


premet

  • Host
Re: Programování pod Linuxem pro všechny
« Odpověď #1 kdy: 11 Června 2008, 20:10:44 »
Takže :
1) Nesprávná kategorie
2) Příště když tak link, když to není váš návod
3) Když už tak kopírovat třeba bez odkazů nebo diskuze  ;D ;)

ADIO45

  • Stálý člen
  • **
  • Příspěvků: 847
  • snažím poradit...nezáleží na karmy ale snahu :)
    • Dráčkovo herní doupě
Re: Programování pod Linuxem pro všechny
« Odpověď #2 kdy: 11 Června 2008, 20:17:33 »
ty jo a vždycky je okraden  ;D
Toshiba L505 - iCore-3, ATI Radeon HD, 4GB ram,500GB  + Win7 s virtual Ubuntu
Neumím psát česky. Jsem sluchově postižení...

Pavel Půlpán

Re: Programování pod Linuxem pro všechny
« Odpověď #3 kdy: 11 Června 2008, 20:22:35 »
A ještě k tomu to není ani upravený tak, aby se v tom dalo vyznat... ::)

No nic, založil jsem novou diskuzi, kam se podobné linky (a prosím jenom linky) mohou umísťovat. Nejvhodnější půjdou přímo do prvního příspěvku, ostatní se budou filtrovat.

Tygr

  • Návštěvník
  • Příspěvků: 66
Re: Programování pod Linuxem pro všechny
« Odpověď #4 kdy: 11 Června 2008, 20:22:55 »
sorry ja sem to sem jen hodil abych nemuseli hledat.  :-\

Pavel Půlpán

Re: Programování pod Linuxem pro všechny
« Odpověď #5 kdy: 11 Června 2008, 20:23:53 »
V pořádku, ale příště opravdu jenom link. ;) Na prasečiny tu mám patent já. :D

Tygr

  • Návštěvník
  • Příspěvků: 66
Re: Programování pod Linuxem pro všechny
« Odpověď #6 kdy: 11 Června 2008, 20:30:42 »
jo ja si to ted ctu  8)

 

Provoz zaštiťuje spolek OpenAlt.