Ako si z MS Visual Studia vyripovat potrebne subory a kompilovat veci z komandlajnu

16.03.2007 14:49 | vid

Tento clanok pisem pre ludi ktorych v skole nutia pouzivat Visual Studio. Ukazem tu ako si z neho vyripovat len to potrebne a ako si skompilovat program z prikazoveho riadku. Malo by to ludom dat predstavu ako asi veci funguju, nieco viac ako "opiste toto a stlacte F9".

Clanok opisuje postup pre Microsoft Visual Studio 8.x (Microsoft Visual Studio 2005 .NET). Pre verzie 6.x by to malo byt velmi podobne, niektore adreasare mozno budu ine.

KOMPILATOR
==========
Najprv si musime vyripovat veci potrebne pre funkcny kompilator.

Vytvorte si adresar a do nho nakoirujte tieto subory z adresaru Visualka:

- VC\bin\cl.exe - kompilator
- VC\bin\link.exe - linker
- VC\bin\c1.dll - first pass C compiler, sucast kompilatoru
- VC\bin\c1xx.dll - first pass C++ compiler, tiez
- VC\bin\c2.dll - second pass compiler, tiez
- Common7\IDE\mspdb80.dll - kniznica na pracu s debug symbolmi
- VC\bin\1033\clui.dll - kniznica obsahujuca chybove hlasky

MSPDB80 treba aj ked debug symboly nepouzivame! Pozor s tymto suborom byva obcas problem. Visual Studio obsahuje viac verzii, ale iba jedna z nich je "spravna". Ak mate niekde v ceste (envvar PATH) nespravnu kopiu, tak to bude hadzat podivne hlasky.

Pokial mate nejaku lokalizovanu verziu MSVS (co som este v zivote nevidel), tj. nie anglicku, tak namiesto "1033" bude ine podobne cislo (viac)

Uz s tymto dokazeme skompilovat cisty C subor. Vytvorte subor test.c:

int main() { return 0; }

skompilujte ho:

cl.exe /c /Zl test.c

Prepinac /c znamena ze subor sa nelinkuje na ziadne kniznice, len cisto skompiluje ako je. Prepinac /Zl znamena ze objekt nebude mat zavislost na defaultnych knizniciach. Vznikne nam objektovy subor "test.obj".

Tento teraz "zlinkujeme" na exac:

link /entry:main /nodefaultlib test.obj

Prepinace su potrebne kvoli tomu ze link.exe predpoklada defaultne ze budeme pouzivat standardnu C kniznicu. My ja zatial nepouzivame, takze mu to musime oznamit (toto sme uz vyriesili prepinacom /Zl, ale pre istotu). Na to sluzi "/nodefualtlib". Stale je ale problem ze defaultny entry point je na symbol "_mainCRTStartup", ktory je v jednej z defaultnych C kniznic. Nastavime teda nasu funkciu "main" ako entry point "/entry:main".

Samozrejme, tento exac este nic nerobi, len sa hned ukonci.

STANDARDNA C KNIZNICA
=====================
Dalsia vec ktoru budeme potrebovat je standardna C kniznica. Tato je sucastou Visual Studia (dokonca aj so zdrojakmi!).

Tu je nas jednoduchy program pouzivajuci standardnu C kniznicu:

#include <stdio.h>
int main()
{
printf("Ahoj\n");
return 0;
}

Dalej musime pri kompilovani nastavit cestu k suboru stdio.h a dalsim headerom standardnej C kniznice. Tie sa nachadzaju v podadresari Visualka "VC\include". Cestu k include suborom nastavime pomocou prepinacu "/I<dir>". Ak cesta obsahuje medzery, dame ju do uvodzoviek.
Takze nas program skompilujeme takto:

cl /c /I"C:\Program Files\Microsoft Visual Studio 8\VC\include" test.c

samozrejme cesta k Visualku moze byt ina :)

Dalej treba objekt prilinkovat k nejakej C kniznici. MSVS poskytuje moznost prilinkovat ju staticky (kod kniznice rovno v exaci) aj dynamicky (pouziva systemovu DLLku).

Pri statickom linkovani je exac o par 10KB vacsii. Pri dynamickom byva problem, ked sa odvolate na prilis novu alebo staru verziu, a potom spustite program na masine kde sa prislusna DLLka nenachadza.

Aby ste si rozsirili rozhlad, ukazeme si obidve.

Pre staticke linkovanie potrebujete subor "libcmt.obj" (Library C Multi-Threaded) ktory najdete v podadresari vizualka "VC\lib". Prekopirujte si ho do svojho adresara a napiste:

link a.obj

Subor libcmt.obj netreba udavat lebo je defaultny. Naopak, ked ho nechcete treba ho vypat pomocou "/nodefaultlib:libcmt.lib" ako sme to robili pri prazdnom subore.

Teraz sa bude este link stazovat ze mu chyba dalsia defaultna kniznica, OLDNAMES.lib. Tuto kniznicu vobec nieje treba a zrejme je to iba nejaka vec kvoli backward kompatibilite. Pridajte do linkovania parameter "/nodefaultlib:oldnames.lib":

link /nodefaultlib:oldnames.lib a.obj

Teraz by to malo vyplut funkcny exac ktory vypise "Ahoj". Exac ma velkost par desiatok KB, lebo je v nom cela potrebna cast C kniznice. Teraz si spravime verziu ktora sa bude linkovat k C kniznici dynamicky.

C kniznica pre dynamicke linkovanie je v subore MSVCR80.DLL (Microsoft Visual C RunTime 8.0) vo Windows\System32. Pri linkovani sa na nu odkazuje pomocou suboru "msvcrt.lib" v adresari "VC\lib" (tam kde bol libcmt.lib). Tento subor si tiez nahraje k sebe do adresaru a linkujte takto:

link /nodefaultlib:libcmt.lib /nodefaultlib:oldnames.lib
a.obj msvcrt.lib

Teraz budete mat malicky .exe subor. Problem je v tom ze ak ho skusi spustit niekto kto nema SVCR80.DLL, tak mu nepojde. V praxi sa preto zvykne MSVCR80.DLL prikladat do distribucie programov (licencia to povoluje), cim sa ale trochu straca vyhoda dynamickeho linkovania. :]

WinAPI
======
Dalsia vec ktoru by ste mohli potrebovat je WinAPI, teda Windows Application Programming Interface.

Headery a .lib subory k nemu sa nachadzaju v Platform SDK. U mna je to adresar "VC\PlatformSDK", dalej budem predpokladat ze u vas tiez.

Najprv si napiseme program ktory pouziva C kniznicu aj WinAPI:

#include <stdio.h>
#include <windows.h>
int main()
{
MessageBox(0, "Serem na Visual Studio", "Test", MB_OK);
printf("Ahoj\n");
return 0;
}

Potom program skompilujeme, pricom do zoznamu include adresarov pridame pomocou prepipanaca "\I" adresar "Include" z Platform SDK:

cl /c /I"C:\Program Files\Microsoft Visual Studio 8\VC\include" /I"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include" test.c

Vsimnite si ze program sa poznatelne dlhsie kompiluje, kedze includuje headery pre cele winAPI, co je slusnych zopar mega. Pre vecsinu programov je treba iba malu cast z tohoto. Na to sluzi definicia WIN32_LEAN_AND_MEAN.

#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
int main()
{
MessageBox(0, "Serem na Visual Studio", "Test", MB_OK);
printf("Ahoj\n");
return 0;
}

Teraz by sa mal program kompilovat rychlejsie.

Teraz este treba program prilinkovat. Pri WinAPI sa uz nejedna o jeden .lib subor, ale o celkom slusne mnozstvo (z ktorych aj tak viac ako 5 tazko vyuzijete, ale co uz). Preto bude lepsie nastavit si pri
linkovani cestu k nim priamo do adresaru "lib" v Platform SDK. Na toto sluzi prepinac "/LIBPATH:".

Potom treba este prilinkovat tie .lib subory z ktorych funkcie pouzivame. V nasom pripade pouzivame len funkciu z "USER32.LIB". Rozumnejsie je vsak dat si tieto: KERNEL32, USER32, SHELL32, WSOCK32, GDI32.
Ostatne snad nebude treba, ked ano lahko sa na to prijde.

Takze nas novy command line:

link /libpath:"C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\lib" /nodefaultlib:oldnames.lib kernel32.lib user32.lib shell32.lib wsock32.lib gdi32.lib test.obj

A mame funkcny program ktory vyuziva WinAPI aj C kniznicu

ZHRNUTIE
========
Ak by ste chceli tento sposob pouzivat na prakticke veci, odporucam spravit si na to nejaky skript (v pripade windowsu .bat subor).

Pripadne este lepsie je nastudovat si pouzivanie utilitky "make" (vo vizualku je "nmake.exe").

Nevyhoda oproti pouzivaniu MSVS IDE je, ze nemate integrovany debugger.

Ako alternativu k MSVC doporucujem MinGW GCC (Windows port GNU GCC), a ako alternativu k MSVS IDE doporucujem Code::Blocks. Ako C++ kompilator je MSVC vyborny, ale nieje velmi striktny ako C kompilator, a MSVS IDE (prostredie) je straaaasne zle a cim dalej tym horsie.

    • Re: Ako si z MS Visual Studia vyripovat potrebne subory a kompil 17.03.2007 | 15:58
      Avatar marvin   Používateľ

      celkom fajn clanok,mne osobne sa prida.
      maly bug v texte: vsade kde mas kod #include tak ti zrejme system zhltol nazov standardnej kniznice medzi < a >
      ------
      42.nothing more needed

      ------ Kto je Španielsko?Prečo je Hitler?Kedy je vľavo?
      • Re: Ako si z MS Visual Studia vyripovat potrebne subory a kompil 18.03.2007 | 17:57
        Avatar vid   Používateľ

        jj, len sa mi nejak neda editovat teraz clanok, kedze som ho ja nepridaval :(

        • opravene 18.03.2007 | 19:06
          Avatar y   Používateľ

          opravene
          ==
          are you canadian?!

          == Don't buy drugs...Become a pop star and get them for free!
          • Re: opravene 18.03.2007 | 20:03
            Avatar vid   Používateľ

            dik

            este by bolo fajn zistit preco mi to nejde editovat. pridaval to myslim bhole, ale pod mojim userom nejako.

            Len ja ked to otvorim nemam tam moznost edit. Alebo som mozno len nieco prehliadol. Rad by som tam pridal aj code tagy

    • Re: Ako si z MS Visual Studia vyripovat potrebne subory a kompil 18.04.2007 | 13:24
      contmp   Návštevník

      presne to co som hladal! dakujem :-)

    • Update: Ako si z MS Visual Studia vyripovat... 28.11.2007 | 01:27
      Avatar vid   Používateľ

      Trochu som updatol tento clanok nech sa zan nemusim hanbit :)

    • Re: Ako si z MS Visual Studia vyripovat potrebne ... 28.11.2007 | 09:19
      chess   Návštevník

      strucne, zrozumitelne, uzitocne.
      vyborna praca.
      vdaka.