KDevelop (4) - linkujeme shared library

KDevelop (4) - linkujeme shared library
30.04.2008 23:00 | Články | Timotej Šiškovič
Dneska trocha odbočíme a naučíme sa ako správne prilinkovať k nášmu projektu takzvanú shared library. (Rozhodol som sa tak v následku ohlasov od čitateľov)

Čo je to „shared library“?

Na úvod si "shared library" trocha predstavíme.(pôjde len o zjednodušený popis) Shared library, alebo zdieľaná knižnica je niečo podobné, ako dobre známe windowsácke dll(dynamicky prilinkovateľná knižnica). Prestavte si napríklad, že Váš program potrebuje prehrávať MP3 súbor. Bolo by veľmi neefektívne(časovo i priestorovo) a náchylné na chyby, keby každý program, ktorý chce mp3ky prehrať musel mať svoj vlastný algoritmus na ich dekódovanie a manipuláciu s nimi. Tento problém sa dá vyriešiť omnoho elegantnejšie a to tak, že funkcie na prácu z mp3 súbormi uložíme do externého súboru=knižnice, ktorú potom môže použiť ľubovoľný program. Toto má viacero výhod (a zďaľeka nevypíšem všetky):

  • Šetríme miestom na disku
  • Šetríme pamäťou (systém môže zabezpečiť, aby bola knižnica načítaná v pamäti iba raz, napriek tomu, že ju používa viacero programov)
  • Ak vyjde nová verzia knižnice s kompatibilným API (rozhraním), napríklad opravujúca bugy, stačí aktualizovať samotnú knižnicu a všetky programy automaticky použijú novú opravenú verziu. (t.j. netreba aktualizovať všetky programy)
  • Pomocou zdieľaných knižníc môžeme dynamicky rozširovať funkčnosť programu za behu (áno zdieľané knižnice sa dajú načítať aj zavrieť za behu)
  • Tisíce takýchto knižníc určených na rôzny účel je už dávno na svete a čakajú len na to, kedy ich objavíte
  • Progamovanie GUI je v 90% prípadov riešené tiež cez zdieľané knižnice (Gtk, Qt)

Ako začať

Vytvoríme si „Hello world“ C++ projekt a ukážkovou knižnicou ktorú budeme linkovať je dobre známa SDL (používaná na vývoj multiplatformových hier). Z toho dôvodu treba samozrejme knižnicu SDL nainštalovať a takisto budete potrebovať balík SDL-devel (balík z hlavičkovými súbormi, v iných distribúciach sa môže volať inak!!!). Naša ukážková aplikácia „zneužije“ knižnicu SDL na zobrazenie obrázka na monitor a po 2,5 sekundách sa sama ukončí.

Upravujeme zdroják. Pokus č.1

Na začiatok hlavného zdrojového súboru (ten v ktorom sa nachádza funkcia main), tesne za všetky direktívy #include vložíme:

SDL_Surface *screen;
Skúsime projekt skompilovať. Samozrejme, že kompilátor vyhlási na pridanom riadku chybu. Typ SDL_Surface predsa nieje nikde deklarovaný.

Upravujeme zdroják. Pokus č.2

Do nášho Hello World projektu pridáme hlavičkový súbor SDL.h

#include <SDL/SDL.h>
Skúsime projekt skompilovať. Ak kompilátor vyhlásil chybu, že nenašiel SDL.h, pravdepodobne nemáte správne nainštalované SDL vývojové prostredie (SDL-devel). Ak máme vývojové prostredie nainštalované správne, náš projekt by sa mal skompilovať.

Upravujeme zdroják. Pokus č.3

Problém nastane, keď do funkcie main pridáme nejakú funkciu zo SDL.h. Riadok:

cout << "Hello, world!" << endl;
nahradíme riadkom:
SDL_Init(SDL_INIT_VIDEO);
a skúsime program skompilovať. Narazíme na chybu (tentoraz nám ju vypíše linker, nie kompilátor):
undefined reference to `SDL_Init'
Kde je problém? Zahrnutím SDL/SDL.h sme funkciu SDL_Init len deklarovali, t.j. v SDL.h nieje samotná implementácia tejto funkcie. Kompilátor teda vie: „Existuje funkcia SDL_Init ktorá ma takéto parametre a takúto návratovú hodnotu.“ a preto súbor skompilujte. Nevie ale, kde samotnú funkciu (jej kód) SDL_Init nájsť. Poskytnúť implementáciu tejto funkcie, keďže sa nenachádza v tom istom súbore ako náš kód, je úlohou linkera. Linker jednoducho (teda vlastne zložito ;-) ) hľadá implementácie použitých funkcií vo všetkých vstupných súboroch a potom vytvorí hotový „zlinkovaný“ výstupný súbor. Takto môžeme zlinkovať viacero objektových súborov, statických knižníc a v neposlednom rade knižníc zdieľaných/dynamických. Rozdiel je pri zdieľaných knižniciach v tom, že knižnica nieje priamo pripojená do výstupného súboru, ale linkovanie prebehne automaticky až pri spustení programu. Pri zdieľaných knižniciach potrebujeme linkéru povedať, v ktorej knižnici má implementácie hľadať a teda ktoré knižnice má program pri svojom spustení načítať.

Let's go

V Kdevelope sa knižnice pridávajú jednoducho. Otvoríme správcu automake na pravom sidepaneli, označíme aktuálny projekt(v spodnej časti) a klikneme na ikonku kľúča v spodnej časti. Potom vyberieme kartu libraries , kde do sekcie „Link libraries outside project“ pridajte „-lSDL“

Po potvrdení zmien by sa nám mal projekt úspešne skompilovať. Ostatné knižnice používame rovnakým spôsobom.

Konvencie pomenovania knižníc

Knižnice majú obvykle vlastné meno (napr. v našom príklade to bolo SDL), meno súboru knižnice je potom urobené podľa takejto schémy libSDL-1.2.so. Pri linkovaní sa však použije len -lSDL, pričom linkér sám zistí verziu, ktorú použije (ak sa pozriete napríklad do adresára /lib, zistíte že veľkú časť práce pri tom zohrávajú symlinky), pričom prefix „lib“ sa tiež neuvádza.

Podľa tejto schémy je možné ľahko odhadnúť, ako prilinkovať ktorúkoľvek knižnicu. Ak sa pomenovanie knižnice odlišuje od zaužívaného, zostáva len obrátiť sa na dokumentáciu, prípadne vyhľadať súbor na disku.

Tak trochu natiahnutý záver

Preto, aby ste mali lepší dojem z práce a motiváciu, napíšem ešte ukážkovú SDL aplikáciu sľúbenú v úvode. Na jej použitie stačí mať prilinkovanú knižnicu SDL.

Kód vo funkcii main nahradíme týmto:

/* Initialize the SDL library */
  if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr,
      "Couldn't initialize SDL: %s\n", SDL_GetError());
    exit(1);
  }

  /* Clean up on exit */
  atexit(SDL_Quit);
    
  /*
   * Initialize the display in a 640x480 32-bit mode,
   * requesting a software surface
   */
  screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
  if ( screen == NULL ) {
    fprintf(stderr, "Couldn't set 640x480x32 video mode: %s\n",
              SDL_GetError());
    exit(1);
  }

  char fname[]="wallpaper.bmp";
  display_bmp(fname);

  SDL_Delay(2500);
  return EXIT_SUCCESS;

A nad funkciu main pridáme túto funkciu:

void display_bmp(char *file_name)
{
    SDL_Surface *image;

    /* Load the BMP file into a surface */
    image = SDL_LoadBMP(file_name);
    if (image == NULL) {
        fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());
        return;
    }

    /* Blit onto the screen surface */
    if(SDL_BlitSurface(image, NULL, screen, NULL) < 0)
        fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());

    SDL_UpdateRect(screen, 0, 0, image->w, image->h);

    /* Free the allocated BMP surface */
    SDL_FreeSurface(image);
}

Do adresára debug/src skopírujte ľubovoľný obrázok vo formáte bmp, najlepšie z rozlíšením 640x480 . Teraz stačí projekt skompilovať a spustiť. Mala by sa Vám objaviť konzola a v popredí vybraný obrázok.

Timotej Šiškovič

    • Velmi dobre 01.05.2008 | 11:52
      Castler   Návštevník
      Chcem len pochvalit clanok, velmi sa mi pacil, bolo to vysvetlene velmi pristupnou formou (pochopil som to aj ja). Je dobre ze autor nepouzova len tie zauzivane programatorske supervyrazy, ale ich aj hned vysvetluje. Od teraz presne viem co v principe znamena dll alebo dynamicka kniznica.:o) SUPER tesim sa na pokracovanie serialu.
    • nejde 30.11.2008 | 21:37
      martin   Návštevník
      Nejde mi ani jeden program stale to hadze nejake chyby. Uz som skusil okrem trhania si vlasov vsetko . Viete nejaku pomoc.

      ../libtool: line 818: X--tag=CC: command not found
      ../libtool: line 851: libtool: ignoring unknown tag : command not found
      ../libtool: line 818: X--mode=link: command not found
      ../libtool: line 985: *** Warning: inferring the mode of operation is deprecated.: command not found
      ../libtool: line 986: *** Future versions of Libtool will require --mode=MODE be specified.: command not found
      ../libtool: line 2223: X-O0: command not found
      ../libtool: line 2223: X-g3: command not found
      ../libtool: line 2392: Xha: command not found
      X: user not authorized to run the X server, aborting.
      ../libtool: line 2404: Xha: command not found
      ../libtool: line 2412: mkdir /.libs: No such file or directory
      mkdir: cannot create directory `/.libs': Permission denied
      make[2]: Leaving directory `/home/martin/ha/debug/src'
      make[2]: *** [ha] Error 1
      make[2]: Target `all' not remade because of errors.
      make[1]: *** [all-recursive] Error 1
      make[2]: Entering directory `/home/martin/ha/debug'
      make[2]: Nothing to be done for `all-am'.
      make[2]: Leaving directory `/home/martin/ha/debug'
      make[1]: Leaving directory `/home/martin/ha/debug'
      make: *** [all] Error 2
      *** Exited with status: 2 ***
    • Výborný seriál 11.03.2009 | 06:21
      Babbbrak   Návštevník
      Páči sa mi, že tu je aj návod pre GUI. Klikni sem, klikni tam. Neviem si predstaviť lepší návod ako toto.
      Nech si hovoria konzoláci, čo chcú, v grafike sa kódi neporovnateľne kvalitnejšie oproti tomu ostatnému.. Programátor je vždy len človek a v GUI sa rýchlejšie zorientuje ako na "x" oknách natlačených v "y" tty konzolách :-D.
      Mohlo by byť v ďalších častiach niečo o klasickejšom GUI toolkit ako wxWidgets alebo tak nejak? Špeciálne by ma zaujímalo, či a ak tak ako je v Kdevelop riešené rozhadzovanie GUI komponentov po Frame. Či je to tak ako v borlanďáckych IDE, alebo ak nie. A či to dokáže pridať nejaký "tajný" voliteľný package.
    • Zaujem 22.08.2009 | 20:42
      autor   Návštevník
      Je ešte záujem o pokračovanie tohoto seriálu?? (napr.: GUI, ... ), prip. navrhnite čo by ste chceli čítať/počuť/vediet (multithreaded programing, linux kernel module programming). Chcel by som vedieť aký by bol o takéto články záujem
      • Re: Zaujem 08.12.2010 | 17:31
        Fero   Návštevník
        Zdravim,

        ja osobne a moj brat netrpezlivo cakame na GUI od QT ako sa to da pouzivat s Kdevelop 4.

        Pretoze v Kdevelop 3.55 bolo tam aj vstavane GUI rozhranie. Ale v tomto novom Kdevelop 4.0.2 to nechce fungovat a zrejme to vynechali.

        Diky, za predchadzajuce clanky. Nam pomohli, lebo mame len 14 rokov.

        Fero a Miki
      • Re: Zaujem 08.12.2010 | 17:34
        Adrian   Návštevník
        Cau cau,

        no, mozem povedat ze chcel by som naozaj vidiet to GUI od QT ako sa pouziva v tom novom Kdevelop 4.0.2. Lebo mne to nefunguje. V QT som profik ale ako to prilinkovat do Kdev, no neviem.

        Inak super clanky, cakam na ten novy.

        Cau,

        s pozdravom Ado
      • Re: Zaujem 08.12.2010 | 17:39
        Katka   Návštevník
        Ahoj

        volam sa Katka y Brezna, a rada citam tvoje clanky. Denne pracujem s c++ v linuxe. Mala by som zaujem o multithreaded programing a GUI, podobne ako Adrian.

        Potrebujem vediet ako to funguje, ked chcem naraz spracovavat 6 vlakien, a zobrazovat ich plynule v nejakom okne ako vysledky ciarovych grafov. Moze byt OpenGL.

        Vdaka, fajn temy.

        Tesim sa na dalsi clanok.

        Cau
      • Re: Zaujem 08.12.2010 | 17:51
        Stano   Návštevník
        Ahoj

        ja programujem uz nejaku tu dobu asi 15 rokov v C++, a v C++Builderi, pod windowsom. Ale rozhodol som sa ten system vymenit za linux mint 10, postaveny na ubuntu.

        Mal by som yaujem keby si priblizil temu GUI aj OpenGL, a nejake tie zvukove finty s SDL kniznicou. Najprv by bolo najlepsie ak by si napisal step-by-step v Kdevelop 4.0.2, ako naprogramovat nejaky jednoduchy Textovy editor s QT su subormi *.ui, ulozenie, otvorenie, tlac, nahlad, a pod. Toto by som velmi ocenil.

        Potom v dalsom seriali skus nieco o GUI rozhrani od QT(myslim ze je najpouzivanejsie a jednoduche rozhranie), Dalsi clanok by som Ta chcel poprosit o OpenGL a GUI ako to s kombinovat v Kdevelop. Aj multithreaded programing nie zla tema, ak je v Kdevelop ukazana na grafike, to je dobra kombinacia.

        Skus popremyslat, ktora tema by bola ako dalsia v poradi. Som fanda, super clanky. Samozrejme ze ludia napisu aj chyby. To nevadi, ved nikto z ludi nie je bez nich.

        Cau

        Standa
      • Re: Zaujem 08.12.2010 | 17:55
        m0r1c   Návštevník
        ahoj

        sem rad ze po mesici sem se dostal na net. A zrovna na tenhle ten server o linuxe/

        Ja bych mel velky zajem o sminovane nove kdevelop 4.0.2 a nove qt. Nejaci novy jednoduchy editor, jak to udelat a tak.

        Jo, inak supr. moc fajn vsehny clanky.

        m0r1c, c++, linux, qt
      • Re: Zaujem 08.12.2010 | 21:38
        morfeuz   Návštevník
        Ahoj

        vcelku ok clanky. Ja programujem rychle pod linuxom c++ asi 5 rokov. Ale podla mna tebalo by tu ozrejmit a vysvetlit ludom-hlavne zaciatocnikom, ako QT, Kdevelop, SDL pre hry, je mozne zosuladit a pouzivat na programovanie hier, oknovych aplikacii a tiez 3D kniznic, napr. OpenGL pre grafiku, a OpenAL pre zvuk. Chcel by to bez, ohladu na to co ini pisu toto:

        1. jasne definovanie programov a ich verzii, ako aj linuxu
        2. funkcne adresy, kde stiahnut tie programy
        3. krok za krokom co stlacat a pisat kde, a ako, aby vsetko fungovalo
        4. vzorovy priklad, alebo zip na stiahnutie

        Paci sami ze mas tam aj PDF verziu, to je vyborna ukazka pre ostatnych, ze je to vsetko tam.

        Inak fajn praca, som dost spokojny. Tesim sa na pokracovanie QT a kdevelop ten novy neviem cislo 4.xx, ale ten novy je iny.

        cau

        : morfeuz
      • Re: Zaujem 08.12.2010 | 21:50
        Lucky   Návštevník
        ja by som uvital dalsie pokracovanie o novom kdevelop4 a to prostredie ci co to je to QT, lebo som videl fotky na nete a to QT je dost silne. Chcel by som vediet programovat nejaky jednoduchy textovy editor v linuxe pod KDevelop 4.

        fajn praca, budem cakat na dalsie pokracovania

        very well :-)