Laborator 03 - Dezvoltarea programelor în C sub mediul Linux

Obiective laborator

  • Familiarizarea cu etapele prin care trece codul sursa de la sursa la executabil
  • Familiarizarea cu toolurile necesare acestui lucru (gcc)
  • Automatizarea procesului de compilare (make & Makefiles)
  • Prezentarea unor principii de bază în scrierea/editarea de cod

Suport laborator

Pachete necesare

Pe unele sisteme este posibil ca aceste pachete necesare să lipsească:

  • build-essential
  • manpages-dev

În cazul în care nu sunt instalate implicit pe sistemul vostru, pe un sistem Ubuntu se poate folosi comanda

student@uso:~$ sudo apt-get install build-essential manpages-dev

Demo

Pentru demo deschidem un terminal (folosim combinația de taste Alt+Ctrl+t) și clonăm repository-ului oficial uso.

Ne asigurăm că suntem în /home/student

Folosim comanda:

student@uso:~$ git clone https://github.com/systems-cs-pub-ro/uso 

În directorul /home/student/uso/lab03 găsim fișierele necesare pentru laboratorul 3.

Compilarea unui singur fișier sursă

În cele ce urmează, vom consideră ca verbul a compila înseamnă a obține dintr-unul sau mai multe fișiere sursă un fișier executabil.

Mergem în directorul /home/student/uso/lab03/simple-gcc unde găsim fișierul simple_hello.c.

student@midgard$ pwd
/home/student/
student@midgard$ cd uso/lab03/simple-gcc
student@midgard$ ls
Makefile  hello.c  simple_hello.c  utils.h
errors.c  help.c   utils.c         warnings.c
student@midgard$ gcc simple_hello.c                                 
student@midgard$ ls
Makefile  errors.c  help.c          utils.c  warnings.c
a.out     hello.c   simple_hello.c  utils.h
student@midgard$ ./a.out
Hello world!

Anterior am folosit comanda gcc căreia i-am dat un singur parametru ca intrare. A generat un binar numit a.out. Mai jos putem vedea cum obținem un nume custom pentru binarul rezulat în urma comiplării fișierului simple_hello.c.

student@midgard$ ls
Makefile  errors.c  help.c          utils.c  warnings.c
a.out     hello.c   simple_hello.c  utils.h
student@midgard$ gcc simple_hello.c -o hello                          
student@midgard$ ls                      
Makefile  errors.c  hello.c  simple_hello.c  utils.h
a.out     hello     help.c   utils.c         warnings.c
student@midgard$ ./hello
Hello world!
student@midgard$ pwd
/home/student/uso/lab03/simple-gcc/

Observați că anterior am folosit o cale relativă la directorul curent pentru a executa fișierul hello, prin apelul ./hello. Puteam folosi și o cale absolută: /home/student/uso/lab03/simple-gcc/hello pentru executare.

Reamintiți-vă de la laboratorul trecut ce înseamnă . (punct, dot): directorul curent.

Pentru a vedea ce tip de fișier binar/executabil este hello, putem folosi comanda file:

student@midgard$ file ./hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x92a8cd0efe5b5dd5587b5965d8bc6fa27fac32af, not stripped

Comanda gcc simple_hello.c a fost folosită pentru compilarea fișierului sursă simple_hello.c. Rezultatul a fost obținerea fișierului executabil a.out (nume implicit utilizat de gcc). Dacă se dorește obținerea unui executabil cu un alt nume se poate folosi opțiunea -o.

În mod similar se folosește g++ pentru compilarea unui program sursă C++.

Alte exemple de comenzi folosind compilatorul gcc

Pentru compilarea de programe C, respectiv C++ folosim în linie de comandă compilatoarele gcc, respectiv g++. O invocare tipică este pentru compilarea unui program dintr-un singur fișier sursă, în cazul nostru simple_hello.c.

Pornim de la programul simplu din fișierul simple_hello.c pe care îl găsim în directorul ~/uso/lab03/simple-gcc care tipărește la ieșirea standard un șir de caractere:

simple_hello.c
#include <stdio.h>
 
int main(void) 
{
      printf("Hello world!\n");
      return 0;
}

Formatul general al unei comenzi de compilare cu gcc:

gcc fisiere.c -o nume_executabil COMPILING_FLAGS LINK_BIBLIOTECI
  • COMPILING_FLAGS sunt opțiuni ale gcc (precum -g, -w, -Wall)
  • LINK_BIBLIOTECI ține de opțiuni precum -lm sau -L.

După -o trebuie să se găsească numele fișierului de ieșire. Acesta suprascrie fișierele pe care le primește ca argument.

Comanda poate fi, la fel de bine, structurată și astfel:

gcc COMPILING_FLAGS -o nume_executabil fisiere.c LINK_BIBLIOTECI

După -o nu punem fișiere sursă sau alte fișiere. Dacă vom face asta, fișierele vor fi suprascrise și vom pierde conținutul acestora.

Exemple concrete:

Intrați în directorul ~/uso/lab03/simple-gcc

  1. Compilarea unui program simplu:
     gcc simple_hello.c -o simple_hello 
  2. Compilarea unui program simplu, și afișarea tuturor warning-urilor
     gcc -Wall simple_hello.c -o simple_hello 
  3. Compilarea unui program, cu afisarea tuturor warning-urilor care are nevoie de legatura catre biblioteca matematica
     gcc -Wall simple_hello.c -o math_hello -lm 
  4. Compilarea unui program, cu afișarea tuturor warning-urilor, din mai multe fișiere sursă
     gcc -Wall hello.c utils.c help.c -o hello

Paginile de ajutor ale GCC (man gcc, info gcc) oferă o listă cu toate opțiunile posibile ale GCC.

gcc -c simple_hello.c -o hello-obj.o

La acest pas, obținem programul în limbaj cod mașină, cod care nu mai poate fi înțeles deloc de către oameni, fiind practic doar șiruri de biți 1/0. Acest tip de cod generat mai este cunoscut și sub numele de cod obiect și poate fi executat direct de către procesor.

Fișierul intermediar produs are extensia .o.

Editare de legături(linking phase)
 gcc hello-obj.o -o hello 

Odată ce fișierul obiect este generat în etapa de asamblare, toate simbolurile (funcții, variabile globale etc) trebuie rezolvate, adică, de exemplu pentru funcții, trebuie găsită implementarea efectivă (corpul funcției) care se poate afla în alt fișier obiect sau într-o bibliotecă a sistemului. De exemplu atunci când scriem printf(…), pentru a afișa un șir de caractere pe ecran, codul aferent funcției de bibliotecă printf() trebuie efectiv copiat în programul nostru sau măcar făcută o legătură către el (de aici și numele de editare de legături). De asemenea, dacă programul nostru constă din mai multe fișiere .c, fiecare dintre ele va produce câte un fișier obiect separat, dar în final noi vom obține un singur fișier și anume programul executabil. De legătura dintre fișierele obiect mai sus menționate se ocupă, bineînțeles, linkerul.

Executarea codului

Se face apelând din Bash (Terminal) fișierul executabil, folosind calea către acesta:

  1. Fie relativă la directorul curent
       student@midgard$: pwd
       /home/student/uso/lab03/simple-gcc/
       student@midgard$: ./hello 
  2. Fie absolută
     student@midgard$: /home/student/uso/lab03/simple-gcc/hello 

Exemplu: Putem rula ls folosind binarul din sistemul Linux. Încercați să executați comanda /bin/ls :-)

Intrăm în directorul ~/uso/lab03/simple-gcc

Separăm compilarea fișierului help.c de link-editare pentru a obține fișierului obiect help.o. Pentru aceasta vom folosi comanda:

student@midgard$: gcc -c help.c
student@midgard$: ls
errors.c  hello.c  help.c  help.o  Makefile  utils.c  utils.h  warnings.c simple_hello.c

Observați crearea fișierului help.o. Procedăm similar pentru utils.c și hello.c:

student@midgard$: gcc -c utils.c
student@midgard$: gcc -c hello.c
student@midgard$: ls
errors.c  hello.c  hello.o  help.c  help.o  Makefile  simple_hello.c  utils.c  utils.h  utils.o  warnings.c

Pentru a obține fișierul binar hello, care execută codul din corpul funcției main al fișierului sursă hello.c este nevoie să punem cap la cap toate cele 3 fișiere obiect, să le link-edităm:

student@midgard$: gcc utils.o help.o hello.o -o hello
student@midgard$: ls
errors.c  hello  hello.c  hello.o  help.c  help.o  Makefile  simple_hello.c  utils.c  utils.h  utils.o  warnings.c
student@midgard$: file hello
hello: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=54b686de038a29fed397f604403961f9d1086f76, not stripped
student@midgard$: ./hello
30
craaaaap

Makefiles

Make este un utilitar care permite automatizarea și eficientizarea sarcinilor. În mod particular este folosit pentru automatizarea compilării programelor. După cum s-a precizat, pentru obținerea unui executabil provenind din mai multe surse este ineficientă compilarea de fiecare dată a fiecărui fișier și apoi link-editarea. Se compilează fiecare fișier separat, iar la o modificare se va recompila doar fișierul modificat.

Exemplu simplu de Makefile

Utilitarul make folosește un fișier de configurare denumit Makefile. Un astfel de fișier conține reguli și comenzi de automatizare.

Makefile
all:
       gcc -Wall hello.c -o hello
clean:
       rm -f hello
student@midgard$ make
gcc -Wall hello.c -o hello
student@midgard$ ./hello
Hello, World!
student@midgard$ make clean
rm -f hello
student@midgard$ make all
gcc -Wall hello.c -o hello

Aveți grijă la separatorul folosit în cadrul unui fișier Makefile. Liniile care conțin comenzi de compilare sunt indentate folosind TAB, nu space.

Makefile
main.o: main.c
<  TAB  >gcc -Wall -c main.c

Exemplul prezentat mai sus conține două reguli: all și clean. La rularea comenzii make se execută prima regulă din Makefile (în cazul de față all, nu contează în mod special denumirea). Comanda executată este gcc -Wall hello.c -o hello. Se poate preciza explicit ce regulă să se execute prin transmiterea ca argument comenzii make. (comanda make clean pentru a șterge executabilul hello și comanda make all pentru a obține din nou acel executabil).

Alt exemplu de Makefile

Intrați în directorul ~/uso/lab03/simple-gcc. Amintiți-vă cele 4 comenzi gcc pe care le-am dat pentru a obține 3 fișiere obiect din sursele utils.c, hello.c și help.c și cea de a patra comanda pentru a link-edita cele 3 obiecte spre obținerea binarului.

Putem automatiza toți acești pași putem folosi fișierul Makefile:

student@midgard$: make
gcc -c utils.c
gcc -c hello.c
gcc -c help.c
gcc utils.o help.o hello.o -o hello
student@midgard$: ls
errors.c  hello  hello.c  hello.o  help.c  help.o  Makefile  simple_hello.c  utils.c  utils.h  utils.o  warnings.c
student@midgard$: file hello
hello: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=54b686de038a29fed397f604403961f9d1086f76, not stripped
student@midgard$: ./hello
30
craaaaap

Urmăriți dependențele între reguli din fișierul ~/uso/lab03/simple-gcc/Makefile:

Makefile
build: utils.o hello.o help.o
        gcc utils.o help.o hello.o -o hello
 
all:
        gcc simple_hello.c -o simple
 
utils.o: utils.c
        gcc -c utils.c
 
hello.o: hello.c
        gcc -c hello.c
 
help.o: help.c
        gcc -c help.c
 
clean:
        rm -f *.o hello

Exerciții

0.0. Pregătire setup laborator (1p)

Intrați în directorul /home/student. Dacă nu ați clonat deja la secțiunea demo repository-ului oficial uso, atunci clonați-l acum folosind coamnda:

student@uso:~$ git clone https://github.com/systems-cs-pub-ro/uso 

În directorul ~/uso/lab03 găsiți fișierele necesare pentru rezolvarea acestui laborator.

Recomandăm rezolvarea exercițiilor pe mașina virtuală USO pe care o veți avea și la teme și la testul practic. Informații pas cu pas despre importul și pornirea acesteia se află în secțiunea Mașina virtuală.

Pentru acest laborator putem porni la lucru cu mașina cu interfață grafică, aceasta se află în /mnt/unfrozen. Drept urmare importăm fișierul /mnt/unfrozen/uso_2016_2017_gnome.ova

[1] Compilarea unui fișier sursă C (2p)

Pentru a rezolva următoarea serie de exerciții mergeți în directorul /home/student/uso/lab03/simple-gcc. Pentru aceasta folosim următoarea comandă cd ~/uso/lab03/simple-gcc. În directorul simple-gcc găsiți fișierul sursă simple_hello.c. Compilați-l, folosind gcc, într-un fișier executabil denumit hello. Pentru aceasta folosim următoarea comandă:

student@midgard$ gcc simple_hello.c -o hello

Rulați executabilul proaspăt obținut.

student@midgard$ ./hello
Hello, World

Repetați procesul de mai sus, dar de data aceasta obțineți un executabil cu numele salut. Acum îl rulăm și observăm că am obținut exact același lucru ca mai sus. Cele două fișiere par identice, dar ca să ne asigurăm folosim comanda cmp.

Folosiți cunoștințele din laboratorul precedent și căutați în pagina de manual a comenzii cmp folosind comanda:

 man cmp 

Dacă în urma rulării comenzii cmp cu parametrii corespunzător nu se va afișa nimic înseamnă că cele două fișiere sunt identice.

Observăm că cele două fișiere sunt într-adevăr identice, acest lucru datorându-se faptului că procesul de compilare este unul determinist (o bucată de cod sursă C se va traduce mereu în exact aceleași instrucțiuni în limbaj de asamblare și apoi în cod mașină - dacă se păstrează același grad de optimizare).

[2] Detectarea și corectarea warning-urilor (2p)

În același director ca mai sus, /home/student/uso/lab03/simple-gcc, găsim fișierul warnings.c. Compilați-l folosind următoarea comandă:

student@midgard$ gcc warnings.c -o warnings
student@midgard$ ./warnings
a + b = 5

Observăm că fișierul a fost compilat și rulat cu succes. Repetați comanda de mai sus, dar folosiți de această dată flagul -Wall pentru comanda gcc, ca mai jos:

student@midgard$ gcc -Wall warnings.c -o warnings
warnings.c: In function ‘main’:
warnings.c:8: warning: unused variable ‘c’

Vedem totuși că de data aceasta a fost identificată o problemă cu fișierul warnings.c și anume că variabila c a fost declarată, inițializată, dar nefolosită. Acest fapt nu afectează comportamentul programului nostru, dar, în general, e bine să le evităm pe cât posibil.

Inspectați fișierul sursă warnings.c și corectați warningul. Rulați din nou comanda gcc -Wall warnings.c -o warnings până când nu mai primiți niciun warning la compilare.

[3] Compilarea temei folosind Makefile (3p)

Intrați în directorul /home/student/uso/lab03/tema-pc. Dorim să compilăm tema la programare folosind fișierul Makefile. Rulați comanda make.

Rulați încă o dată comanda make. S-a mai executat vreo comandă?

Schimbați valoarea macro-ului MIN_VAL în fișierul utils.h. Rulați încă o dată comanda make. De ce nu se actualizează fișierul executabil? Modificați fișierul Makefile pentru ca obținerea fișierelor obiect (cu extensia .o) să țină cont și de fișierele header (cu extensia .h) de care acestea depind.

Revedeți secțiunea de Makefiles din suportul laboratorului.

[4] Detectarea și corectarea erorilor de compilare (1p)

În același director ca mai sus, /home/student/uso/lab03/simple-gcc, găsim fișierul errors.c. Compilați-l folosind următoarea comandă:

student@midgard$ gcc -Wall errors.c -o errors
errors.c: In function ‘main’:
errors.c:7: error: expected ‘;’ before ‘returnstudent@midgard$ ls errors
ls: cannot access errors: No such file or directory

Observăm că de această dată nu a mai fost obținut niciun fișier executabil, întrucât în fișierul errors.c au fost detectate erori de sintaxă. Cea identificată în cazul nostru este la linia 7 și anume că înaintea instrucțiunii return lipsește caracterul ;. Modificați fișierul errors.c astfel încât acesta să fie compilat și rulat cu succes.

[5] Detectarea și corectarea erorilor de linkare (1p)

Mergeți în directorul /home/student/uso/lab03/tema-pc, unde găsim 4 fișiere. Pentru acest exercițiu ignorați fișierul Makefile, ne interesează numai tema.c, utils.c și utils.h.

Inspectăm fișierul tema.c folosind un editor sau comanda cat tema.c și vedem că folosește două funcții (vect_gt și vect_lt) care nu apar definite nicăieri. Observăm totuși că este inclus fișierul utils.h, iar dacă ne uităm în acesta vom vedea că cele două funcții sunt declarate totuși acolo.

Încercăm să compilăm fișierul tema.c așa cum am învățat până acum:

student@midgard$ gcc tema.c
/tmp/cc7oBohY.o: In function `main':
tema.c:(.text+0xac): undefined reference to `vect_gt'
tema.c:(.text+0xdb): undefined reference to `vect_lt'
collect2: ld returned 1 exit status

Din păcate, procesul de compilare eșuează în etapa de linking, chiar dacă noi avem cele două funcții declarate în fișierul utils.h, iar acesta este inclus în fișierul principal tema.c.

Compilați fișierul tema.c numai până la codul obiect (până la etapa de linkare), folosind flagul -c. Comanda necesară pentru acest lucru este:

student@midgard$ gcc -Wall -c tema.c

Repetați același lucru pentru fișierul utils.c și obțineți fișierul obiect utils.o. Putem obține acum fără probleme executabilul nostru, dacă linkăm cele două fișiere obiect. Facem asta cu comanda:

student@midgard$ gcc tema.o utils.o -o tema
student@midgard$ ./tema
Values: 10 -20 30 9 7 8 11 5 -2 100 
Values greater than 5: 7
Values less than 3: 2

Puteam realiza același lucru de la început folosind direct comanda:

student@midgard$ gcc -Wall tema.c utils.c -o tema

Deschideți în editorul preferat fișierul tema.c și realizați o modificare minoră, de exemplu modificați valoarea lui N din 9 în 5. Compilați din nou fișierul tema.c pentru a obține fișierul obiect tema.o. La fel ca mai sus, linkați fișierele obiect tema.o și utils.o pentru a obține executabilul tema, după care rulați-l. Observăm că nu a mai fost nevoie de recompilarea fișierului utils.c, am folosit fișierul obiect obținut anterior.

Un mare avantaj al opririi procesului de compilare înainte de etapa de linkare este faptul că putem refolosi fișiele obiect. Dacă avem un proiect mare cu numeroase fișiere sursă și realizăm o modificare într-un singur fișier sursă, nu este nevoie sa compilăm de fiecare dată toate fișierele, ci numai cel modificat, fiind astfel suficient doar să le relinkăm la final. Cum putem exploata acest lucru vom observa în exercițiile următoare.

[Bonus #1] Makefile pentru un proiect (1 Karma WoUSO)

În directorul /home/student/uso/lab03/large-project găsiți o structură de fișiere și directoare care simulează un proiect software mai mare (mai multe fișiere sursă, împărțit pe funcționalități etc). Structura proiectului nostru este următoarea:

student@midgard$: tree
.
├── Makefile
├── main.c
├── sum
│   ├── add
│   │   ├── add.c
│   │   └── add.h
│   ├── sum.c
│   └── sum.h
└── utils
    ├── utils.c
    └── utils.h
 
3 directories, 8 files

Practic, modulul main depinde de modulele sum și utils, iar modulul sum depinde și el la rândul lui de modulul add.

Completați fișierul Makefile din rădăcina proiectului astfel încât la rularea comenzii make all toate fișierele sursă .c vor fi compilate și va fi obținut executabilul main. Înlocuiți liniile care conțin #TODO cu comenzile necesare pentru compilare.

Urmăriți ca model și fișierul Makefile de la exercițiul 5.

[Bonus #2] Scrierea unui Makefile (1 Karma WoUSO)

În directorul /home/student/uso/lab03/project se află două fișiere sursă, project.c și functions.c. Fișierul project.c conține funcția main ce apelează o funcție denumită f și definită în fișierul functions.c. Observăm că la rularea unei comenzi simple de compilare se obține un warning:

student@uso:~/uso/lab03/project$ gcc -Wall functions.c project.c 
project.c: In function ‘main’:
project.c:6:5: warning: implicit declaration of function ‘f’ [-Wimplicit-function-declaration]
     f();
     ^

Acest lucru se datorează faptului că funcția f este chemată fără a fi declarată. Pentru a evita această problemă trebuie să-i promitem compilatorului că funcția f va exista la un moment ulterior definită (cu același nume, același tip de retur, același număr de parametri).

Creați un fișier header functions.h în care să declarați funcția f după care includeți fișierul functions.h în project.c. Observați că warningul de mai sus a dispărut.

student@uso:~/uso/lab03/project$ gcc -Wall functions.c project.c
student@uso:~/uso/lab03/project$

În continuare, creați un fișier Makefile folosind editorul vim, în același folder, care să conțină, cel puțin, câte o regulă de compilare până la fișiere obiect pentru fiecare fișier .c, o regulă pentru obținerea executabilului (executată când rulăm comanda make) și o regulă clean care șterge fișierele obiect și executabilul obținut în urma comenzii make. De asemenea, scrieți Makefileul astfel încât la rularea mai multor comenzi make consecutive, proiectul să nu fie recompilat de fiecare dată.

[BONUS #3] Variabile în Makefile (2 Karma WoUSO)

Un fișier Makefile permite folosirea de variabile. Astfel, un exemplu uzual de fișier Makefile este:

Makefile
CC = gcc
CFLAGS = -Wall -g
 
all: hello
 
hello: hello.o
        $(CC) hello.o -o hello
 
hello.o: hello.c
        $(CC) $(CFLAGS) -c hello.c
 
clean:
        rm *.o hello

În exemplul de mai sus au fost definite variabilele CC și CFLAGS. Variabila CC reprezintă compilatorul folosit, iar variabila CFLAGS reprezintă opțiunile (flag-urile) de compilare utilizate; în cazul de față sunt afișarea avertismentelor și compilarea cu suport de depanare. Referirea unei variabile se realizează prin intermediul construcției $(VAR_NAME). Astfel, $(CC) se înlocuiește cu gcc, iar $(CFLAGS) se înlocuiește cu -Wall -g.

Observăm că șirurile hello, gcc, precum și flagurile date la compilare apar în foarte multe locuri. Modificați fișierul Makefile astfel încât să avem de schimbat o singură linie în cazul în care dorim să schimbăm numele executabilului, compilatorului sau să mai adăugăm un alt flag.

Modificați fișierul Makefile din directorul /home/student/uso/lab03/tema-pc astfel încât să folosiți în cadrul fiecărei reguli variabilele predefite:

  • $@ se expandează la numele target-ului.
  • $^ se expandează la lista de cerințe.
  • $< se expandează la prima cerință.

Motivul utilizării acestora nu este pentru a reduce dimensiunea Makefile sau pentru a îl obfusca, ci pentru a evita cât mai mult posibil repetițiile, minimizând în acest fel și potențialele erori ce pot apărea în viitor. Spre exemplu, dacă în cadrul unei reguli se adaugă ca dependență un fișier sursă .c nou, nu mai este nevoie să fie trecut și pe linia următoare corespunzătoare comenzii de compilare. El va fi automat expandat din variabila $^.

[BONUS #4] Investigarea bibliotecilor externe folosite (1 Karma WoUSO)

În directorul /home/student/uso/lab03/static-lib aveți fișierele simple_math.c și Makefile. Rulăm comanda make și observăm că primim o eroare de linking (în etapa de link-editare)

student@midgard$: make
gcc -Wall simple_math.o -o simple_math 
simple_math.o: In function `main':
simple_math.c:(.text+0x1e): undefined reference to `sqrtq'
simple_math.c:(.text+0x3c): undefined reference to `quadmath_snprintf'
collect2: error: ld returned 1 exit status
make: *** [simple_math] Error 1

Eroarea provine de la faptul că două simboluri, și anume sqrtq și quadmath_snprintf au fost utilizate, declarate, dar nu au fost și definite. Pentru a rezolva problema avem nevoie să legăm biblioteca statică libquadmath la codul nostru.

Modificați linia din Makefile care obține fișierul executabil simple_math astfel încât să legați biblioteca statică libquadmath.

Revedeți secțiunea de biblioteci din cadrul demo-ului. Mai multe informații despre biblioteca quadmath puteți afla de aici.

[Bonus #5] Instalarea și compilarea din surse (2 Karma WoUSO)

Vrem să compilăm și să instalăm un program din cod sursă (adică nu dintr-un pachet).

Descărcați Python 2.7.8 de aici. Alegeți formatul corespunzător sistemului pe care lucrați.

Următorii pași se aplică, în general, la compilarea din surse:

student@midgard ~ $ ./configure 
student@midgard ~ $ make
student@midgard ~ $ make install

Etapa de configurare dispune de un parametru special

./configure --prefix=/path/to/my/custom/folder

în care putem specifica directorul de instalare. Folosiți această opţiune deoarece dorim să nu afectăm versiunea de Python a sistemului. Folosiți o cale absolută către un director din /home/student.

Dacă doriți instalare ca utilizator neprivilegiat (fără a prefixa comanda cu sudo, vom învăța amănunte într-unul din laboratoarele viitoare), trebuie să folosiți opțiunea --prefix a comenzii ./configure și să transmiteți un director la care utilizatorul are acces. În absența acestei opțiuni instalarea se face, în general, în directoare precum /usr/bin/ și /usr/lib/, unde doar utilizatorul privilegiat (root) are acces.

[Bonus #6] Good code practices (1-5 Karma WoUSO)

E bine ca atunci când scriem cod să fie cât mai organizat, aerisit, cât mai ușor de înțeles de către altcineva. În directorul /home/student/uso/lab03/ugly găsiți fișierul ugly.c care este scris intenționat într-un mod foarte confuz și alambicat. Citiți articolul de la acest link după care modificați fișierul ugly.c conform principiilor prezentate, păstrând însă exact aceeași funcționalitate.

uso-ac/laboratoare/laborator-03.txt · Last modified: 2016/10/25 23:22 by giorgiana.vlasceanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0